home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -seriously_amiga- / programming / other / wipeout / source / monitoring.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-27  |  16.2 KB  |  822 lines

  1. /*
  2.  * $Id: monitoring.c 1.3 1998/04/13 09:59:42 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(IsActive && CanAllocate())
  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.             /* memory may be deallocated only from an even address */
  199.             if(IsOddAddress((ULONG)memoryBlock))
  200.             {
  201.                 if(IsActive)
  202.                 {
  203.                     VoiceComplaint(stackFrame,NULL,"FreeMem(0x%08lx,%ld) on odd address\n",memoryBlock,byteSize);
  204.                     hit = TRUE;
  205.                 }
  206.     
  207.                 freeIt = FALSE;
  208.             }
  209.  
  210.             /* check if the address points into RAM */
  211.             if(IsInvalidAddress((ULONG)memoryBlock))
  212.             {
  213.                 if(IsActive)
  214.                 {
  215.                     VoiceComplaint(stackFrame,NULL,"FreeMem(0x%08lx,%ld) on illegal address\n",memoryBlock,byteSize);
  216.                     hit = TRUE;
  217.                 }
  218.     
  219.                 freeIt = FALSE;
  220.             }
  221.  
  222.             /* check if the memory to free is really allocated */
  223.             if(NOT IsAllocatedMemory((ULONG)memoryBlock,byteSize))
  224.             {
  225.                 if(IsActive)
  226.                 {
  227.                     VoiceComplaint(stackFrame,NULL,"FreeMem(0x%08lx,%ld) not in allocated memory\n",memoryBlock,byteSize);
  228.                     hit = TRUE;
  229.                 }
  230.     
  231.                 freeIt = FALSE;
  232.             }
  233.  
  234.             /* now test whether the allocation was tracked by us */
  235.             if(IsTrackedAllocation((ULONG)memoryBlock,&th))
  236.             {
  237.                 /* check whether the allocation walls were trashed */
  238.                 if(CheckStomping(stackFrame,th))
  239.                 {
  240.                     freeIt = FALSE;
  241.  
  242.                     if(IsActive)
  243.                     {
  244.                         hit = TRUE;
  245.                     }
  246.                 }
  247.     
  248.                 if(byteSize != th->th_Size)
  249.                 {
  250.                     if(IsActive)
  251.                     {
  252.                         VoiceComplaint(stackFrame,th,"Free size %ld does not match allocation size %ld\n",byteSize,th->th_Size);
  253.                         hit = TRUE;
  254.                     }
  255.     
  256.                     freeIt = FALSE;
  257.                 }
  258.     
  259.                 if(th->th_Type != ALLOCATIONTYPE_AllocMem)
  260.                 {
  261.                     if(IsActive)
  262.                     {
  263.                         VoiceComplaint(stackFrame,th,"In FreeMem(0x%08lx,%ld): Memory was not allocated with AllocMem()\n",memoryBlock,byteSize);
  264.                         hit = TRUE;
  265.                     }
  266.     
  267.                     freeIt = FALSE;
  268.                 }
  269.     
  270.                 if(freeIt)
  271.                 {
  272.                     PerformDeallocation(th);
  273.                 }
  274.                 else
  275.                 {
  276.                     /* Let it go, but don't deallocate it. */
  277.                     th->th_Magic = 0;
  278.                 }
  279.             }
  280.             else
  281.             {
  282.                 if(freeIt)
  283.                 {
  284.                     (*OldFreeMem)(memoryBlock,byteSize,SysBase);
  285.                 }
  286.             }
  287.         }
  288.     }
  289.     else
  290.     {
  291.         if(IsActive)
  292.         {
  293.             VoiceComplaint(stackFrame,NULL,"FreeMem(0x%08lx,%ld) called from interrupt/exception\n",memoryBlock,byteSize);
  294.         }
  295.     }
  296.  
  297.     if(hit && WaitAfterHit)
  298.     {
  299.         WaitForBreak();
  300.     }
  301. }
  302.  
  303. /******************************************************************************/
  304.  
  305. APTR ASM
  306. NewAllocVec(
  307.     REG(d0)    ULONG    byteSize,
  308.     REG(d1) ULONG    attributes,
  309.     REG(a2) ULONG *    stackFrame)
  310. {
  311.     APTR result = NULL;
  312.     BOOL hit = FALSE;
  313.  
  314.     if(NOT CalledFromSupervisorMode())
  315.     {
  316.         if(IsActive && CanAllocate())
  317.         {
  318.             if(byteSize == 0)
  319.             {
  320.                 VoiceComplaint(stackFrame,NULL,"AllocVec(%ld,0x%08lx) called\n",byteSize,attributes);
  321.                 hit = TRUE;
  322.             }
  323.             else
  324.             {
  325.                 if(CANNOT PerformAllocation(stackFrame[16],NULL,byteSize,attributes,ALLOCATIONTYPE_AllocVec,&result))
  326.                 {
  327.                     if(ShowFail)
  328.                     {
  329.                         VoiceComplaint(stackFrame,NULL,"AllocVec(%ld,0x%08lx) failed\n",byteSize,attributes);
  330.                         hit = TRUE;
  331.                     }
  332.                 }
  333.             }
  334.         }
  335.         else
  336.         {
  337.             result = (*OldAllocVec)(byteSize,attributes,SysBase);
  338.         }
  339.     }
  340.     else
  341.     {
  342.         if(IsActive)
  343.         {
  344.             VoiceComplaint(stackFrame,NULL,"AllocVec(%ld,0x%08lx) called from interrupt/exception\n",byteSize,attributes);
  345.         }
  346.     }
  347.  
  348.     if(hit && WaitAfterHit)
  349.     {
  350.         WaitForBreak();
  351.     }
  352.  
  353.     return(result);
  354. }
  355.  
  356. VOID ASM
  357. NewFreeVec(
  358.     REG(a1)    APTR    memoryBlock,
  359.     REG(a2) ULONG *    stackFrame)
  360. {
  361.     BOOL hit = FALSE;
  362.  
  363.     if(NOT CalledFromSupervisorMode())
  364.     {
  365.         if(memoryBlock != NULL)
  366.         {
  367.             struct TrackHeader * th;
  368.             BOOL freeIt = TRUE;
  369.     
  370.             if(IsOddAddress((ULONG)memoryBlock))
  371.             {
  372.                 if(IsActive)
  373.                 {
  374.                     VoiceComplaint(stackFrame,NULL,"FreeVec(0x%08lx) on odd address\n",memoryBlock);
  375.                     hit = TRUE;
  376.                 }
  377.     
  378.                 freeIt = FALSE;
  379.             }
  380.     
  381.             if(IsInvalidAddress((ULONG)memoryBlock))
  382.             {
  383.                 if(IsActive)
  384.                 {
  385.                     VoiceComplaint(stackFrame,NULL,"FreeVec(0x%08lx) on illegal address\n",memoryBlock);
  386.                     hit = TRUE;
  387.                 }
  388.     
  389.                 freeIt = FALSE;
  390.             }
  391.  
  392.             /* note that in order to check the size and the place of the
  393.              * allocation, the address must be valid
  394.              */
  395.             if(freeIt && NOT IsAllocatedMemory(((ULONG)memoryBlock)-4,(*(ULONG *)(((ULONG)memoryBlock)-4))))
  396.             {
  397.                 if(IsActive)
  398.                 {
  399.                     VoiceComplaint(stackFrame,NULL,"FreeVec(0x%08lx) not in allocated memory\n",memoryBlock);
  400.                     hit = TRUE;
  401.                 }
  402.     
  403.                 freeIt = FALSE;
  404.             }
  405.  
  406.             if(IsTrackedAllocation(((ULONG)memoryBlock) - sizeof(ULONG),&th))
  407.             {
  408.                 if(CheckStomping(stackFrame,th))
  409.                 {
  410.                     freeIt = FALSE;
  411.  
  412.                     if(IsActive)
  413.                     {
  414.                         hit = TRUE;
  415.                     }
  416.                 }
  417.     
  418.                 if(th->th_Type != ALLOCATIONTYPE_AllocVec)
  419.                 {
  420.                     if(IsActive)
  421.                     {
  422.                         VoiceComplaint(stackFrame,th,"In FreeVec(0x%08lx): Memory was not allocated with AllocVec()\n",memoryBlock);
  423.                         hit = TRUE;
  424.                     }
  425.     
  426.                     freeIt = FALSE;
  427.                 }
  428.     
  429.                 if(freeIt)
  430.                 {
  431.                     PerformDeallocation(th);
  432.                 }
  433.                 else
  434.                 {
  435.                     /* Let it go, but don't deallocate it. */
  436.                     th->th_Magic = 0;
  437.                 }
  438.             }
  439.             else
  440.             {
  441.                 if(freeIt)
  442.                 {
  443.                     (*OldFreeVec)(memoryBlock,SysBase);
  444.                 }
  445.             }
  446.         }
  447.     }
  448.     else
  449.     {
  450.         if(IsActive)
  451.         {
  452.             VoiceComplaint(stackFrame,NULL,"FreeVec(0x%08lx) called from interrupt/exception\n",memoryBlock);
  453.         }
  454.     }
  455.  
  456.     if(hit && WaitAfterHit)
  457.     {
  458.         WaitForBreak();
  459.     }
  460. }
  461.  
  462. /******************************************************************************/
  463.  
  464. APTR ASM
  465. NewCreatePool(
  466.     REG(d0)    ULONG    memFlags,
  467.     REG(d1) ULONG    puddleSize,
  468.     REG(d2) ULONG    threshSize,
  469.     REG(a2) ULONG *    stackFrame)
  470. {
  471.     APTR result = NULL;
  472.     BOOL hit = FALSE;
  473.  
  474.     if(NOT CalledFromSupervisorMode())
  475.     {
  476.         if(IsActive && CanAllocate())
  477.         {
  478.             /* the puddle threshold size must not be larger
  479.              * than the puddle size
  480.              */
  481.             if(threshSize <= puddleSize)
  482.             {
  483.                 struct PoolHeader * ph;
  484.         
  485.                 ph = CreatePoolHeader(memFlags,puddleSize,threshSize,stackFrame[16]);
  486.                 if(ph != NULL)
  487.                 {
  488.                     result = ph->ph_PoolHeader;
  489.                 }
  490.                 else
  491.                 {
  492.                     if(ShowFail)
  493.                     {
  494.                         VoiceComplaint(stackFrame,NULL,"CreatePool(0x%08lx,%ld,%ld) failed\n",memFlags,puddleSize,threshSize);
  495.                         hit = TRUE;
  496.                     }
  497.                 }
  498.             }
  499.             else
  500.             {
  501.                 VoiceComplaint(stackFrame,NULL,"Threshold size %ld must be <= puddle size %ld\n",threshSize,puddleSize);
  502.                 hit = TRUE;
  503.             }
  504.         }
  505.         else
  506.         {
  507.             result = (*OldCreatePool)(memFlags,puddleSize,threshSize,SysBase);
  508.         }
  509.     }
  510.     else
  511.     {
  512.         if(IsActive)
  513.         {
  514.             VoiceComplaint(stackFrame,NULL,"CreatePool(0x%08lx,%ld,%ld) called from interrupt/exception\n",memFlags,puddleSize,threshSize);
  515.         }
  516.     }
  517.  
  518.     if(hit && WaitAfterHit)
  519.     {
  520.         WaitForBreak();
  521.     }
  522.  
  523.     return(result);
  524. }
  525.  
  526. VOID ASM
  527. NewDeletePool(
  528.     REG(a0) APTR    poolHeader,
  529.     REG(a2) ULONG *    stackFrame)
  530. {
  531.     BOOL hit = FALSE;
  532.  
  533.     if(NOT CalledFromSupervisorMode())
  534.     {
  535.         if(poolHeader != NULL)
  536.         {
  537.             struct PoolHeader * ph;
  538.     
  539.             ph = FindPoolHeader(poolHeader);
  540.             if(ph != NULL)
  541.             {
  542.                 /* note that DeletePoolHeader() implies
  543.                  * HoldPoolSemaphore()..ReleasePoolSemaphore()
  544.                  */
  545.                 if(CANNOT DeletePoolHeader(stackFrame,ph))
  546.                 {
  547.                     if(IsActive)
  548.                     {
  549.                         hit = TRUE;
  550.                     }
  551.                 }
  552.             }
  553.             else
  554.             {
  555.                 (*OldDeletePool)(poolHeader,SysBase);
  556.             }
  557.         }
  558.         else
  559.         {
  560.             if(IsActive)
  561.             {
  562.                 VoiceComplaint(stackFrame,NULL,"DeletePool(NULL) called\n");
  563.                 hit = TRUE;
  564.             }
  565.         }
  566.     }
  567.     else
  568.     {
  569.         if(IsActive)
  570.         {
  571.             VoiceComplaint(stackFrame,NULL,"DeletePool(0x%08lx) called from interrupt/exception\n",poolHeader);
  572.         }
  573.     }
  574.  
  575.     if(hit && WaitAfterHit)
  576.     {
  577.         WaitForBreak();
  578.     }
  579. }
  580.  
  581. /******************************************************************************/
  582.  
  583. APTR ASM
  584. NewAllocPooled(
  585.     REG(a0) APTR    poolHeader,
  586.     REG(d0) ULONG    memSize,
  587.     REG(a2) ULONG *    stackFrame)
  588. {
  589.     APTR result = NULL;
  590.     BOOL hit = FALSE;
  591.  
  592.     if(NOT CalledFromSupervisorMode())
  593.     {
  594.         if(IsActive && CanAllocate())
  595.         {
  596.             if(poolHeader != NULL && memSize > 0)
  597.             {
  598.                 struct PoolHeader * ph;
  599.  
  600.                 /* check whether this memory pool is being tracked */
  601.                 ph = FindPoolHeader(poolHeader);
  602.                 if(ph != NULL)
  603.                 {
  604.                     HoldPoolSemaphore(ph,stackFrame[16]);
  605.  
  606.                     if(CANNOT PerformAllocation(stackFrame[16],ph,memSize,ph->ph_Attributes,ALLOCATIONTYPE_AllocPooled,&result))
  607.                     {
  608.                         if(ShowFail)
  609.                         {
  610.                             VoiceComplaint(stackFrame,NULL,"AllocPooled(0x%08lx,%ld) failed\n",poolHeader,memSize);
  611.                             hit = TRUE;
  612.                         }
  613.                     }
  614.  
  615.                     ReleasePoolSemaphore(ph);
  616.                 }
  617.                 else
  618.                 {
  619.                     result = (*OldAllocPooled)(poolHeader,memSize,SysBase);
  620.                 }
  621.             }
  622.             else
  623.             {
  624.                 VoiceComplaint(stackFrame,NULL,"AllocPooled(0x%08lx,%ld) called\n",poolHeader,memSize);
  625.                 hit = TRUE;
  626.             }
  627.         }
  628.         else
  629.         {
  630.             result = (*OldAllocPooled)(poolHeader,memSize,SysBase);
  631.         }
  632.     }
  633.     else
  634.     {
  635.         if(IsActive)
  636.         {
  637.             VoiceComplaint(stackFrame,NULL,"AllocPooled(0x%08lx,%ld) called from interrupt/exception\n",poolHeader,memSize);
  638.         }
  639.     }
  640.  
  641.     if(hit && WaitAfterHit)
  642.     {
  643.         WaitForBreak();
  644.     }
  645.  
  646.     return(result);
  647. }
  648.  
  649. VOID ASM
  650. NewFreePooled(
  651.     REG(a0)    APTR    poolHeader,
  652.     REG(a1)    APTR    memoryBlock,
  653.     REG(d0) ULONG    memSize,
  654.     REG(a2) ULONG *    stackFrame)
  655. {
  656.     BOOL hit = FALSE;
  657.  
  658.     if(NOT CalledFromSupervisorMode())
  659.     {
  660.         if(poolHeader != NULL && memoryBlock != NULL && memSize > 0)
  661.         {
  662.             struct PoolHeader * ph;
  663.             BOOL freeIt = TRUE;
  664.     
  665.             if(IsOddAddress((ULONG)memoryBlock))
  666.             {
  667.                 if(IsActive)
  668.                 {
  669.                     VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) on odd address\n",poolHeader,memoryBlock,memSize);
  670.                     hit = TRUE;
  671.                 }
  672.     
  673.                 freeIt = FALSE;
  674.             }
  675.     
  676.             if(IsInvalidAddress((ULONG)memoryBlock))
  677.             {
  678.                 if(IsActive)
  679.                 {
  680.                     VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) on illegal address\n",poolHeader,memoryBlock,memSize);
  681.                     hit = TRUE;
  682.                 }
  683.     
  684.                 freeIt = FALSE;
  685.             }
  686.     
  687.             if(NOT IsAllocatedMemory((ULONG)memoryBlock,memSize))
  688.             {
  689.                 if(IsActive)
  690.                 {
  691.                     VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) not in allocated memory\n",poolHeader,memoryBlock,memSize);
  692.                     hit = TRUE;
  693.                 }
  694.     
  695.                 freeIt = FALSE;
  696.             }
  697.  
  698.             ph = FindPoolHeader(poolHeader);
  699.             if(ph != NULL)
  700.             {
  701.                 struct TrackHeader * th;
  702.  
  703.                 HoldPoolSemaphore(ph,stackFrame[16]);
  704.  
  705.                 if(NOT PuddleIsInPool(ph,memoryBlock))
  706.                 {
  707.                     if(IsActive)
  708.                     {
  709.                         VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) not in pool\n",poolHeader,memoryBlock,memSize);
  710.                         DumpPoolOwner(ph);
  711.  
  712.                         hit = TRUE;
  713.                     }
  714.         
  715.                     freeIt = FALSE;
  716.                 }
  717.  
  718.                 if(IsTrackedAllocation((ULONG)memoryBlock,&th))
  719.                 {
  720.                     if(CheckStomping(stackFrame,th))
  721.                     {
  722.                         freeIt = FALSE;
  723.  
  724.                         if(IsActive)
  725.                         {
  726.                             hit = TRUE;
  727.                         }
  728.                     }
  729.         
  730.                     if(memSize != th->th_Size)
  731.                     {
  732.                         if(IsActive)
  733.                         {
  734.                             VoiceComplaint(stackFrame,th,"Free size %ld does not match allocation size %ld\n",memSize,th->th_Size);
  735.                             hit = TRUE;
  736.                         }
  737.     
  738.                         freeIt = FALSE;
  739.                     }
  740.     
  741.                     if(th->th_PoolHeader->ph_PoolHeader != poolHeader)
  742.                     {
  743.                         if(IsActive)
  744.                         {
  745.                             struct PoolHeader * ph;
  746.  
  747.                             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);
  748.                             hit = TRUE;
  749.  
  750.                             DumpPoolOwner(th->th_PoolHeader);
  751.  
  752.                             ph = FindPoolHeader(poolHeader);
  753.                             if(ph != NULL)
  754.                                 DumpPoolOwner(ph);
  755.                         }
  756.     
  757.                         freeIt = FALSE;
  758.                     }
  759.     
  760.                     if(th->th_Type != ALLOCATIONTYPE_AllocPooled)
  761.                     {
  762.                         if(IsActive)
  763.                         {
  764.                             VoiceComplaint(stackFrame,th,"In FreePooled(0x%08lx,0x%08lx,%ld): Memory was not allocated with AllocPooled()\n",poolHeader,memoryBlock,memSize);
  765.                             hit = TRUE;
  766.                         }
  767.     
  768.                         freeIt = FALSE;
  769.                     }
  770.     
  771.                     if(freeIt)
  772.                     {
  773.                         PerformDeallocation(th);
  774.                     }
  775.                     else
  776.                     {
  777.                         /* Let it go, but don't deallocate it. */
  778.                         th->th_Magic = 0;
  779.                     }
  780.                 }
  781.                 else
  782.                 {
  783.                     if(IsActive)
  784.                     {
  785.                         VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) called on puddle that is not in pool\n",poolHeader,memoryBlock,memSize);
  786.                         hit = TRUE;
  787.                     }
  788.                 }
  789.  
  790.                 ReleasePoolSemaphore(ph);
  791.             }
  792.             else
  793.             {
  794.                 if(freeIt)
  795.                 {
  796.                     (*OldFreePooled)(poolHeader,memoryBlock,memSize,SysBase);
  797.                 }
  798.             }
  799.         }
  800.         else
  801.         {
  802.             if(IsActive)
  803.             {
  804.                 VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) called\n",poolHeader,memoryBlock,memSize);
  805.                 hit = TRUE;
  806.             }
  807.         }
  808.     }
  809.     else
  810.     {
  811.         if(IsActive)
  812.         {
  813.             VoiceComplaint(stackFrame,NULL,"FreePooled(0x%08lx,0x%08lx,%ld) called from interrupt/exception\n",poolHeader,memoryBlock,memSize);
  814.         }
  815.     }
  816.  
  817.     if(hit && WaitAfterHit)
  818.     {
  819.         WaitForBreak();
  820.     }
  821. }
  822.