home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / sys / mac / programm / 21992 < prev    next >
Encoding:
Internet Message Format  |  1993-01-23  |  5.4 KB

  1. Path: sparky!uunet!olivea!pagesat!netsys!agate!stanford.edu!eos!data.nas.nasa.gov!taligent!kip-50.taligent.com!user
  2. From: keith@taligent.com (Keith Rollin)
  3. Newsgroups: comp.sys.mac.programmer
  4. Subject: Re: Verifying valid handles, how to?
  5. Message-ID: <keith-220193155445@kip-50.taligent.com>
  6. Date: 23 Jan 93 00:04:58 GMT
  7. References: <1993Jan22.015520.1@fnalo.fnal.gov> <NEERI.93Jan22190934@iis.ethz.ch>
  8. Sender: usenet@taligent.com (More Bytes Than You Can Read)
  9. Followup-To: comp.sys.mac.programmer
  10. Organization: Taligent
  11. Lines: 133
  12.  
  13. In article <NEERI.93Jan22190934@iis.ethz.ch>, neeri@iis.ethz.ch (Matthias
  14. Neeracher) wrote:
  15. > In article <1993Jan22.015520.1@fnalo.fnal.gov>, gwatts@fnalo.fnal.gov writes:
  16. > >   At any rate, I was thinking.  I've got only indirect objects in my project.
  17. > > This means every object is a handle, right?  Well, why not, in the debug
  18. > > version of the message dispatcher (oopDebug library) put a little code that
  19. > > will check the object is infact allocated as a handle?
  20. > >   I checked out the routine in msg.c (in the oops Libraries folder), and
  21. > > the handle is stored in register a1.  I don't know, however, how to check
  22. > > if it is a valid handle without causing an error (bus or otherwise) of
  23. > > somesort.  Especially if it is a random number!  Anyone know?  Is there
  24. > > some memory manager routine, given a suspected handle, will tell me this?
  25. > Here you go. This code is not guaranteed to work 100% of the time, but I doubt
  26. > you will get it to produce an address error for any normal memory setup (One
  27. > exception I can think of are macs with a memory upgrade that makes the ROM
  28. > appear in the middle of the application heap).
  29. > /* Heuristic to determine whether a given address is a Handle            */
  30. > /* Based on the articles of Lloyd Lim and Matthew T Russotto in the UMPG */
  31. > /* This code may be redistributed without any restrictions               */
  32. > Boolean RealHandle(void * addr)
  33. > {
  34. >    THz   sysZone;
  35. >    THz   applZone;
  36. >    THz   heapZone;
  37. >    
  38. >    addr  =  StripAddress(addr);
  39. >    if (addr && !((long) addr & 1))  {
  40. >       sysZone  =  SystemZone();
  41. >       applZone =  ApplicZone();
  42. >       if (addr >= (Ptr) &sysZone->heapData   && 
  43. >           addr <  (Ptr) sysZone->bkLim          ||
  44. >           addr >= (Ptr) &applZone->heapData  && 
  45. >           addr <  (Ptr) applZone->bkLim
  46. >          )
  47. >          if (*(long *)addr && !(*(long *)addr & 1)) {
  48. >             heapZone =  HandleZone(addr);
  49. >             if (!MemError())
  50. >                if (heapZone == sysZone || heapZone == applZone)
  51. >                   return true;
  52. >          }
  53. >    }
  54. >    
  55. >    return false;
  56. > }
  57.  
  58. I think that the above routine tries to validate any value that you might
  59. have lying around. However, if you have a value that you know at one time
  60. was a handle, you might want to check to see if it's on the free chain or
  61. not (this code is from MacApp):
  62.  
  63. Boolean IsFreeHandle(Handle aHandle)
  64. {
  65.     THz applZone = ApplicZone();
  66.     Handle currHandle = (Handle) applZone->hFstFree;
  67.  
  68.     while (currHandle != NULL)
  69.     {
  70.         if (currHandle == aHandle)
  71.             return TRUE;
  72.         currHandle = (Handle) * currHandle;
  73.     }
  74.     return FALSE;
  75. }
  76.  
  77. If course, nothing will help you if the master pointer has been
  78. re-allocated. Your old handle will now be pointing to a new, perfectly
  79. valid block of memory. I think the only thing you can do at that point is
  80. check the handle size against sizeof(TYourClass).
  81.  
  82. Greg Marriott (who was seen the other night at the Red Pepper with Cindy
  83. Jasper) wrote an INIT that tries to detect double-dispose bugs. It's on
  84. Apple's Developer CD and probably other places. Here are the release notes
  85. for your reading pleasure:
  86.  
  87. ;
  88. ;    DoubleTrouble - by Greg Marriott
  89. ;
  90. ;    ) 1992, Apple Computer, Inc.
  91. ;
  92. ;    DoubleTrouble is a debugging utility made to catch a common programming
  93. error:
  94. ;    freeing a handle that has already been freed.  (I call these errors
  95. Rdouble
  96. ;    dispose bugsSI)
  97. ;
  98. ;    When _DisposeHandle is called on a handle, the memory manager adds the
  99. handle
  100. ;    to its Rfree list,S a linked list of handles available for the allocator
  101. to use.
  102. ;    Calling _DisposeHandle on that handle again is usually benign.  The
  103. memory
  104. ;    manager dereferences the handle, pointing to the next handle in the free
  105. list.
  106. ;    If the the dereferenced handle points to the first handle in a master
  107. pointer block,
  108. ;    however, the handle appears valid because it points to a real block.  The
  109. memory
  110. ;    manager fails to realize the block is NOT a relocatable block (all master
  111. pointer
  112. ;    blocks are nonrelocatable), and marks it free (yikes!).  The freed master
  113. pointer
  114. ;    block is then used in a future allocation (usually very soon after being
  115. freed).
  116. ;    This mangles several master pointers and the free list.  Crashes soon
  117. follow.
  118. ;
  119. ;    This kind of bug is very hard to track down, and usually difficult to
  120. reproduce,
  121. ;    because master pointer blocks contain 64 handles (by default, some
  122. programs
  123. ;    change this behavior).  So, this situation only comes up about 1/64th of
  124. the
  125. ;    time.  When it happens, though, the results are inevitably catastrophic.
  126. ;
  127. ;    DoubleTrouble compares each handle being disposed to every handle in the
  128. free list of
  129. ;    the zone containing the handle.  If the handle is already in the free
  130. list, DoubleTrouble
  131. ;    breaks into the debugger with a message indicating whatUs going on. 
  132. Continuing execution
  133. ;    will stuff memWZErr (WhichZone failed, -111) into MemErr and d0 and
  134. return to the caller
  135. ;    (and NOT call through to _DisposeHandle).
  136. ;    
  137.  
  138. -----
  139. Keith Rollin
  140. Phantom Programmer
  141. Taligent, Inc.
  142.