home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Memory / MemHooks.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  9.7 KB  |  330 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        MemHooks.cpp
  3.  
  4.     Contains:    Memory manager hook classes for debugging
  5.  
  6.     Owned by:    Michael Burbidge
  7.     Owned by:    Jens Alfke
  8.  
  9.     Copyright:    © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13.          <9>      8/4/95    DM        Leak checking [1267956]
  14.          <8>      5/4/95    jpa        Added AboutToAllocate.
  15.          <7>    10/24/94    jpa        Constness [1194286]
  16.          <6>     9/29/94    RA        1189812: Mods for 68K build.
  17.          <5>     9/14/94    jpa        Eliminated dependencies on rest of OpenDoc.
  18.                                     [1186692]
  19.          <4>      8/8/94    jpa        DidAllocate doesn't offset ptr if it's NULL
  20.                                     [1179564]
  21.          <3>      8/8/94    jpa        Fixed realloc hooks.
  22.          <2>      8/2/94    jpa        Now supports realloc. Also optimized some
  23.                                     code, and fed different zap values into the
  24.                                     cushion blocks when deleting.
  25.          <1>     7/26/94    jpa        first checked in
  26.          
  27.     To Do:
  28.     In Progress:
  29.         
  30. */
  31.  
  32.  
  33. #ifndef _MEMCNFIG_
  34. #include "MemCnfig.h"
  35. #endif
  36.  
  37.  
  38. #if MM_DEBUG
  39.  
  40.  
  41. #ifndef _MEMHOOKS_
  42. #include "MemHooks.h"
  43. #endif
  44.  
  45. #ifndef _PLATFMEM_
  46. #include "PlatfMem.h"
  47. #endif
  48.  
  49. #ifndef _CRAWL_
  50. #include <Crawl.h>
  51. #endif
  52.  
  53.  
  54. //==============================================================================
  55. // CBlockCushionHook
  56. //==============================================================================
  57.  
  58. //------------------------------------------------------------------------------
  59. // CBlockCushionHook::CBlockCushionHook
  60. //------------------------------------------------------------------------------
  61.  
  62. CBlockCushionHook::CBlockCushionHook()
  63. {
  64. }
  65.  
  66. //------------------------------------------------------------------------------
  67. // CBlockCushionHook::~CBlockCushionHook
  68. //------------------------------------------------------------------------------
  69.  
  70. CBlockCushionHook::~CBlockCushionHook()
  71. {
  72. }
  73.  
  74. //------------------------------------------------------------------------------
  75. // CBlockCushionHook::GetHeaderSize
  76. //------------------------------------------------------------------------------
  77.  
  78. ODBlockSize CBlockCushionHook::GetHeaderSize()
  79. {
  80.     return kPrefixCushionLength;
  81. }
  82.  
  83. //------------------------------------------------------------------------------
  84. // CBlockCushionHook::AboutToAllocate
  85. //------------------------------------------------------------------------------
  86.  
  87. ODBlockSize CBlockCushionHook::AboutToAllocate(ODBlockSize size) const
  88. {
  89.     return size + kPrefixCushionLength + kSuffixCushionLength;
  90. }
  91.  
  92. //------------------------------------------------------------------------------
  93. // CBlockCushionHook::DidAllocate
  94. //------------------------------------------------------------------------------
  95.  
  96. void* CBlockCushionHook::DidAllocate(void* blk, ODBlockSize size)
  97. {
  98.     if( blk == kMMNULL )
  99.         return kMMNULL;
  100.     else {
  101.         unsigned long *prefix
  102.             = (unsigned long *) blk;
  103.         unsigned long *suffix
  104.             = (unsigned long *) ((char *) blk + size - kSuffixCushionLength);
  105.         
  106.         *prefix++ = kPrefixCushionMagicNumber;
  107.         *prefix++ = size;
  108.         *prefix++ = kPrefixCushionMagicNumber;
  109.             
  110.         *suffix = kSuffixCushionMagicNumber;
  111.     
  112.         return (char *) blk + kPrefixCushionLength;
  113.     }
  114. }
  115.  
  116. //------------------------------------------------------------------------------
  117. // CBlockCushionHook::AboutToBlockSize
  118. //------------------------------------------------------------------------------
  119.  
  120. const void* CBlockCushionHook::AboutToBlockSize(const void* blk)
  121. {
  122.     unsigned long *prefix = (unsigned long *) ((char*)blk - kPrefixCushionLength);
  123.     
  124.     if( prefix[0]!=kPrefixCushionMagicNumber || prefix[2]!=kPrefixCushionMagicNumber )
  125.         MM_WARN("Block %p's prefix is invalid",blk);
  126.     
  127.     unsigned long *suffix = (unsigned long *)
  128.         ((char*)prefix + prefix[1] - kSuffixCushionLength);
  129.     
  130.     if( *suffix != kSuffixCushionMagicNumber )
  131.         MM_WARN("Block %p's suffix is invalid",blk);
  132.  
  133.     return prefix;
  134. }
  135.  
  136. //------------------------------------------------------------------------------
  137. // CBlockCushionHook::BasicAboutToFree
  138. //------------------------------------------------------------------------------
  139.  
  140. unsigned long* CBlockCushionHook::BasicAboutToFree(void* blk, MMBoolean zap)
  141. {
  142.     unsigned long *prefix = (unsigned long *) ((char*)blk - kPrefixCushionLength);
  143.  
  144.     if( prefix[0]!=kPrefixCushionMagicNumber || prefix[2]!=kPrefixCushionMagicNumber )
  145.         MM_WARN("Block %p's prefix is invalid",blk);
  146.     
  147.     unsigned long *suffix = (unsigned long *)
  148.         ((char*)prefix + prefix[1] - kSuffixCushionLength);
  149.     
  150.     if( *suffix != kSuffixCushionMagicNumber )
  151.         MM_WARN("Block %p's suffix is invalid",blk);
  152.  
  153.     if( zap )
  154.         prefix[0] = prefix[2] = *suffix = 0xDDDDDDDD;        // Zap on free
  155.  
  156.     return prefix;
  157. }
  158.  
  159. //------------------------------------------------------------------------------
  160. // CBlockCushionHook::AboutToFree
  161. //------------------------------------------------------------------------------
  162.  
  163. void* CBlockCushionHook::AboutToFree(void* blk)
  164. {
  165.     return this->BasicAboutToFree(blk,kMMTrue);
  166. }
  167.  
  168. //------------------------------------------------------------------------------
  169. // CBlockCushionHook::AboutToRealloc
  170. //------------------------------------------------------------------------------
  171.  
  172. void CBlockCushionHook::AboutToRealloc(void* &blk , ODBlockSize &size)
  173. {
  174.     // The current block will be freed, and a new one allocated.
  175.     blk = this->BasicAboutToFree(blk,kMMFalse);        // Don't zap it, it might not get freed
  176.     size += kPrefixCushionLength + kSuffixCushionLength;
  177. }
  178.  
  179. //------------------------------------------------------------------------------
  180. // CBlockCushionHook::DidRealloc
  181. //------------------------------------------------------------------------------
  182.  
  183. void* CBlockCushionHook::DidRealloc(void* oldBlk, void* blk, ODBlockSize size)
  184. {
  185.     return this->DidAllocate(blk,size);
  186. }
  187.  
  188.  
  189.  
  190.  
  191. //==============================================================================
  192. // CBlockStackCrawlHook
  193. //==============================================================================\
  194.  
  195.  
  196. MMBoolean CBlockStackCrawlHook::gTrack;
  197.  
  198. // Global operator new/delete for StackCrawl objects
  199. void* operator new( size_t size )
  200. {
  201.     return MMAllocate(size);
  202. }
  203.  
  204. void operator delete( void* block )
  205. {
  206.     MMFree(block);
  207. }
  208.  
  209.  
  210. //------------------------------------------------------------------------------
  211. // CBlockStackCrawlHook::GetHeaderSize
  212. //------------------------------------------------------------------------------
  213.  
  214. ODBlockSize CBlockStackCrawlHook::GetHeaderSize()
  215. {
  216.     return sizeof(StackCrawl*);
  217. }
  218.  
  219. //------------------------------------------------------------------------------
  220. // CBlockStackCrawlHook::AboutToAllocate
  221. //------------------------------------------------------------------------------
  222.  
  223. ODBlockSize CBlockStackCrawlHook::AboutToAllocate(ODBlockSize size) const
  224. {
  225.     return size + sizeof(StackCrawl*);
  226. }
  227.  
  228. //------------------------------------------------------------------------------
  229. // CBlockStackCrawlHook::DidAllocate
  230. //------------------------------------------------------------------------------
  231.  
  232. void* CBlockStackCrawlHook::DidAllocate(void* blk, ODBlockSize size)
  233. {
  234.     if( blk == kMMNULL )
  235.         return kMMNULL;
  236.     else {
  237.         StackCrawl**stackCrawl = (StackCrawl**)blk;    // Points to where it's stored
  238.         if( gTrack ) {
  239.             gTrack = kMMFalse; // Disable to prevent recursion!
  240.             *stackCrawl = StackCrawl::New(3,-5);
  241.             gTrack = kMMTrue;
  242.         } else
  243.             *stackCrawl = 0;
  244.         return stackCrawl + 1;
  245.     }
  246. }
  247.  
  248. //------------------------------------------------------------------------------
  249. // CBlockStackCrawlHook::AboutToBlockSize
  250. //------------------------------------------------------------------------------
  251.  
  252. const void* CBlockStackCrawlHook::AboutToBlockSize(const void* blk)
  253. {
  254.     return ((StackCrawl**)blk) - 1;
  255. }
  256.  
  257. //------------------------------------------------------------------------------
  258. // CBlockStackCrawlHook::BasicAboutToFree
  259. //------------------------------------------------------------------------------
  260.  
  261. void* CBlockStackCrawlHook::BasicAboutToFree(void* blk, MMBoolean zap)
  262. {
  263.     StackCrawl** s = (StackCrawl**)blk - 1;
  264.     if( zap ) {
  265.         delete (StackCrawl*) ((size_t)(*s) & ~3);    // Delete crawl, mask lo bits
  266.         *s = (StackCrawl*) 0xDDDDDDDD;                // Zap on free
  267.     }
  268.     return s;
  269. }
  270.  
  271. //------------------------------------------------------------------------------
  272. // CBlockStackCrawlHook::AboutToFree
  273. //------------------------------------------------------------------------------
  274.  
  275. void* CBlockStackCrawlHook::AboutToFree(void* blk)
  276. {
  277.     return this->BasicAboutToFree(blk,kMMTrue);
  278. }
  279.  
  280. //------------------------------------------------------------------------------
  281. // CBlockStackCrawlHook::AboutToRealloc
  282. //------------------------------------------------------------------------------
  283.  
  284. void CBlockStackCrawlHook::AboutToRealloc(void* &blk , ODBlockSize &size)
  285. {
  286.     // The current block will be freed, and a new one allocated.
  287.     blk = this->BasicAboutToFree(blk,kMMFalse);        // Don't zap it, it might not get freed
  288.     size += sizeof(StackCrawl*);
  289. }
  290.  
  291. //------------------------------------------------------------------------------
  292. // CBlockStackCrawlHook::DidRealloc
  293. //------------------------------------------------------------------------------
  294.  
  295. void* CBlockStackCrawlHook::DidRealloc(void* oldBlk, void* blk, ODBlockSize size)
  296. {
  297.     return this->DidAllocate(blk,size);
  298. }
  299.  
  300. //------------------------------------------------------------------------------
  301. // CBlockStackCrawlHook::GetType
  302. //------------------------------------------------------------------------------
  303.  
  304. long CBlockStackCrawlHook::GetType( ) const
  305. {
  306.     return kBlockStackCrawlHookType;
  307. }
  308.  
  309. //------------------------------------------------------------------------------
  310. // CBlockStackCrawlHook::GetStackCrawl
  311. //------------------------------------------------------------------------------
  312.  
  313. StackCrawl* CBlockStackCrawlHook::GetStackCrawl(const void* blk) const
  314. {
  315.     return * (StackCrawl**) blk;
  316. }
  317.  
  318. //------------------------------------------------------------------------------
  319. // CBlockStackCrawlHook::SetStackCrawl
  320. //------------------------------------------------------------------------------
  321.  
  322. void CBlockStackCrawlHook::SetStackCrawl(const void* blk, StackCrawl* s)
  323. {
  324.     * (StackCrawl**) blk = s;
  325. }
  326.  
  327.  
  328.  
  329.  
  330. #endif /*MM_DEBUG*/