📄 memprb.cpp
字号:
{
#ifdef _DEBUG
HX_RESULT RetVal = HXR_OK;
if (m_bIsFrozen)
{
return HXR_UNEXPECTED;
}
EnterCriticalSection(&m_Mutex);
_CrtMemCheckpoint(&m_MemFreezePoint);
// Fixup Parent
if (m_pParent != NULL)
{
m_pParent->m_MaxMemUsedWithCrt = mem_max( m_pParent->m_MaxMemUsedWithCrt,
m_pParent->m_MemUsedWithCrt + m_MaxMemUsedWithCrt);
m_pParent->m_MemUsedWithCrt += m_MemUsedWithCrt;
m_pParent->m_MaxMemUsed = mem_max( m_pParent->m_MaxMemUsed,
m_pParent->m_MemUsed + m_MaxMemUsed);
m_pParent->m_MemUsed += m_MemUsed;
m_pParent->m_pChild = m_pChild;
}
if (m_pChild == NULL)
{
// Since there are no children, this must be the active probe
HX_ASSERT(mz_pActiveProbe == this);
mz_pActiveProbe = m_pParent;
}
else
{
// Collect Info from child and disown it
LONG32 uChildMax;
HX_ASSERT(!m_pChild->m_bIsFrozen);
uChildMax = (LONG32) m_pChild->GetMaxMemUsed(PNDBG_ALL_MEM, PNDBG_NOBASE_MEM);
m_MaxMemUsedWithCrt = mem_max( m_MaxMemUsedWithCrt,
m_MemUsedWithCrt + uChildMax);
uChildMax = m_pChild->GetMaxMemUsed(HXDBG_CLIENT_MEM, PNDBG_NOBASE_MEM);
m_MaxMemUsed = mem_max(m_MaxMemUsed,
m_MemUsed + uChildMax);
m_pChild->m_pParent = m_pParent;
}
m_pParent = NULL;
m_pChild = NULL;
if (SUCCEEDED(RetVal))
{
DestroyBlockInfo(m_MemFreeze);
if (bGenerateDetailInfo)
{
RetVal = MakeBlockInfo(m_MemFreeze, bWithCrt);
}
}
m_bIsFrozen = TRUE;
if (mz_pActiveProbe == NULL)
{
m_bMutexInitialized = FALSE;
DeleteCriticalSection(&m_Mutex);
}
else
{
LeaveCriticalSection(&m_Mutex);
}
return RetVal;
#else /* DEBUG */
return HXR_OK;
#endif /* _DEBUG */
}
const char* CHXMemProbe::SearchMemFrozen(ULONG32 uMemBlockId)
{
#ifdef _DEBUG
MemBlockInfo *pInfo;
for (pInfo = m_MemFreeze.pNext; pInfo != NULL; pInfo = pInfo->pNext)
{
if (pInfo->uId == uMemBlockId)
{
return pInfo->pDetail;
}
}
#endif /* _DEBUG */
return NULL;
}
HX_RESULT CHXMemProbe::GetFirstMemFrozen(ULONG32 &uMemBlockId, ULONG32 &uMemUsed)
{
#ifdef _DEBUG
m_pMemFreezeIter = m_MemFreeze.pNext;
if (m_pMemFreezeIter != NULL)
{
uMemBlockId = m_pMemFreezeIter->uId;
uMemUsed = m_pMemFreezeIter->uMemUsed;
return HXR_OK;
}
#endif /* _DEBUG */
return HXR_FAIL;
}
HX_RESULT CHXMemProbe::GetNextMemFrozen(ULONG32 &uMemBlockId, ULONG32 &uMemUsed)
{
#ifdef _DEBUG
if (m_pMemFreezeIter != NULL)
{
m_pMemFreezeIter = m_pMemFreezeIter->pNext;
}
if (m_pMemFreezeIter != NULL)
{
uMemBlockId = m_pMemFreezeIter->uId;
uMemUsed = m_pMemFreezeIter->uMemUsed;
return HXR_OK;
}
#endif /* _DEBUG */
return HXR_FAIL;
}
/****************************************************************************
* Private Methods
*/
#ifdef _DEBUG
HX_RESULT CHXMemProbe::MakeBlockInfo(MemBlockInfo &Info, BOOL bWithCrt)
{
FILE *pTempFile;
HX_RESULT RetVal = HXR_OK;
char Buffer[MAX_DUMPLINE_LENGTH]; /* Flawfinder: ignore */
char *pString;
ULONG32 uId;
ULONG32 uMemUsed;
// Create temporary file
pTempFile = tmpfile();
if (pTempFile == NULL)
{
RetVal = HXR_FAIL;
}
// Dump Current Heap State
if (SUCCEEDED(RetVal))
{
_DumpMemUsedSinceReset(pTempFile, bWithCrt);
if (fseek(pTempFile, 0, SEEK_SET) != 0)
{
RetVal = HXR_FAIL;
}
}
// Parse Dump
while (SUCCEEDED(RetVal) && (fgets(Buffer, sizeof(Buffer), pTempFile) != NULL))
{
if (strncmp(Buffer, DUMPDATA_START_STRING, strlen(DUMPDATA_START_STRING)) == 0)
{
// skip the data section
continue;
}
pString = strchr(Buffer, DUMPBLOCKID_START_CHAR);
if (pString != NULL)
{
pString++;
if (sscanf(pString, "%ld", &uId) != 1)
{
RetVal = HXR_PARSE_ERROR;
}
if (SUCCEEDED(RetVal))
{
pString = strchr(pString, DUMPMEMUSED_START_CHAR);
if (pString == NULL)
{
RetVal = HXR_PARSE_ERROR;
}
else
{
pString++;
if (sscanf(pString, "%ld", &uMemUsed) != 1)
{
RetVal = HXR_PARSE_ERROR;
}
}
}
if (SUCCEEDED(RetVal))
{
pString = strchr(pString, '\n');
if (pString != NULL)
{
*pString = '\0';
}
}
if (SUCCEEDED(RetVal))
{
RetVal = AddBlockInfo(Info, uId, uMemUsed, Buffer);
}
}
}
if (pTempFile != NULL)
{
fclose(pTempFile);
}
return RetVal;
}
HX_RESULT CHXMemProbe::AddBlockInfo(MemBlockInfo &Info, ULONG32 uId, ULONG32 uMemUsed, const char *pDetail)
{
MemBlockInfo *pNewInfo = NULL;
char *pNewDetail = NULL;
HX_RESULT RetVal = HXR_OK;
pNewInfo = (MemBlockInfo *) _malloc_dbg(sizeof(MemBlockInfo),
_CRT_BLOCK,
__FILE__,
__LINE__);
if (pNewInfo == NULL)
{
RetVal = HXR_OUTOFMEMORY;
}
if (SUCCEEDED(RetVal))
{
if (pDetail != NULL)
{
pNewDetail = (char *) _calloc_dbg( strlen(pDetail) + 1,
sizeof(char),
_CRT_BLOCK,
__FILE__,
__LINE__);
if (pNewDetail == NULL)
{
RetVal = HXR_OUTOFMEMORY;
}
else
{
strcpy(pNewDetail, pDetail); /* Flawfinder: ignore */
}
}
}
if (SUCCEEDED(RetVal))
{
pNewInfo->uId = uId;
pNewInfo->uMemUsed = uMemUsed;
pNewInfo->pDetail = pNewDetail;
pNewInfo->pNext = Info.pNext;
Info.pNext = pNewInfo;
}
else
{
if (pNewInfo != NULL)
{
free(pNewInfo);
}
if (pNewDetail != NULL)
{
free(pNewDetail);
}
}
return RetVal;
}
void CHXMemProbe::DestroyBlockInfo(MemBlockInfo &Info)
{
MemBlockInfo *pInfo;
MemBlockInfo *pDeadInfo;
m_pMemFreezeIter = NULL;
pInfo = Info.pNext;
while(pInfo != NULL)
{
pDeadInfo = pInfo;
pInfo = pInfo->pNext;
if (pDeadInfo->pDetail != NULL)
{
free(pDeadInfo->pDetail);
}
free(pDeadInfo);
}
Info = EmptyMemBlockInfo;
}
#if (defined(_MSC_VER) && (_MSC_VER > 1100) && defined(_BASETSD_H_)) /* VC 6 Check */
int __cdecl CHXMemProbe::MemProbeHook(int allocType, void *userData, size_t size, int blockType,
long requestNumber, const unsigned char *filename, int lineNumber)
#else
int __cdecl CHXMemProbe::MemProbeHook(int allocType, void *userData, size_t size, int blockType,
long requestNumber, const char *filename, int lineNumber)
#endif
{
if (mz_pActiveProbe != NULL)
{
if (allocType == _HOOK_REALLOC)
{
size_t old_size;
old_size = _msize_dbg(userData, blockType);
if (size > old_size)
{
size = size - old_size;
allocType = _HOOK_ALLOC;
}
else if (size < old_size)
{
size = old_size - size;
allocType = _HOOK_FREE;
}
}
else if (allocType == _HOOK_FREE)
{
size = _msize_dbg(userData, blockType);
}
switch(allocType)
{
case _HOOK_ALLOC:
mz_pActiveProbe->m_MemUsedWithCrt += size;
if (mz_pActiveProbe->m_MemUsedWithCrt > ((LONG32) mz_pActiveProbe->m_MaxMemUsedWithCrt))
{
mz_pActiveProbe->m_MaxMemUsedWithCrt = mz_pActiveProbe->m_MemUsedWithCrt;
}
if (blockType != _CRT_BLOCK)
{
mz_pActiveProbe->m_MemUsed += size;
if (mz_pActiveProbe->m_MemUsed > ((LONG32) mz_pActiveProbe->m_MaxMemUsed))
{
mz_pActiveProbe->m_MaxMemUsed = mz_pActiveProbe->m_MemUsed;
}
}
break;
case _HOOK_FREE:
mz_pActiveProbe->m_MemUsedWithCrt -= size;
if (blockType != _CRT_BLOCK)
{
mz_pActiveProbe->m_MemUsed -= size;
}
break;
case _HOOK_REALLOC:
// nothing to do: no size change
break;
default:
HX_ASSERT(FALSE);
break;
}
}
return TRUE;
}
#endif /* _DEBUG */
/****************************************************************************
* Helper Functions
*/
#ifdef _DEBUG
static LONG32 CalcUsedMem(_CrtMemState *MemState, BOOL bWithCrt)
{
LONG32 UsedMem = 0;
if (MemState != NULL)
{
int BlockType;
for (BlockType = 0; BlockType < _MAX_BLOCKS; BlockType++)
{
if ((BlockType != _FREE_BLOCK) && ((BlockType != _CRT_BLOCK) || bWithCrt))
{
UsedMem += MemState->lSizes[BlockType];
// printf("BlockType(%ld) Block(%ld) Size = %ld\n", BlockType, i, MemState->lSizes[BlockType]);
}
}
}
return UsedMem;
}
#endif /* _DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -