home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 August - Disc 3 / chip_20018103_hu.iso / amiga / chiputil / wipeout.lha / source / monitoring.c < prev    next >
C/C++ Source or Header  |  1999-10-07  |  18KB  |  863 lines

  1. /*
  2.  * $Id: monitoring.c 1.5 1999/10/07 11:01:17 olsen Exp olsen $
  3.  *
  4.  * :ts=4
  5.  *
  6.  * Wipeout -- Traces and munges memory and detects memory trashing
  7.  *
  8.  * Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
  9.  * Public Domain
  10.  */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "global.h"
  14. #endif    /* _GLOBAL_H */
  15.  
  16. /******************************************************************************/
  17.  
  18. #include "installpatches.h"
  19.  
  20. /******************************************************************************/
  21.  
  22. STATIC VOID
  23. WaitForBreak(VOID)
  24. {
  25.     STRPTR taskTypeName;
  26.  
  27.     taskTypeName = GetTaskTypeName(GetTaskType(NULL));
  28.  
  29.     /* tell the user that a task is needing attention */
  30.     if(CANNOT GetTaskName(NULL,GlobalNameBuffer,sizeof(GlobalNameBuffer)))
  31.     {
  32.         DPrintf("WAITING; to continue, send ^C to %s \"%s\" (task 0x%08lx).\n",taskTypeName,GlobalNameBuffer,FindTask(NULL));
  33.     }
  34.     else
  35.     {
  36.         DPrintf("WAITING; to continue, send ^C to this %s (task 0x%08lx).\n",taskTypeName,FindTask(NULL));
  37.     }
  38.  
  39.     /* wait for the wakeup signal */
  40.     SetSignal(0,SIGBREAKF_CTRL_C);
  41.     Wait(SIGBREAKF_CTRL_C);
  42.  
  43.     DPrintf("\n");
  44. }
  45.  
  46. /******************************************************************************/
  47.  
  48. STATIC BOOL
  49. CalledFromSupervisorMode(VOID)
  50. {
  51.     BOOL supervisorMode;
  52.  
  53.     supervisorMode = (BOOL)((GetCC() & 0x2000) != 0);
  54.  
  55.     /* If this routine returns TRUE, then the CPU is currently
  56.      * processing an interrupt request or an exception condition
  57.      * was triggered (more or less the same).
  58.      */
  59.     return(supervisorMode);
  60. }
  61.  
  62. /******************************************************************************/
  63.  
  64. BOOL
  65. CheckStomping(ULONG * stackFrame,struct TrackHeader * th)
  66. {
  67.     BOOL wasStomped = FALSE;
  68.     UBYTE * mem;
  69.     LONG memSize;
  70.     UBYTE * stompMem;
  71.     LONG stompSize;
  72.     UBYTE * body;
  73.  
  74.     body = ((UBYTE *)(th + 1)) + PreWallSize;
  75.  
  76.     mem = (UBYTE *)(th + 1);
  77.     memSize = PreWallSize;
  78.  
  79.     /* check if the pre-allocation wall was trashed */
  80.     if(WasStompedUpon(mem,memSize,th->th_FillChar,&stompMem,&stompSize))
  81.     {
  82.         if(IsActive)
  83.         {
  84.             VoiceComplaint(stackFrame,th,"Front wall was stomped upon\n");
  85.  
  86.             DPrintf("%ld byte(s) stomped (0x%08lx..0x%08lx), allocation-%ld byte(s)\n",
  87.                 stompSize,stompMem,stompMem+stompSize-1,
  88.                 (LONG)body - (LONG)(stompMem+stompSize-1));
  89.  
  90.             DumpWall(stompMem,stompSize,th->th_FillChar);
  91.         }
  92.  
  93.         wasStomped = TRUE;
  94.     }
  95.  
  96.     mem += PreWallSize + th->th_Size;
  97.     memSize = th->th_PostSize;
  98.  
  99.     /* check if the post-allocation wall was trashed */
  100.     if(WasStompedUpon(mem,memSize,th->th_FillChar,&stompMem,&stompSize))
  101.     {
  102.         if(IsActive)
  103.         {
  104.             VoiceComplaint(stackFrame,th,"Back wall was stomped upon\n");
  105.  
  106.             DPrintf("%ld byte(s) stomped (0x%08lx..0x%08lx), allocation+%ld byte(s)\n",
  107.                 stompSize,stompMem,stompMem+stompSize-1,
  108.                 (LONG)stompMem - (LONG)(body + th->th_Size - 1));
  109.  
  110.             DumpWall(stompMem,stompSize,th->th_FillChar);
  111.         }
  112.  
  113.         wasStomped = TRUE;
  114.     }
  115.  
  116.     return(wasStomped);
  117. }
  118.  
  119. /******************************************************************************/
  120.  
  121. APTR ASM
  122. NewAllocMem(
  123.     REG(d0)    ULONG    byteSize,
  124.     REG(d1) ULONG    attributes,
  125.     REG(a2) ULONG *    stackFrame)
  126. {
  127.     APTR result = NULL;
  128.     BOOL hit = FALSE;
  129.  
  130.     /* no memory allocation routine may be called from supervisor mode */
  131.     if(NOT CalledFromSupervisorMode())
  132.     {
  133.         /* check if this allocation should be tracked */
  134.         if(byteSize <= 0x7FFFFFFF && IsActive && CanAllocate() && (NOT CheckConsistency || IsAllocationListConsistent()))
  135.         {
  136.             if(byteSize == 0)
  137.             {
  138.                 VoiceComplaint(stackFrame,NULL,"AllocMem(%ld,0x%08lx) called\n",byteSize,attributes);
  139.                 hit = TRUE;
  140.             }
  141.             else
  142.             {
  143.                 /* stackFrame[16] contains the return address of the caller */
  144.                 if(CANNOT PerformAllocation(stackFrame[16],NULL,byteSize,attributes,ALLOCATIONTYPE_AllocMem,&result))
  145.                 {
  146.                     if(ShowFail)
  147.                     {
  148.                         VoiceComplaint(stackFrame,NULL,"AllocMem(%ld,0x%08lx) failed\n",byteSize,attributes);
  149.                         hit = TRUE;
  150.                     }
  151.                 }
  152.             }
  153.         }
  154.         else
  155.         {
  156.             result = (*OldAllocMem)(byteSize,attributes,SysBase);
  157.         }
  158.     }
  159.     else
  160.     {
  161.         if(IsActive)
  162.         {
  163.             VoiceComplaint(stackFrame,NULL,"AllocMem(%ld,0x%08lx) called from interrupt/exception\n",byteSize,attributes);
  164.         }
  165.     }
  166.  
  167.     if(hit && WaitAfterHit)
  168.     {
  169.         WaitForBreak();
  170.     }
  171.  
  172.     return(result);
  173. }
  174.  
  175. VOID ASM
  176. NewFreeMem(
  177.     REG(a1)    APTR    memoryBlock,
  178.     REG(d0) ULONG    byteSize,
  179.     REG(a2) ULONG *    stackFrame)
  180. {
  181.     BOOL hit = FALSE;
  182.  
  183.     if(NOT CalledFromSupervisorMode())
  184.     {
  185.         if(memoryBlock == NULL || byteSize == NULL)
  186.         {
  187.             if(IsActive)
  188.             {
  189.                 VoiceComplaint(stackFrame,NULL,"FreeMem(0x%08lx,%ld) called\n",memoryBlock,byteSize);
  190.                 hit = TRUE;
  191.             }
  192.         }
  193.         else
  194.         {
  195.             struct TrackHeader * th;
  196.             BOOL freeIt = TRUE;
  197.  
  198.             /* check whether the memory list is consistent */
  199.             if(CheckConsistency && NOT IsAllocationListConsistent())
  200.             {
  201.                 freeIt = FALSE;
  202.             }
  203.  
  204.             /* memory may be deallocated only from an even address */
  205.             if(IsOddAddress((ULONG)memoryBlock))
  206.             {
  207.                 if(IsActive)
  208.                 {
  209.                     VoiceComplaint(stackFrame,NULL,"FreeMem(0x%08lx,%ld) on odd address\n",memoryBlock,byteSize);
  210.                     hit = TRUE;
  211.                 }
  212.     
  213.                 freeIt = FALSE;
  214.             }
  215.  
  216.             /* check if the address points into RAM */
  217.             if(IsInvalidAddress((ULONG)memoryBlock))
  218.             {
  219.                 if(IsActive)
  220.                 {
  221.                     VoiceComplaint(stackFrame,NULL,"FreeMem(0x%08lx,%ld) on illegal address\n",memoryBlock,byteSize);
  222.                     hit = TRUE;
  223.                 }
  224.     
  225.                 freeIt = FALSE;
  226.             }
  227.  
  228.             /* check if the memory to free is really allocated */
  229.             if(NOT IsAllocatedMemory((ULONG)memoryBlock,byteSize))
  230.             {
  231.                 if(IsActive)
  232.                 {
  233.                     VoiceComplaint(stackFrame,NULL,"FreeMem(0x%08lx,%ld) not in allocated memory\n",memoryBlock,byteSize);
  234.                     hit = TRUE;
  235.                 }
  236.     
  237.                 freeIt = FALSE;
  238.             }
  239.  
  240.             /* now test whether the allocation was tracked by us */
  241.             if(IsTrackedAllocation((ULONG)memoryBlock,&th))
  242.             {
  243.                 /* check whether the allocation walls were trashed */
  244.                 if(CheckStomping(stackFrame,th))
  245.                 {
  246.                     freeIt = FALSE;
  247.  
  248.                     if(IsActive)
  249.                     {
  250.                         hit = TRUE;
  251.                     }
  252.                 }
  253.     
  254.                 if(byteSize != th->th_Size)
  255.                 {
  256.                     if(IsActive)
  257.                     {
  258.                         VoiceComplaint(stackFrame,th,"Free size %ld does not match allocation size %ld\n",byteSize,th->th_Size);
  259.                         hit = TRUE;
  260.                     }
  261.     
  262.                     freeIt = FALSE;
  263.                 }
  264.     
  265.                 if(th->th_Type != ALLOCATIONTYPE_AllocMem)
  266.                 {
  267.                     if(IsActive)
  268.                     {
  269.                         VoiceComplaint(stackFrame,th,"In FreeMem(0x%08lx,%ld): Memory was not allocated with AllocMem()\n",memoryBlock,byteSize);
  270.                         hit = TRUE;
  271.                     }
  272.     
  273.                     freeIt = FALSE;
  274.                 }
  275.     
  276.                 if(freeIt)
  277.                 {
  278.                     PerformDeallocation(th);
  279.                 }
  280.                 else
  281.                 {
  282.                     /* Let it go, but don't deallocate it. */
  283.                     th->th_Magic = 0;
  284.                     FixTrackHeaderChecksum(th);
  285.                 }
  286.             }
  287.             else
  288.             {
  289.                 if(freeIt)
  290.                 {
  291.                     (*OldFreeMem)(memoryBlock,byteSize,SysBase);
  292.                 }
  293.             }
  294.         }
  295.     }
  296.     else
  297.     {
  298.         if(IsActive)
  299.         {
  300.             VoiceComplaint(stackFrame,NULL,"FreeMem(0x%08lx,%ld) called from interrupt/exception\n",memoryBlock,byteSize);
  301.         }
  302.     }
  303.  
  304.     if(hit && WaitAfterHit)
  305.     {
  306.         WaitForBreak();
  307.     }
  308. }
  309.  
  310. /******************************************************************************/
  311.  
  312. APTR ASM
  313. NewAllocVec(
  314.     REG(d0)    ULONG    byteSize,
  315.     REG(d1) ULONG    attributes,
  316.     REG(a2) ULONG *    stackFrame)
  317. {
  318.     APTR result = NULL;
  319.     BOOL hit = FALSE;
  320.  
  321.     if(NOT CalledFromSupervisorMode())
  322.     {
  323.         if(byteSize <= 0x7FFFFFFF && IsActive && CanAllocate() && (NOT CheckConsistency || IsAllocationListConsistent()))
  324.         {
  325.             if(byteSize == 0)
  326.             {
  327.                 VoiceComplaint(stackFrame,NULL,"AllocVec(%ld,0x%08lx) called\n",byteSize,attributes);
  328.                 hit = TRUE;
  329.             }
  330.             else
  331.             {
  332.                 if(CANNOT PerformAllocation(stackFrame[16],NULL,byteSize,attributes,ALLOCATIONTYPE_AllocVec,&result))
  333.                 {
  334.                     if(ShowFail)
  335.                     {
  336.                         VoiceComplaint(stackFrame,NULL,"AllocVec(%ld,0x%08lx) failed\n",byteSize,attributes);
  337.                         hit = TRUE;
  338.                     }
  339.                 }
  340.             }
  341.         }
  342.         else
  343.         {
  344.             result = (*OldAllocVec)(byteSize,attributes,SysBase);
  345.         }
  346.     }
  347.     else
  348.     {
  349.         if(IsActive)
  350.         {
  351.             VoiceComplaint(stackFrame,NULL,"AllocVec(%ld,0x%08lx) called from interrupt/exception\n",byteSize,attributes);
  352.         }
  353.     }
  354.  
  355.     if(hit && WaitAfterHit)
  356.     {
  357.         WaitForBreak();
  358.     }
  359.  
  360.     return(result);
  361. }
  362.  
  363. VOID ASM
  364. NewFreeVec(
  365.     REG(a1)    APTR    memoryBlock,
  366.     REG(a2) ULONG *    stackFrame)
  367. {
  368.     BOOL hit = FALSE;
  369.  
  370.     if(NOT CalledFromSupervisorMode())
  371.     {
  372.         if(memoryBlock != NULL)
  373.         {
  374.             struct TrackHeader * th;
  375.             BOOL freeIt = TRUE;
  376.  
  377.             /* check whether the memory list is consistent */
  378.             if(CheckConsistency && NOT IsAllocationListConsistent())
  379.             {
  380.                 freeIt = FALSE;
  381.             }
  382.  
  383.             if(IsOddAddress((ULONG)memoryBlock))
  384.             {
  385.                 if(IsActive)
  386.                 {
  387.                     VoiceComplaint(stackFrame,NULL,"FreeVec(0x%08lx) on odd address\n",memoryBlock);
  388.                     hit = TRUE;
  389.                 }
  390.     
  391.                 freeIt = FALSE;
  392.             }
  393.     
  394.             if(IsInvalidAddress((ULONG)memoryBlock))
  395.             {
  396.                 if(IsActive)
  397.                 {
  398.                     VoiceComplaint(stackFrame,NULL,"FreeVec(0x%08lx) on illegal address\n",memoryBlock);
  399.                     hit = TRUE;
  400.                 }
  401.     
  402.                 freeIt = FALSE;
  403.             }
  404.  
  405.             /* note that in order to check the size and the place of the
  406.              * allocation, the address must be valid
  407.              */
  408.             if(freeIt && NOT IsAllocatedMemory(((ULONG)memoryBlock)-4,(*(ULONG *)(((ULONG)memoryBlock)-4))))
  409.             {
  410.                 if(IsActive)
  411.                 {
  412.                     VoiceComplaint(stackFrame,NULL,"FreeVec(0x%08lx) not in allocated memory\n",memoryBlock);
  413.                     hit = TRUE;
  414.                 }
  415.     
  416.                 freeIt = FALSE;
  417.             }
  418.  
  419.             if(IsTrackedAllocation(((ULONG)memoryBlock) - sizeof(ULONG),&th))
  420.             {
  421.                 if(CheckStomping(stackFrame,th))
  422.                 {
  423.                     freeIt = FALSE;
  424.  
  425.                     if(IsActive)
  426.                     {
  427.                         hit = TRUE;
  428.                     }
  429.                 }
  430.     
  431.                 if(th->th_Type != ALLOCATIONTYPE_AllocVec)
  432.                 {
  433.                     if(IsActive)
  434.                     {
  435.                         VoiceComplaint(stackFrame,th,"In FreeVec(0x%08lx): Memory was not allocated with AllocVec()\n",memoryBlock);
  436.                         hit = TRUE;
  437.                     }
  438.     
  439.                     freeIt = FALSE;
  440.                 }
  441.     
  442.                 if(freeIt)
  443.                 {
  444.                     PerformDeallocation(th);
  445.                 }
  446.                 else
  447.                 {
  448.                     /* Let it go, but don't deallocate it. */
  449.                     th->th_Magic = 0;
  450.                     FixTrackHeaderChecksum(th);
  451.                 }
  452.             }
  453.             else
  454.             {
  455.                 if(freeIt)
  456.                 {
  457.                     (*OldFreeVec)(memoryBlock,SysBase);
  458.                 }
  459.             }
  460.         }
  461.     }
  462.     else
  463.     {
  464.         if(IsActive)
  465.         {
  466.             VoiceComplaint(stackFrame,NULL,"FreeVec(0x%08lx) called from interrupt/exception\n",memoryBlock);
  467.         }
  468.     }
  469.  
  470.     if(hit && WaitAfterHit)
  471.     {
  472.         WaitForBreak();
  473.     }
  474. }
  475.  
  476. /******************************************************************************/
  477.  
  478. APTR ASM
  479. NewCreatePool(
  480.     REG(d0)    ULONG    memFlags,
  481.     REG(d1) ULONG    puddleSize,
  482.     REG(d2) ULONG    threshSize,
  483.     REG(a2) ULONG *    stackFrame)
  484. {
  485.     APTR result = NULL;
  486.     BOOL hit = FALSE;
  487.  
  488.     if(NOT CalledFromSupervisorMode())
  489.     {
  490.         if(IsActive && CanAllocate() && (NOT CheckConsistency || IsAllocationListConsistent()))
  491.         {
  492.             /* the puddle threshold size must not be larger
  493.              * than the puddle size
  494.              */
  495.             if(threshSize <= puddleSize)
  496.             {
  497.                 struct PoolHeader * ph;
  498.         
  499.                 ph = CreatePoolHeader(memFlags,puddleSize,threshSize,stackFrame[16]);
  500.                 if(ph != NULL)
  501.                 {
  502.                     result = ph->ph_PoolHeader;
  503.                 }
  504.                 else
  505.                 {
  506.                     if(ShowFail)
  507.                     {
  508.                         VoiceComplaint(stackFrame,NULL,"CreatePool(0x%08lx,%ld,%ld) failed\n",memFlags,puddleSize,threshSize);
  509.                         hit = TRUE;
  510.                     }
  511.                 }
  512.             }
  513.             else
  514.             {
  515.                 VoiceComplaint(stackFrame,NULL,"Threshold size %ld must be <= puddle size %ld\n",threshSize,puddleSize);
  516.                 hit = TRUE;
  517.             }
  518.         }
  519.         else
  520.         {
  521.             result = (*OldCreatePool)(memFlags,puddleSize,threshSize,SysBase);
  522.         }
  523.     }
  524.     else
  525.     {
  526.         if(IsActive)
  527.         {
  528.             VoiceComplaint(stackFrame,NULL,"CreatePool(0x%08lx,%ld,%ld) called from interrupt/exception\n",memFlags,puddleSize,threshSize);
  529.         }
  530.     }
  531.  
  532.     if(hit && WaitAfterHit)
  533.     {
  534.         WaitForBreak();
  535.     }
  536.  
  537.     return(result);
  538. }
  539.  
  540. VOID ASM
  541. NewDeletePool(
  542.     REG(a0) APTR    poolHeader,
  543.     REG(a2) ULONG *    stackFrame)
  544. {
  545.     BOOL hit = FALSE;
  546.  
  547.     if(NOT CalledFromSupervisorMode())
  548.     {
  549.         if(poolHeader != NULL)
  550.         {
  551.             struct PoolHeader * ph;
  552.     
  553.             ph = FindPoolHeader(poolHeader);
  554.             if(ph != NULL)
  555.             {
  556.                 BOOL freeIt = TRUE;
  557.  
  558.                 /* check whether the memory list is consistent */
  559.                 if(CheckConsistency && NOT IsPuddleListConsistent(ph))
  560.                 {
  561.                     freeIt = FALSE;
  562.                 }
  563.  
  564.                 /* note that DeletePoolHeader() implies
  565.                  * HoldPoolSemaphore()..ReleasePoolSemaphore()
  566.                  */
  567.                 if(freeIt && CANNOT DeletePoolHeader(stackFrame,ph))
  568.                 {
  569.                     if(IsActive)
  570.                     {
  571.                         hit = TRUE;
  572.                     }
  573.                 }
  574.             }
  575.             else
  576.             {
  577.                 (*OldDeletePool)(poolHeader,SysBase);
  578.             }
  579.         }
  580.         else
  581.         {
  582.             if(IsActive)
  583.             {
  584.                 VoiceComplaint(stackFrame,NULL,"DeletePool(NULL) called\n");
  585.                 hit = TRUE;
  586.             }
  587.         }
  588.     }
  589.     else
  590.     {
  591.         if(IsActive)
  592.         {
  593.             VoiceComplaint(stackFrame,NULL,"DeletePool(0x%08lx) called from interrupt/exception\n",poolHeader);
  594.         }
  595.     }
  596.  
  597.     if(hit && WaitAfterHit)
  598.     {
  599.         WaitForBreak();
  600.     }
  601. }
  602.  
  603. /******************************************************************************/
  604.  
  605. APTR ASM
  606. NewAllocPooled(
  607.     REG(a0) APTR    poolHeader,
  608.     REG(d0) ULONG    memSize,
  609.     REG(a2) ULONG *    stackFrame)
  610. {
  611.     APTR result = NULL;
  612.     BOOL hit = FALSE;
  613.  
  614.     if(NOT CalledFromSupervisorMode())
  615.     {
  616.         if(memSize <= 0x7FFFFFFF && IsActive && CanAllocate())
  617.         {
  618.             if(poolHeader != NULL && memSize > 0)
  619.             {
  620.                 struct PoolHeader * ph;
  621.  
  622.                 /* check whether this memory pool is being tracked */
  623.                 ph = FindPoolHeader(poolHeader);
  624.                 if(ph != NULL)
  625.                 {
  626.                     BOOL allocateIt = TRUE;
  627.  
  628.                     if(CheckConsistency && NOT IsPuddleListConsistent(ph))
  629.                     {
  630.                         allocateIt = FALSE;
  631.                     }
  632.  
  633.                     if(allocateIt)
  634.                     {
  635.                         HoldPoolSemaphore(ph,stackFrame[16]);
  636.     
  637.                         if(CANNOT PerformAllocation(stackFrame[16],ph,memSize,ph->ph_Attributes,ALLOCATIONTYPE_AllocPooled,&result))
  638.                         {
  639.                             if(ShowFail)
  640.                             {
  641.                                 VoiceComplaint(stackFrame,NULL,"AllocPooled(0x%08lx,%ld) failed\n",poolHeader,memSize);
  642.                                 hit = TRUE;
  643.                             }
  644.                         }
  645.     
  646.                         ReleasePoolSemaphore(ph);
  647.                     }
  648.                 }
  649.                 else
  650.                 {
  651.                     result = (*OldAllocPooled)(poolHeader,memSize,SysBase);
  652.                 }
  653.             }
  654.             else
  655.             {
  656.                 VoiceComplaint(stackFrame,NULL,"AllocPooled(0x%08lx,%ld) called\n",poolHeader,memSize);
  657.                 hit = TRUE;
  658.             }
  659.         }
  660.         else
  661.         {
  662.             result = (*OldAllocPooled)(poolHeader,memSize,SysBase);
  663.         }
  664.     }
  665.     else
  666.     {
  667.         if(IsActive)
  668.         {
  669.             VoiceComplaint(stackFrame,NULL,"AllocPooled(0x%08lx,%ld) called from interrupt/exception\n",poolHeader,memSize);
  670.         }
  671.     }
  672.  
  673.     if(hit && WaitAfterHit)
  674.     {
  675.         WaitForBreak();
  676.     }
  677.  
  678.     return(result);
  679. }
  680.  
  681. VOID ASM
  682. NewFreePooled(
  683.     REG(a0)    APTR    poolHeader,
  684.     REG(a1)    APTR    memoryBlock,
  685.     REG(d0) ULONG    memSize,
  686.     REG(a2) ULONG *    stackFrame)
  687. {
  688.     BOOL hit = FALSE;
  689.  
  690.     if(NOT CalledFromSupervisorMode())
  691.     {
  692.         if(poolHeader != NULL && memoryBlock != NULL && memSize > 0)
  693.         {
  694.             struct PoolHeader * ph;
  695.             BOOL freeIt = TRUE;
  696.     
  697.             if(IsOddAddress((ULONG)memoryBlock))
  698.             {
  699.                 if(IsActive)
  700.                 {
  701.                     VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) on odd address\n",poolHeader,memoryBlock,memSize);
  702.                     hit = TRUE;
  703.                 }
  704.     
  705.                 freeIt = FALSE;
  706.             }
  707.     
  708.             if(IsInvalidAddress((ULONG)memoryBlock))
  709.             {
  710.                 if(IsActive)
  711.                 {
  712.                     VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) on illegal address\n",poolHeader,memoryBlock,memSize);
  713.                     hit = TRUE;
  714.                 }
  715.     
  716.                 freeIt = FALSE;
  717.             }
  718.     
  719.             if(NOT IsAllocatedMemory((ULONG)memoryBlock,memSize))
  720.             {
  721.                 if(IsActive)
  722.                 {
  723.                     VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) not in allocated memory\n",poolHeader,memoryBlock,memSize);
  724.                     hit = TRUE;
  725.                 }
  726.     
  727.                 freeIt = FALSE;
  728.             }
  729.  
  730.             ph = FindPoolHeader(poolHeader);
  731.             if(ph != NULL)
  732.             {
  733.                 if(CheckConsistency && NOT IsPuddleListConsistent(ph))
  734.                 {
  735.                     freeIt = FALSE;
  736.                 }
  737.  
  738.                 if(freeIt)
  739.                 {
  740.                     struct TrackHeader * th;
  741.     
  742.                     HoldPoolSemaphore(ph,stackFrame[16]);
  743.     
  744.                     if(NOT PuddleIsInPool(ph,memoryBlock))
  745.                     {
  746.                         if(IsActive)
  747.                         {
  748.                             VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) not in pool\n",poolHeader,memoryBlock,memSize);
  749.                             DumpPoolOwner(ph);
  750.     
  751.                             hit = TRUE;
  752.                         }
  753.             
  754.                         freeIt = FALSE;
  755.                     }
  756.     
  757.                     if(IsTrackedAllocation((ULONG)memoryBlock,&th))
  758.                     {
  759.                         if(CheckStomping(stackFrame,th))
  760.                         {
  761.                             freeIt = FALSE;
  762.     
  763.                             if(IsActive)
  764.                             {
  765.                                 hit = TRUE;
  766.                             }
  767.                         }
  768.             
  769.                         if(memSize != th->th_Size)
  770.                         {
  771.                             if(IsActive)
  772.                             {
  773.                                 VoiceComplaint(stackFrame,th,"Free size %ld does not match allocation size %ld\n",memSize,th->th_Size);
  774.                                 hit = TRUE;
  775.                             }
  776.         
  777.                             freeIt = FALSE;
  778.                         }
  779.         
  780.                         if(th->th_PoolHeader->ph_PoolHeader != poolHeader)
  781.                         {
  782.                             if(IsActive)
  783.                             {
  784.                                 struct PoolHeader * ph;
  785.     
  786.                                 VoiceComplaint(stackFrame,th,"FreePooled(0x%08lx,0x%08lx,%ld) called on puddle in wrong pool (right=0x%08lx wrong=0x%08lx)\n",poolHeader,memoryBlock,memSize,th->th_PoolHeader->ph_PoolHeader,poolHeader);
  787.                                 hit = TRUE;
  788.     
  789.                                 DumpPoolOwner(th->th_PoolHeader);
  790.     
  791.                                 ph = FindPoolHeader(poolHeader);
  792.                                 if(ph != NULL)
  793.                                     DumpPoolOwner(ph);
  794.                             }
  795.         
  796.                             freeIt = FALSE;
  797.                         }
  798.         
  799.                         if(th->th_Type != ALLOCATIONTYPE_AllocPooled)
  800.                         {
  801.                             if(IsActive)
  802.                             {
  803.                                 VoiceComplaint(stackFrame,th,"In FreePooled(0x%08lx,0x%08lx,%ld): Memory was not allocated with AllocPooled()\n",poolHeader,memoryBlock,memSize);
  804.                                 hit = TRUE;
  805.                             }
  806.         
  807.                             freeIt = FALSE;
  808.                         }
  809.         
  810.                         if(freeIt)
  811.                         {
  812.                             PerformDeallocation(th);
  813.                         }
  814.                         else
  815.                         {
  816.                             /* Let it go, but don't deallocate it. */
  817.                             th->th_Magic = 0;
  818.                             FixTrackHeaderChecksum(th);
  819.                         }
  820.                     }
  821.                     else
  822.                     {
  823.                         if(IsActive)
  824.                         {
  825.                             VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) called on puddle that is not in pool\n",poolHeader,memoryBlock,memSize);
  826.                             hit = TRUE;
  827.                         }
  828.                     }
  829.     
  830.                     ReleasePoolSemaphore(ph);
  831.                 }
  832.             }
  833.             else
  834.             {
  835.                 if(freeIt)
  836.                 {
  837.                     (*OldFreePooled)(poolHeader,memoryBlock,memSize,SysBase);
  838.                 }
  839.             }
  840.         }
  841.         else
  842.         {
  843.             if(IsActive)
  844.             {
  845.                 VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) called\n",poolHeader,memoryBlock,memSize);
  846.                 hit = TRUE;
  847.             }
  848.         }
  849.     }
  850.     else
  851.     {
  852.         if(IsActive)
  853.         {
  854.             VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) called from interrupt/exception\n",poolHeader,memoryBlock,memSize);
  855.         }
  856.     }
  857.  
  858.     if(hit && WaitAfterHit)
  859.     {
  860.         WaitForBreak();
  861.     }
  862. }
  863.