memprb.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:19k
源码类别:

Symbian

开发平台:

Visual C++

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