lim@iris.ucdavis.edu (Lloyd Lim) (06/04/90)
This is perhaps not the best thing to do on a Mac but I need to be able to tell if some arbitrary long is a real handle in the System heap or the current app heap. I want to keep it relatively clean so I don't want to go looking through the heap's internal structures. Currently, I use the following code: Boolean ValidHandle(address) register long address; { register Boolean valid; register THz heapZone; valid = FALSE; if (address && !(address & 1)) { heapZone = HandleZone(address); if (!MemError() && (heapZone == SystemZone() || heapZone == ApplicZone())) { valid = TRUE; } } return(valid); } The problem is that this routine can get passed any arbitrary long and that some values seem to cause a bus error with HandleZone. I say "seem" because I haven't been able to find a value which causes a bus error in a test program but bus errors do occur in the real situation if enough values are examined. The real situation is practically unobservable. Any ideas on a better way? If you try doing extra checking before calling HandleZone, you'll get bus errors right away when you do (*(Ptr) address). If there is a solution that isn't right 100% of the time but doesn't cause bus errors, that would also be ok. +++ Lloyd Lim Internet: lim@iris.ucdavis.edu (128.120.57.20) Compuserve: 72647,660 US Mail: 146 Lysle Leach Hall, U.C. Davis, Davis, CA 95616
russotto@eng.umd.edu (Matthew T. Russotto) (06/05/90)
In article <7426@ucdavis.ucdavis.edu> lim@iris.ucdavis.edu (Lloyd Lim) writes: >This is perhaps not the best thing to do on a Mac but I need to be able to >tell if some arbitrary long is a real handle in the System heap or the current >app heap. I want to keep it relatively clean so I don't want to go looking >through the heap's internal structures. Currently, I use the following code: > >Boolean ValidHandle(address) > >register long address; > >{ > register Boolean valid; > register THz heapZone; > > valid = FALSE; > if (address && !(address & 1)) { > heapZone = HandleZone(address); > if (!MemError() && (heapZone == SystemZone() || > heapZone == ApplicZone())) { > valid = TRUE; > } > } > return(valid); >} > >The problem is that this routine can get passed any arbitrary long and that >some values seem to cause a bus error with HandleZone. I say "seem" because >I haven't been able to find a value which causes a bus error in a test program >but bus errors do occur in the real situation if enough values are examined. >The real situation is practically unobservable. Check to see if the handle itself is below BufPtr or MemTop or whatever variable you feel is appropriate. If it's below that, there should never be a bus error. Then do validity checks on *address, and check to see if IT is below BufPtr or MemTop. Then call HandleZone. -- Matthew T. Russotto russotto@eng.umd.edu russotto@wam.umd.edu ][, ][+, ///, ///+, //e, //c, IIGS, //c+ --- Any questions?
odawa@well.sf.ca.us (Michael Odawa) (06/07/90)
In article <7426@ucdavis.ucdavis.edu> lim@iris.ucdavis.edu (Lloyd Lim) writes: > ...I need to be able to tell if some arbitrary long is a real handle in > the System heap or the current app heap. I want to keep it relatively clean > so I don't want to go looking through the heap's internal structures...The > problem is that this routine can get passed any arbitrary long and that some > values seem to cause a bus error with HandleZone....Any ideas on a better > way? You have to make a range check against the high end of your memory. Here's something you might add to your code: { register Boolean valid; register THz heapZone; valid = FALSE; if (address && !(address & 1)) { if (address < long(**ApplicZone.BkLim)) { /***** Add this line *****/ heapZone = HandleZone(address); if (!MemError() && (heapZone == SystemZone() || heapZone == ApplicZone())) { valid = TRUE; } } return(valid); } A different check (which I do in my version of ValidHandle) might be to determine whether the tag byte on the block header (the first of the eight bytes which preceed the address) contained 0x8x, as documented in IM II-24: if (address < long(**ApplicZone.BkLim)) if ((*(ptr)(address - 8) & 0x80) != 0) valid = TRUE; Of course, we have not even begun to discuss problems with 24-bit vs 32-bit addressing schemes. So perhaps we ought to preceed our code by address = (long)StripAddress((ptr)address); ----- Michael Odawa Simple Software odawa@well.sf.ca.us
lsr@Apple.COM (Larry Rosenstein) (06/08/90)
In article <18379@well.sf.ca.us> odawa@well.sf.ca.us (Michael Odawa) writes: > A different check (which I do in my version of ValidHandle) might be to > determine whether the tag byte on the block header (the first of the eight > bytes which preceed the address) contained 0x8x, as documented in IM II-24: Unfortunately, this isn't 32-bit clean. The block headers in the 32-bit Memory Manager seem to be 12 bytes long (instead of 8). (I say "seem to be" since I was poking around without documentation.) In addition to the other tests that were mentioned, you might try testing whether RecoverHandle(addresss^)=address. (This is part of MacApp's IsHandle check.) If you do this, you have to be careful because RecoverHandle only works if the current heap zone is the same as the handle's. You also have to check for an empty handle (one whose master pointer is NIL). Larry Rosenstein, Apple Computer, Inc. Object Specialist Internet: lsr@Apple.com UUCP: {nsc, sun}!apple!lsr AppleLink: Rosenstein1