pepke@gw.scri.fsu.edu (Eric Pepke) (07/11/90)
Speaking of Munger, it's a cute little routine, but what happens when it fails due to insufficient memory? I run this little test program: #include <stdio.h> #include <MacTypes.h> #include <MemoryMgr.h> main() { unsigned char buffer[1000]; Handle block; long beforeLength, afterLength; printf("Yahoo!\n"); block = NewHandle(0L); for (;;) { beforeLength = GetHandleSize(block); Munger(block, GetHandleSize(block), (unsigned char *) 0, 0L, buffer, (long) sizeof(buffer)); afterLength = GetHandleSize(block); if (beforeLength + sizeof(buffer) > afterLength || MemError()) { printf("\nSize increased from %ld to %ld\n", beforeLength, afterLength); printf("MemError() == %d\n", MemError()); exit(-1); } else { printf("."); } } } and I get Yahoo! ........................................................................... ..... ........................................................................... ..... ........................................................................... ..... ....................................................................... Size increased from 311000 to 311000 MemError() == 0 So, when Munger fails due to lack of memory, you cannot tell from looking at MemError. In this case, at least, it left the handle unchanged. Can somebody who knows about the internals of Munger tell me if that is guaranteed to be the case, or is there a possibility that the handle will be corrupted in any way, such as being left larger than it was but not as large as is needed? Eric Pepke INTERNET: pepke@gw.scri.fsu.edu Supercomputer Computations Research Institute MFENET: pepke@fsu Florida State University SPAN: scri::pepke Tallahassee, FL 32306-4052 BITNET: pepke@fsu Disclaimer: My employers seldom even LISTEN to my opinions. Meta-disclaimer: Any society that needs disclaimers has too many lawyers.
keith@Apple.COM (Keith Rollin) (07/13/90)
In article <233@sun13.scri.fsu.edu> pepke@gw.scri.fsu.edu (Eric Pepke) writes: >Speaking of Munger, it's a cute little routine, but what happens when it >fails due to insufficient memory? > >I run this little test program: > >#include <stdio.h> >#include <MacTypes.h> >#include <MemoryMgr.h> > >main() >{ > unsigned char buffer[1000]; > Handle block; > long beforeLength, afterLength; > > printf("Yahoo!\n"); > > block = NewHandle(0L); > > for (;;) > { > beforeLength = GetHandleSize(block); > Munger(block, GetHandleSize(block), (unsigned char *) 0, > 0L, buffer, (long) sizeof(buffer)); > afterLength = GetHandleSize(block); > > if (beforeLength + sizeof(buffer) > afterLength || MemError()) > { > printf("\nSize increased from %ld to %ld\n", > beforeLength, afterLength); > printf("MemError() == %d\n", MemError()); > exit(-1); > } > else > { > printf("."); > } > } >} > >and I get > >Yahoo! >........................................................................... >..... >........................................................................... >..... >........................................................................... >..... >....................................................................... >Size increased from 311000 to 311000 >MemError() == 0 > >So, when Munger fails due to lack of memory, you cannot tell from looking >at MemError. In this case, at least, it left the handle unchanged. Can >somebody who knows about the internals of Munger tell me if that is >guaranteed to be the case, or is there a possibility that the handle will >be corrupted in any way, such as being left larger than it was but not as >large as is needed? When Munger needs some more memory, it calls SetHandleSize. If SetHandleSize returns an error (returned in register D0), Munger exits immediately. This means that the error result code is still in D0, and you can retrieve it with a little bit of glue code or inline assembly. The reason why MemError isn't set is because the Memory Manager doesn't set it; that's the function of the glue code provided for those calls by your development system. Your call to something like SetHandleSize is really a call to subroutine that takes your parameters off the stack, puts them in registers, calls the function, and puts the result code in MemError. Since Munger is written in assembly, it doesn't use this little subroutine. Hence, MemError never gets set with the result code. I've heard that there will be an article on this in an upcoming issue of d e v e l o p. -- ------------------------------------------------------------------------------ Keith Rollin --- Apple Computer, Inc. --- Developer Technical Support INTERNET: keith@apple.com UUCP: {decwrl, hoptoad, nsc, sun, amdahl}!apple!keith "Argue for your Apple, and sure enough, it's yours" - Keith Rollin, Contusions
russotto@eng.umd.edu (Matthew T. Russotto) (07/13/90)
In article <42917@apple.Apple.COM> keith@Apple.COM (Keith Rollin) writes: >When Munger needs some more memory, it calls SetHandleSize. If >SetHandleSize returns an error (returned in register D0), Munger exits >immediately. This means that the error result code is still in D0, and >you can retrieve it with a little bit of glue code or inline assembly. > >The reason why MemError isn't set is because the Memory Manager doesn't >set it; that's the function of the glue code provided for those calls >by your development system. Your call to something like SetHandleSize >is really a call to subroutine that takes your parameters off the stack, >puts them in registers, calls the function, and puts the result code in >MemError. Since Munger is written in assembly, it doesn't use this >little subroutine. Hence, MemError never gets set with the result >code. Says Inside Mac, Volume 4: All Memory Manager routines (including the RecoverHandle function) return a result code that you can examine by calling the MemError function. And a look at the SetHandleSize function reveals that it does indeed move D0 to MemErr... Hmmmm. (Unless, of course, you are running under the 64K Roms) -- Matthew T. Russotto russotto@eng.umd.edu russotto@wam.umd.edu ][, ][+, ///, ///+, //e, //c, IIGS, //c+ --- Any questions? Hey! Bush has NO LIPS!
russotto@eng.umd.edu (Matthew T. Russotto) (07/13/90)
In article <42917@apple.Apple.COM> keith@Apple.COM (Keith Rollin) writes: >In article <233@sun13.scri.fsu.edu> pepke@gw.scri.fsu.edu (Eric Pepke) writes: >>Speaking of Munger, it's a cute little routine, but what happens when it >>fails due to insufficient memory? >> >>I run this little test program: >> >>#include <stdio.h> >>#include <MacTypes.h> >>#include <MemoryMgr.h> >> >>main() >>{ >> unsigned char buffer[1000]; >> Handle block; >> long beforeLength, afterLength; >> >> printf("Yahoo!\n"); >> >> block = NewHandle(0L); >> >> for (;;) >> { >> beforeLength = GetHandleSize(block); >> Munger(block, GetHandleSize(block), (unsigned char *) 0, >> 0L, buffer, (long) sizeof(buffer)); >> afterLength = GetHandleSize(block); >> >> if (beforeLength + sizeof(buffer) > afterLength || MemError()) >> { >> printf("\nSize increased from %ld to %ld\n", >> beforeLength, afterLength); >> printf("MemError() == %d\n", MemError()); >> exit(-1); >> } >> else >> { >> printf("."); >> } >> } >>} >> >>and I get >> >>Yahoo! >>........................................................................... >>..... >>........................................................................... >>..... >>........................................................................... >>..... >>....................................................................... >>Size increased from 311000 to 311000 >>MemError() == 0 >> >>So, when Munger fails due to lack of memory, you cannot tell from looking >>at MemError. In this case, at least, it left the handle unchanged. Can >>somebody who knows about the internals of Munger tell me if that is >>guaranteed to be the case, or is there a possibility that the handle will >>be corrupted in any way, such as being left larger than it was but not as >>large as is needed? > > [detailed, but, except on the 64K ROMs, incorrect explanation...Sorry Keith] The real reason your MemError() test is failing is that printf uses the memory manager, and that clears MemErr (because the calls printf makes succeed) -- Matthew T. Russotto russotto@eng.umd.edu russotto@wam.umd.edu ][, ][+, ///, ///+, //e, //c, IIGS, //c+ --- Any questions? Hey! Bush has NO LIPS!
pepke@gw.scri.fsu.edu (Eric Pepke) (07/14/90)
In article <1990Jul13.142801.6843@eng.umd.edu> russotto@eng.umd.edu (Matthew T. Russotto) writes: > The real reason your MemError() test is failing is that printf uses the memory > manager, and that clears MemErr (because the calls printf makes succeed) No. C evaluates the operands to printf before it invokes it. However, you are partially correct in that it was my error. It's not the printf call that resets MemErr; it's the GetHandleSize. If I put the return value of MemError into a variable before calling that, it returns -108, which is exactly what I had hoped. Eric Pepke INTERNET: pepke@gw.scri.fsu.edu Supercomputer Computations Research Institute MFENET: pepke@fsu Florida State University SPAN: scri::pepke Tallahassee, FL 32306-4052 BITNET: pepke@fsu Disclaimer: My employers seldom even LISTEN to my opinions. Meta-disclaimer: Any society that needs disclaimers has too many lawyers.
keith@Apple.COM (Keith Rollin) (07/16/90)
In article <1990Jul13.135946.6664@eng.umd.edu> russotto@eng.umd.edu (Matthew T. Russotto) writes: >In article <42917@apple.Apple.COM> keith@Apple.COM (Keith Rollin) writes: >>When Munger needs some more memory, it calls SetHandleSize. If >>SetHandleSize returns an error (returned in register D0), Munger exits >>immediately. This means that the error result code is still in D0, and >>you can retrieve it with a little bit of glue code or inline assembly. >> >>The reason why MemError isn't set is because the Memory Manager doesn't >>set it; that's the function of the glue code provided for those calls >>by your development system. Your call to something like SetHandleSize >>is really a call to subroutine that takes your parameters off the stack, >>puts them in registers, calls the function, and puts the result code in >>MemError. Since Munger is written in assembly, it doesn't use this >>little subroutine. Hence, MemError never gets set with the result >>code. > >Says Inside Mac, Volume 4: >All Memory Manager routines (including the RecoverHandle function) return a >result code that you can examine by calling the MemError function. > >And a look at the SetHandleSize function reveals that it does indeed move >D0 to MemErr... Hmmmm. (Unless, of course, you are running under the 64K >Roms) Sigh. Again, I've thrown a walk concerning Munger. Eric eventually found the problem (he was making another Memory Manager call and erasing MemErr from the Munger call). I had assumed that the Memory Manager didn't actually set MemErr because there was glue that also did it. -- ------------------------------------------------------------------------------ Keith Rollin --- Apple Computer, Inc. --- Developer Technical Support INTERNET: keith@apple.com UUCP: {decwrl, hoptoad, nsc, sun, amdahl}!apple!keith "Argue for your Apple, and sure enough, it's yours" - Keith Rollin, Contusions
oster@well.sf.ca.us (David Phillip Oster) (07/18/90)
One of my clients claims that Munger has bugs with offsets over 32k. I haven't checked this out for myself. -- -- David Phillip Oster - Note new address. Old one has gone Bye Bye. -- oster@well.sf.ca.us = {backbone}!well!oster