memprb.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:18k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /****************************************************************************
  36.  *  Defines
  37.  */
  38. #define MAX_DUMPLINE_LENGTH 1024
  39. #define DUMPBLOCKID_START_CHAR '{'
  40. #define DUMPMEMUSED_START_CHAR ','
  41. #define DUMPDATA_START_STRING " Data:"
  42. #define mem_max(x, y) ((x) > (y) ? (x) : (y))
  43. /****************************************************************************
  44.  *  Includes
  45.  */
  46. #ifdef _DEBUG
  47. #include <io.h>
  48. #include <stdio.h>
  49. #include <string.h>
  50. #include <malloc.h>
  51. #endif // _DEBUG
  52. #include "hxassert.h"
  53. #include "hxmemprb.h"
  54. /****************************************************************************
  55.  *  Locals
  56.  */
  57. #ifdef _DEBUG
  58. static LONG32 CalcUsedMem(_CrtMemState *MemState, BOOL bWithCrt);
  59. static const MemBlockInfo EmptyMemBlockInfo =
  60. {
  61.     0,
  62.     0,
  63.     NULL,
  64.     NULL
  65. };
  66. CHXMemProbe* CHXMemProbe::mz_pActiveProbe = NULL;
  67. BOOL CHXMemProbe::m_bMutexInitialized = FALSE;
  68. CRITICAL_SECTION CHXMemProbe::m_Mutex;
  69. #endif  /* _DEBUG */
  70. CHXMemProbe::CHXMemProbe(BOOL bIsFrozen)
  71. #ifdef _DEBUG
  72.     : m_bIsFrozen(TRUE),
  73. m_MemFreeze(EmptyMemBlockInfo),
  74. m_pMemFreezeIter(NULL),
  75. m_MemUsed(0),
  76. m_MemUsedWithCrt(0),
  77. m_MaxMemUsed(0),
  78. m_MaxMemUsedWithCrt(0),
  79. m_BaseMemUsed(0),
  80. m_BaseMemUsedWithCrt(0),
  81. m_pParent(NULL),
  82. m_pChild(NULL)
  83. #endif /* _DEBUG */
  84. {
  85. #ifdef _DEBUG
  86.     if (!m_bMutexInitialized)
  87.     {
  88. InitializeCriticalSection(&m_Mutex);
  89. m_bMutexInitialized = TRUE;
  90.     }
  91.     _CrtSetDbgFlag( _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) |
  92.     _CRTDBG_ALLOC_MEM_DF | 
  93.     _CRTDBG_CHECK_CRT_DF);
  94.     _CrtMemCheckpoint(&m_MemRefPoint);
  95.     m_MemFreezePoint = m_MemRefPoint;
  96.     if (!bIsFrozen)
  97.     {
  98. Reset();  // activate the probe
  99.     }
  100. #endif  /* _DEBUG */
  101. }
  102. CHXMemProbe::~CHXMemProbe()
  103. {
  104. #ifdef _DEBUG
  105.     if (!m_bIsFrozen)
  106.     {
  107. Freeze();
  108.     }
  109.     DestroyBlockInfo(m_MemFreeze);
  110. #endif  /* _DEBUG */
  111. }
  112. BOOL CHXMemProbe::IsRestored(BOOL bWithCrt)
  113. {
  114. #ifdef _DEBUG
  115.     BOOL bSignificantDiff;
  116.     _CrtMemState MemRefPointDiff;
  117.     if (!m_bIsFrozen)
  118.     {
  119. _CrtMemCheckpoint(&m_MemFreezePoint);
  120.     }
  121.     bSignificantDiff = _CrtMemDifference(&MemRefPointDiff, &m_MemRefPoint, &m_MemFreezePoint);
  122.     if (bWithCrt)
  123.     {
  124. return !bSignificantDiff;
  125.     }
  126.     return ((CalcUsedMem(&MemRefPointDiff, HXDBG_CLIENT_MEM) == 0) ? TRUE : FALSE);
  127. #else  /* _DEBUG */
  128.     return TRUE;
  129. #endif  /* _DEBUG */
  130. }
  131. LONG32 CHXMemProbe::GetMemUsed(BOOL bWithCrt, BOOL bWithBase, CHXMemProbe *pReferenceProbe)
  132. {
  133. #ifdef _DEBUG
  134.     LONG32 BaseMem;
  135.     _CrtMemState MemRefPointDiff;
  136.     
  137.     if (bWithBase)
  138.     {
  139. BaseMem = bWithCrt ? m_BaseMemUsedWithCrt : m_BaseMemUsed;
  140. if (pReferenceProbe != NULL)
  141. {
  142.     BaseMem -= (bWithCrt ? pReferenceProbe->m_BaseMemUsedWithCrt : pReferenceProbe->m_BaseMemUsed);
  143. }
  144.     }
  145.     else
  146.     {
  147. BaseMem = 0;
  148.     }
  149.     if (!m_bIsFrozen)
  150.     {
  151. _CrtMemCheckpoint(&m_MemFreezePoint);
  152.     }
  153.     (void) _CrtMemDifference(&MemRefPointDiff, &m_MemRefPoint, &m_MemFreezePoint);
  154.     return (BaseMem + CalcUsedMem(&MemRefPointDiff, bWithCrt));
  155. #else  /* DEBUG */
  156.     return 0;
  157. #endif  /* _DEBUG */
  158. }
  159. LONG32 CHXMemProbe::GetBaseMemUsed(BOOL bWithCrt)
  160. {
  161. #ifdef _DEBUG
  162.     return bWithCrt ? m_BaseMemUsedWithCrt : m_BaseMemUsed;
  163. #else  /* _DEBUG */
  164.     return 0;
  165. #endif  /* _DEBUG */
  166. }
  167. HX_RESULT CHXMemProbe::DumpMemUsedSinceReset(FILE *pFile, BOOL bWithCrt)
  168. {
  169. #ifdef _DEBUG
  170.     FILE *pTempFile;
  171.     char Buffer[MAX_DUMPLINE_LENGTH]; /* Flawfinder: ignore */
  172.     HX_RESULT RetVal = HXR_OK;
  173.     pTempFile = tmpfile();
  174.     if (pTempFile == NULL)
  175.     {
  176. RetVal = HXR_FAIL;
  177.     }
  178.     if (SUCCEEDED(RetVal))
  179.     {
  180. _DumpMemUsedSinceReset(pTempFile, bWithCrt);
  181. if (fseek(pTempFile, 0, SEEK_SET) != 0)
  182. {
  183.     RetVal = HXR_FAIL;
  184. }
  185.     }
  186.     while (SUCCEEDED(RetVal) && (fgets(Buffer, sizeof(Buffer), pTempFile) != NULL))
  187.     {
  188. if (fputs(Buffer, pFile) == EOF)
  189. {
  190.     RetVal = HXR_FAIL;
  191. }
  192.     }
  193.     if (pTempFile != NULL)
  194.     {
  195. fclose(pTempFile);
  196.     }
  197.     return RetVal;
  198. #endif  /* _DEBUG */
  199.     return HXR_OK;
  200. }
  201. #ifdef _DEBUG
  202. void CHXMemProbe::_DumpMemUsedSinceReset(FILE *pFile, BOOL bWithCrt)
  203. {
  204.     int OldFlag;
  205.     int NewFlag;
  206.     _HFILE hOldFile;
  207.     _HFILE hNewFile;
  208.     int OldMode;
  209.     // Set Debug Flag
  210.     OldFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  211.     if (bWithCrt)
  212.     {
  213. NewFlag = OldFlag | _CRTDBG_CHECK_CRT_DF;
  214.     }
  215.     else
  216.     {
  217. NewFlag = OldFlag & (~_CRTDBG_CHECK_CRT_DF);
  218.     }
  219.     (void) _CrtSetDbgFlag(NewFlag);
  220.     // Set Output File
  221.     if (pFile == NULL)
  222.     {
  223. pFile = (FILE *) stdout;
  224.     }
  225.     hNewFile = (_HFILE) _get_osfhandle(_fileno(pFile));
  226.     OldMode = _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
  227.     hOldFile = _CrtSetReportFile(_CRT_WARN, hNewFile);
  228.     // Dump
  229.     _CrtMemDumpAllObjectsSince(&m_MemRefPoint);
  230.     
  231.     // Restore Debug Mode
  232.     (void) _CrtSetDbgFlag(OldFlag);
  233.     (void) _CrtSetReportMode(_CRT_WARN, OldMode);
  234.     (void) _CrtSetReportFile(_CRT_WARN, hOldFile);
  235. }
  236. #endif  /* _DEBUG */
  237. ULONG32 CHXMemProbe::GetMaxMemUsed(BOOL bWithCrt, BOOL bWithBase, CHXMemProbe *pReferenceProbe)
  238. {
  239. #ifdef _DEBUG
  240.     LONG32 BaseMem;
  241.     LONG32 MaxMem;
  242.     if (bWithBase)
  243.     {
  244. BaseMem = bWithCrt ? m_BaseMemUsedWithCrt : m_BaseMemUsed;
  245. if (pReferenceProbe != NULL)
  246. {
  247.     BaseMem -= (bWithCrt ? pReferenceProbe->m_BaseMemUsedWithCrt : pReferenceProbe->m_BaseMemUsed);
  248. }
  249.     }
  250.     else
  251.     {
  252. BaseMem = 0;
  253.     }
  254.     if (m_pChild == NULL)
  255.     {
  256. MaxMem = bWithCrt ? m_MaxMemUsedWithCrt : m_MaxMemUsed;
  257.     }
  258.     else
  259.     {
  260. LONG32 uChildMax;
  261. uChildMax = (LONG32) m_pChild->GetMaxMemUsed(bWithCrt, PNDBG_NOBASE_MEM);
  262. if (bWithCrt)
  263. {
  264.     MaxMem = mem_max(uChildMax + m_MemUsedWithCrt, m_MaxMemUsedWithCrt);
  265. }
  266. else
  267. {
  268.     MaxMem = mem_max(uChildMax + m_MemUsed, m_MaxMemUsed);
  269. }
  270.     }
  271.     return mem_max(BaseMem + MaxMem, 0);
  272. #else  /* DEBUG */
  273.     return 0;
  274. #endif  /* _DEBUG */
  275. }
  276. LONG32 CHXMemProbe::GetGlobalMemUsed(BOOL bWithCrt)
  277. {
  278. #ifdef _DEBUG
  279.     _CrtMemState MemRefPoint;
  280.     _CrtMemCheckpoint(&MemRefPoint);
  281.     return CalcUsedMem(&MemRefPoint, bWithCrt);
  282. #else  /* _DEBUG */
  283.     return 0;
  284. #endif  /* _DEBUG */
  285. }
  286. ULONG32 CHXMemProbe::GetGlobalMaxMemUsed(void)
  287. {
  288. #ifdef _DEBUG
  289.     _CrtMemState MemRefPoint;
  290.     _CrtMemCheckpoint(&MemRefPoint);
  291.     return (ULONG32) MemRefPoint.lHighWaterCount;
  292. #else  /* _DEBUG */
  293.     return 0;
  294. #endif  /* _DEBUG */
  295. }
  296. ULONG32 CHXMemProbe::SetGlobalMemBreak(ULONG32 uMemBlockId)
  297. {
  298. #ifdef _DEBUG
  299.     return _CrtSetBreakAlloc(uMemBlockId);
  300. #else  /* _DEBUG */
  301.     return 0;
  302. #endif  /* _DEBUG */
  303. }
  304. HX_RESULT CHXMemProbe::Reset(void)
  305. {
  306. #ifdef _DEBUG
  307.     if (!m_bMutexInitialized)
  308.     {
  309. InitializeCriticalSection(&m_Mutex);
  310. m_bMutexInitialized = TRUE;
  311.     }
  312.     if (!m_bIsFrozen)
  313.     {
  314. Freeze();
  315.     }
  316.     EnterCriticalSection(&m_Mutex);
  317.     DestroyBlockInfo(m_MemFreeze);
  318.     _CrtMemCheckpoint(&m_MemRefPoint);
  319.     m_MemUsed = 0;
  320.     m_MemUsedWithCrt = 0;
  321.     m_MaxMemUsed = 0;
  322.     m_MaxMemUsedWithCrt = 0;
  323.     m_BaseMemUsed = 0;
  324.     m_BaseMemUsedWithCrt = 0;
  325.     m_pChild = NULL;
  326.     m_pParent = mz_pActiveProbe;
  327.     if (m_pParent != NULL)
  328.     {
  329. m_pParent->m_pChild = this;
  330. m_BaseMemUsedWithCrt = m_pParent->m_MemUsedWithCrt + m_pParent->m_BaseMemUsedWithCrt;
  331. m_BaseMemUsed = m_pParent->m_MemUsed + m_pParent->m_BaseMemUsed;
  332.     }
  333.     mz_pActiveProbe = this;
  334.     _CrtSetAllocHook(MemProbeHook);
  335.     m_bIsFrozen = FALSE;
  336.     
  337.     LeaveCriticalSection(&m_Mutex);
  338. #endif  /* _DEBUG */
  339.     return HXR_OK;
  340. }
  341. HX_RESULT CHXMemProbe::Freeze(BOOL bGenerateDetailInfo, BOOL bWithCrt)
  342. {
  343. #ifdef _DEBUG
  344.     HX_RESULT RetVal = HXR_OK;
  345.     if (m_bIsFrozen)
  346.     {
  347. return HXR_UNEXPECTED;
  348.     }
  349.     EnterCriticalSection(&m_Mutex);
  350.     _CrtMemCheckpoint(&m_MemFreezePoint);
  351.     // Fixup Parent
  352.     if (m_pParent != NULL)
  353.     {
  354. m_pParent->m_MaxMemUsedWithCrt = mem_max(  m_pParent->m_MaxMemUsedWithCrt, 
  355. m_pParent->m_MemUsedWithCrt + m_MaxMemUsedWithCrt);
  356. m_pParent->m_MemUsedWithCrt += m_MemUsedWithCrt;
  357. m_pParent->m_MaxMemUsed = mem_max( m_pParent->m_MaxMemUsed, 
  358.     m_pParent->m_MemUsed + m_MaxMemUsed);
  359. m_pParent->m_MemUsed += m_MemUsed;
  360. m_pParent->m_pChild = m_pChild;
  361.     }
  362.     if (m_pChild == NULL)
  363.     {
  364. // Since there are no children, this must be the active probe
  365. HX_ASSERT(mz_pActiveProbe == this);
  366. mz_pActiveProbe = m_pParent;
  367.     }
  368.     else
  369.     {
  370. // Collect Info from child and disown it
  371. LONG32 uChildMax;
  372. HX_ASSERT(!m_pChild->m_bIsFrozen);
  373. uChildMax = (LONG32) m_pChild->GetMaxMemUsed(PNDBG_ALL_MEM, PNDBG_NOBASE_MEM);
  374. m_MaxMemUsedWithCrt = mem_max( m_MaxMemUsedWithCrt,
  375. m_MemUsedWithCrt + uChildMax);
  376.     
  377. uChildMax = m_pChild->GetMaxMemUsed(HXDBG_CLIENT_MEM, PNDBG_NOBASE_MEM);
  378. m_MaxMemUsed = mem_max(m_MaxMemUsed,
  379. m_MemUsed + uChildMax);
  380. m_pChild->m_pParent = m_pParent;
  381.     }
  382.     m_pParent = NULL;
  383.     m_pChild = NULL;
  384.     if (SUCCEEDED(RetVal))
  385.     {
  386. DestroyBlockInfo(m_MemFreeze);
  387. if (bGenerateDetailInfo)
  388. {
  389.     RetVal = MakeBlockInfo(m_MemFreeze, bWithCrt);
  390. }
  391.     }
  392.     
  393.     m_bIsFrozen = TRUE;
  394.     
  395.     if (mz_pActiveProbe == NULL)
  396.     {
  397. m_bMutexInitialized = FALSE;
  398. DeleteCriticalSection(&m_Mutex);
  399.     }
  400.     else
  401.     {
  402. LeaveCriticalSection(&m_Mutex);
  403.     }
  404.     return RetVal;
  405. #else  /* DEBUG */
  406.     return HXR_OK;
  407. #endif  /* _DEBUG */
  408. }
  409. const char* CHXMemProbe::SearchMemFrozen(ULONG32 uMemBlockId)
  410. {
  411. #ifdef _DEBUG
  412.     MemBlockInfo *pInfo;
  413.     for (pInfo = m_MemFreeze.pNext; pInfo != NULL; pInfo = pInfo->pNext)
  414.     {
  415. if (pInfo->uId == uMemBlockId)
  416. {
  417.     return pInfo->pDetail;
  418. }
  419.     }
  420. #endif  /* _DEBUG */
  421.     return NULL;
  422. }
  423. HX_RESULT CHXMemProbe::GetFirstMemFrozen(ULONG32 &uMemBlockId, ULONG32 &uMemUsed)
  424. {
  425. #ifdef _DEBUG
  426.     m_pMemFreezeIter = m_MemFreeze.pNext;
  427.     if (m_pMemFreezeIter != NULL)
  428.     {
  429. uMemBlockId = m_pMemFreezeIter->uId;
  430. uMemUsed = m_pMemFreezeIter->uMemUsed;
  431. return HXR_OK;
  432.     }
  433. #endif  /* _DEBUG */
  434.     return HXR_FAIL;
  435. }
  436. HX_RESULT CHXMemProbe::GetNextMemFrozen(ULONG32 &uMemBlockId, ULONG32 &uMemUsed)
  437. {
  438. #ifdef _DEBUG
  439.     if (m_pMemFreezeIter != NULL)
  440.     {
  441. m_pMemFreezeIter = m_pMemFreezeIter->pNext;
  442.     }
  443.     if (m_pMemFreezeIter != NULL)
  444.     {
  445. uMemBlockId = m_pMemFreezeIter->uId;
  446. uMemUsed = m_pMemFreezeIter->uMemUsed;
  447. return HXR_OK;
  448.     }
  449. #endif  /* _DEBUG */
  450.     return HXR_FAIL;
  451. }
  452. /****************************************************************************
  453.  *  Private Methods
  454.  */
  455. #ifdef _DEBUG
  456. HX_RESULT CHXMemProbe::MakeBlockInfo(MemBlockInfo &Info, BOOL bWithCrt)
  457. {
  458.     FILE *pTempFile;
  459.     HX_RESULT RetVal = HXR_OK;
  460.     char Buffer[MAX_DUMPLINE_LENGTH]; /* Flawfinder: ignore */
  461.     char *pString;
  462.     ULONG32 uId;
  463.     ULONG32 uMemUsed;
  464.     // Create temporary file
  465.     pTempFile = tmpfile();
  466.     if (pTempFile == NULL)
  467.     {
  468. RetVal = HXR_FAIL;
  469.     }
  470.     // Dump Current Heap State
  471.     if (SUCCEEDED(RetVal))
  472.     {
  473. _DumpMemUsedSinceReset(pTempFile, bWithCrt);
  474. if (fseek(pTempFile, 0, SEEK_SET) != 0)
  475. {
  476.     RetVal = HXR_FAIL;
  477. }
  478.     }
  479.     // Parse Dump
  480.     while (SUCCEEDED(RetVal) && (fgets(Buffer, sizeof(Buffer), pTempFile) != NULL))
  481.     {
  482. if (strncmp(Buffer, DUMPDATA_START_STRING, strlen(DUMPDATA_START_STRING)) == 0)
  483. {
  484.     // skip the data section
  485.     continue;
  486. }
  487. pString = strchr(Buffer, DUMPBLOCKID_START_CHAR);
  488. if (pString != NULL)
  489. {
  490.     pString++;
  491.     if (sscanf(pString, "%ld", &uId) != 1)
  492.     {
  493. RetVal = HXR_PARSE_ERROR;
  494.     }
  495.     if (SUCCEEDED(RetVal))
  496.     {
  497. pString = strchr(pString, DUMPMEMUSED_START_CHAR);
  498. if (pString == NULL)
  499. {
  500.     RetVal = HXR_PARSE_ERROR;
  501. }
  502. else
  503. {
  504.     pString++;
  505.     if (sscanf(pString, "%ld", &uMemUsed) != 1)
  506.     {
  507. RetVal = HXR_PARSE_ERROR;
  508.     }
  509. }
  510.     }
  511.     if (SUCCEEDED(RetVal))
  512.     {
  513. pString = strchr(pString, 'n');
  514. if (pString != NULL)
  515. {
  516.     *pString = '';
  517. }
  518.     }
  519.     if (SUCCEEDED(RetVal))
  520.     {
  521. RetVal = AddBlockInfo(Info, uId, uMemUsed, Buffer);
  522.     }
  523. }
  524.     }
  525.     if (pTempFile != NULL)
  526.     {
  527. fclose(pTempFile);
  528.     }
  529.     return RetVal;
  530. }
  531. HX_RESULT CHXMemProbe::AddBlockInfo(MemBlockInfo &Info, ULONG32 uId, ULONG32 uMemUsed, const char *pDetail)
  532. {
  533.     MemBlockInfo *pNewInfo = NULL;
  534.     char *pNewDetail = NULL;
  535.     HX_RESULT RetVal = HXR_OK;
  536.     pNewInfo = (MemBlockInfo *) _malloc_dbg(sizeof(MemBlockInfo),
  537.     _CRT_BLOCK, 
  538.     __FILE__, 
  539.     __LINE__);
  540.     if (pNewInfo == NULL)
  541.     {
  542. RetVal = HXR_OUTOFMEMORY;
  543.     }
  544.     if (SUCCEEDED(RetVal))
  545.     {
  546. if (pDetail != NULL)
  547. {
  548.     pNewDetail = (char *) _calloc_dbg(  strlen(pDetail) + 1, 
  549. sizeof(char), 
  550. _CRT_BLOCK, 
  551. __FILE__, 
  552. __LINE__);
  553.     if (pNewDetail == NULL)
  554.     {
  555. RetVal = HXR_OUTOFMEMORY;
  556.     }
  557.     else
  558.     {
  559. strcpy(pNewDetail, pDetail); /* Flawfinder: ignore */
  560.     }
  561. }
  562.     }
  563.     if (SUCCEEDED(RetVal))
  564.     {
  565. pNewInfo->uId = uId;
  566. pNewInfo->uMemUsed = uMemUsed;
  567. pNewInfo->pDetail = pNewDetail;
  568. pNewInfo->pNext = Info.pNext;
  569. Info.pNext = pNewInfo;
  570.     }
  571.     else
  572.     {
  573. if (pNewInfo != NULL)
  574. {
  575.     free(pNewInfo);
  576. }
  577. if (pNewDetail != NULL)
  578. {
  579.     free(pNewDetail);
  580. }
  581.     }
  582.     return RetVal;
  583. }
  584. void CHXMemProbe::DestroyBlockInfo(MemBlockInfo &Info)
  585. {
  586.     MemBlockInfo *pInfo;
  587.     MemBlockInfo *pDeadInfo;
  588.     m_pMemFreezeIter = NULL;
  589.     pInfo = Info.pNext;
  590.     
  591.     while(pInfo != NULL)
  592.     {
  593. pDeadInfo = pInfo;
  594. pInfo = pInfo->pNext;
  595. if (pDeadInfo->pDetail != NULL)
  596. {
  597.     free(pDeadInfo->pDetail);
  598. }
  599. free(pDeadInfo);
  600.     }
  601.     Info = EmptyMemBlockInfo;
  602. }
  603. #if (defined(_MSC_VER) && (_MSC_VER > 1100) && defined(_BASETSD_H_)) /* VC 6 Check */
  604. int __cdecl CHXMemProbe::MemProbeHook(int allocType, void *userData, size_t size, int blockType,
  605.      long requestNumber, const unsigned char *filename, int lineNumber)
  606. #else
  607. int __cdecl CHXMemProbe::MemProbeHook(int allocType, void *userData, size_t size, int blockType,
  608.      long requestNumber, const char *filename, int lineNumber)
  609. #endif
  610. {
  611.     if (mz_pActiveProbe != NULL)
  612.     {
  613. if (allocType == _HOOK_REALLOC)
  614. {
  615.     size_t old_size;
  616.     old_size = _msize_dbg(userData, blockType);
  617.     if (size > old_size)
  618.     {
  619. size = size - old_size;
  620. allocType = _HOOK_ALLOC;
  621.     }
  622.     else if (size < old_size)
  623.     {
  624. size = old_size - size;
  625. allocType = _HOOK_FREE;
  626.     }
  627. }
  628. else if (allocType == _HOOK_FREE)
  629. {
  630.     size = _msize_dbg(userData, blockType);
  631. }
  632. switch(allocType)
  633. {
  634. case _HOOK_ALLOC:
  635.     mz_pActiveProbe->m_MemUsedWithCrt += size;
  636.     if (mz_pActiveProbe->m_MemUsedWithCrt > ((LONG32) mz_pActiveProbe->m_MaxMemUsedWithCrt))
  637.     {
  638. mz_pActiveProbe->m_MaxMemUsedWithCrt = mz_pActiveProbe->m_MemUsedWithCrt;
  639.     }
  640.     if (blockType != _CRT_BLOCK)
  641.     {
  642. mz_pActiveProbe->m_MemUsed += size;
  643. if (mz_pActiveProbe->m_MemUsed > ((LONG32) mz_pActiveProbe->m_MaxMemUsed))
  644. {
  645.     mz_pActiveProbe->m_MaxMemUsed = mz_pActiveProbe->m_MemUsed;
  646. }
  647.     }
  648.     break;
  649. case _HOOK_FREE:
  650.     mz_pActiveProbe->m_MemUsedWithCrt -= size;
  651.     if (blockType != _CRT_BLOCK)
  652.     {
  653. mz_pActiveProbe->m_MemUsed -= size;
  654.     }
  655.     break;
  656. case _HOOK_REALLOC:
  657.     // nothing to do: no size change
  658.     break;
  659. default:
  660.     HX_ASSERT(FALSE);
  661.     break;
  662. }
  663.     }
  664.     return TRUE;
  665. }
  666. #endif  /* _DEBUG */
  667. /****************************************************************************
  668.  *  Helper Functions
  669.  */
  670. #ifdef _DEBUG
  671. static LONG32 CalcUsedMem(_CrtMemState *MemState, BOOL bWithCrt)
  672. {
  673.     LONG32 UsedMem = 0;
  674.     if (MemState != NULL)
  675.     {
  676. int BlockType;
  677. for (BlockType = 0; BlockType < _MAX_BLOCKS; BlockType++)
  678. {
  679.     if ((BlockType != _FREE_BLOCK) && ((BlockType != _CRT_BLOCK) || bWithCrt))
  680.     {
  681. UsedMem += MemState->lSizes[BlockType];
  682. // printf("BlockType(%ld) Block(%ld) Size = %ldn", BlockType, i, MemState->lSizes[BlockType]);
  683.     }
  684. }
  685.     }
  686.     return UsedMem;
  687. }
  688. #endif  /* _DEBUG */