📄 memchk.cpp
字号:
/***************************************************************************
* Name : memchk.c
* Title : MBX WinCE driver
* Author(s) : Imagination Technologies
* Created : 6th January 2003
*
* Copyright : 2003 by Imagination Technologies. All rights reserved.
* : No part of this software, either material or conceptual
* : may be copied or distributed, transmitted, transcribed,
* : stored in a retrieval system or translated into any
* : human or computer language in any form by any means,
* : electronic, mechanical, manual or other-wise, or
* : disclosed to third parties without the express written
* : permission of Imagination Technologies Limited, Unit 8,
* : HomePark Industrial Estate, King's Langley, Hertfordshire,
* : WD4 8LZ, U.K.
*
* Description : MBX WinCE driver
*
* Platform : WinCE
*
* Modifications:-
* $Log: memchk.cpp $
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
*
****************************************************************************/
#include "precomp.h"
#include "pvr_debug.h"
// Put this here for now until we sort out the registry stuff.
BOOL ReadRegistryDword (LPCWSTR SubKey, DWORD* pdwResult);
#define MEMCHK_LEV_ALL_GUARD 1
#define MEMCHK_GUARD_PAGE 0
#define MEMCHK_GUARD_BUF 1
#define FRONT_RGN_SIZE 32
#define BACK_RGN_SIZE 32
#define FRONT_RGN_VAL 0xF2
#define BACK_RGN_VAL 0xB2
#define ALLOC_MEM_VAL 0xE2
#define FREE_MEM_VAL 0xD2
typedef struct
{
ULONG ulCurrentAllocs;
ULONG ulAllocCount;
ULONG ulFreeCount;
ULONG ulCurrentAllocSize;
}ALLOC_STATS, *PALLOC_STATS;
typedef struct
{
ULONG ulSize;
PVOID pvBufStart;
PVOID pvUserBuf;
ULONG ulCallersEIP;
ULONG ulRgnSize;
}ALLOC_INFO, *PALLOC_INFO;
#define ALLOC_PER_TABLE 2
typedef struct _ALLOC_LIST_
{
struct _ALLOC_LIST_ *psNext;
ALLOC_INFO asAllocs[ALLOC_PER_TABLE];
}ALLOC_LIST, *PALLOC_LIST;
typedef struct
{
HANDLE hHeap;
ULONG ulCreatorEIP;
ALLOC_STATS sStats;
PALLOC_LIST psAllocList;
ULONG ulMaxSize;
ULONG ulInitSize;
ULONG ulHpCreateFlags;
}HEAP_INFO, *PHEAP_INFO;
typedef struct
{
BOOL bFindUnderRuns;
ULONG ulFrontGuradPages;
ULONG ulBackGuradPages;
}MEMCHK_GURADPAGE_CONFIG;
#define MAX_HEAPS 4
typedef struct
{
PVOID (*pfnHeapAlloc)(HANDLE hHeap, ULONG ulFlags, ULONG ulBytes);
BOOL (*pfnHeapFree) (HANDLE hHeap, ULONG ulFlags, PVOID pvMem);
PBYTE (*pfnIsAllocCorrupt)(PALLOC_INFO psAlloc);
}MEMCHK_FNS, *PMEMCHK_FNS;
typedef struct
{
BOOL bInit;
ULONG ulCheckLevel;
ULONG ulMemChkType;
MEMCHK_GURADPAGE_CONFIG sGuradPageConfig;
ALLOC_STATS sGlbStats;
HEAP_INFO sHeaps[MAX_HEAPS];
PMEMCHK_FNS psfnRoutines;
}HEAPS, *PHEAPS;
#define GET_CALLER_ADDR 0
PALLOC_INFO FindAlloc(PHEAP_INFO psHeap, PVOID pvBufStart);
PBYTE IsMemRgnCorrupt(PVOID pvBuf, ULONG ulSize, BYTE byCorrectValue);
void CheckHeap(PHEAP_INFO psHeap, BOOL bPrintInfo);
void PrintStats(PALLOC_STATS psStats);
void MemChkCheckAllHeaps(BOOL bPrintInfo);
BOOL GuardBufFree (HANDLE hHeap, ULONG ulFlags, PVOID pvMem);
PVOID GuardBufAlloc(HANDLE hHeap, ULONG ulFlags, ULONG ulBytes);
PBYTE GuardBufIsAllocCorrupt(PALLOC_INFO psAlloc);
BOOL GuardPageFree (HANDLE hHeap, ULONG ulFlags, PVOID pvMem);
PVOID GuardPageAlloc(HANDLE hHeap, ULONG ulFlags, ULONG ulBytes);
PBYTE GuardPageIsAllocCorrupt(PALLOC_INFO psAlloc);
HEAPS gsHeaps={FALSE};
MEMCHK_FNS sfnUsingGuardBuf = {GuardBufAlloc, GuardBufFree, GuardBufIsAllocCorrupt};
MEMCHK_FNS sfnUsingGuardPage = {GuardPageAlloc, GuardPageFree, GuardPageIsAllocCorrupt};
HANDLE ghMallocHeap=INVALID_HANDLE_VALUE;
/**************************************************************************
* Function Name : MemChkHeapCreate
* Inputs : ULONG ulOptions, ULONG dwInitialSize, ULONG dwMaximumSize
* Outputs :
* Returns :
* Description :
**************************************************************************/
HANDLE MemChkHeapCreate(ULONG ulOptions, ULONG ulInitialSize, ULONG ulMaximumSize)
{
ULONG ulIdx;
ULONG ulCallerAddr;
PHEAP_INFO psHeap;
/* Get callers address */
ulCallerAddr = GET_CALLER_ADDR;
/* First check global control struct has been initialed */
if (gsHeaps.bInit == FALSE)
{
memset(&gsHeaps, 0, sizeof(gsHeaps));
/* Check for check level value from registry */
ReadRegistryDword( L"MemCheckLevel" , &gsHeaps.ulCheckLevel);
/* Read type of memchk method we should use */
ReadRegistryDword(L"MemCheckMethod" , &gsHeaps.ulMemChkType);
/* If we are using guard pages find config */
if (gsHeaps.ulMemChkType == MEMCHK_GUARD_PAGE)
{
ULONG ulPrimaryGuardPages=1;
ULONG ulSecondaryGuardPages=0;
ULONG ulTemp;
/* Check if we want to check for underruns */
ReadRegistryDword(L"MemCheckFindUnderuns" , &ulTemp);
gsHeaps.sGuradPageConfig.bFindUnderRuns = (BOOL)ulTemp;
/* Read number of primary/secondary guard pages needed */
ReadRegistryDword(L"MemCheckPrimaryGuardPages" , &ulPrimaryGuardPages);
ReadRegistryDword(L"MemCheckSecondaryGuardPages" , &ulSecondaryGuardPages);
/* Now work out number of front and back guard pages */
if (gsHeaps.sGuradPageConfig.bFindUnderRuns == FALSE)
{
/* Ok we want to find overruns, so primary guard pages are after the buffer */
gsHeaps.sGuradPageConfig.ulFrontGuradPages = ulSecondaryGuardPages;
gsHeaps.sGuradPageConfig.ulBackGuradPages = ulPrimaryGuardPages;
}
else
{
/* Ok we want to find underruns, so primary guard pages are after the buffer */
gsHeaps.sGuradPageConfig.ulFrontGuradPages = ulPrimaryGuardPages;
gsHeaps.sGuradPageConfig.ulBackGuradPages = ulSecondaryGuardPages;
}
}
gsHeaps.bInit=TRUE;
}
/* Check type of checking is being used */
if (gsHeaps.ulMemChkType == MEMCHK_GUARD_PAGE)
{
/* Alway use first heap */
psHeap=gsHeaps.sHeaps;
memset(psHeap, 0, sizeof(HEAP_INFO));
psHeap->hHeap=(HANDLE)0x12345678;
/* Setup function pointers */
gsHeaps.psfnRoutines=&sfnUsingGuardPage;
}
else
{
/* Find free idx in table */
ulIdx=0;
while (gsHeaps.sHeaps[ulIdx].hHeap != 0 && ulIdx < MAX_HEAPS-1)
{
ulIdx++;
}
if (gsHeaps.sHeaps[ulIdx].hHeap != 0)
{
DPFERROR((L"MemChkHeapCreate : No spare heaps avaliable, recompile increasing value of MAX_HEAPS"));
DebugBreak();
return 0;
}
psHeap=&gsHeaps.sHeaps[ulIdx];
/* Found new heap, zero control struct */
memset(psHeap, 0, sizeof(HEAP_INFO));
/* Now create heap */
psHeap->hHeap=HeapCreate(ulOptions, ulInitialSize, ulMaximumSize);
if (psHeap->hHeap == 0)
{
DPFERROR((L"MemChkHeapCreate : Failed to create heap"));
DebugBreak();
return 0;
}
/* Store the heap params */
psHeap->ulInitSize = ulInitialSize;
psHeap->ulMaxSize = ulMaximumSize;
psHeap->ulHpCreateFlags = ulOptions;
psHeap->ulCreatorEIP = ulCallerAddr;
/* Setup function pointers */
gsHeaps.psfnRoutines = &sfnUsingGuardBuf;
}
return ((HANDLE)psHeap);
}
/**************************************************************************
* Function Name : MemChkHeapDestroy
* Inputs : HANDLE hHeap
* Outputs :
* Returns :
* Description :
**************************************************************************/
BOOL MemChkHeapDestroy(HANDLE hHeap)
{
BOOL bRtn = TRUE;
PHEAP_INFO psHeap = (PHEAP_INFO)hHeap;
if (psHeap->sStats.ulCurrentAllocs != 0)
{
MemChkCheckAllHeaps(TRUE);
DebugBreak();
}
else
{
PALLOC_LIST psAllocList, psNext;
/* walk the alloclist freeing memory */
psAllocList = psHeap->psAllocList;
while (psAllocList)
{
psNext = psAllocList->psNext;
free(psAllocList);
psAllocList = psNext;
}
}
if ((psHeap->hHeap != (HANDLE)NULL) &&
(psHeap->hHeap != (HANDLE)0x12345678))
{
/* now destroy heap */
bRtn = HeapDestroy(psHeap->hHeap);
}
if (bRtn)
{
gsHeaps.bInit= FALSE;
}
return (bRtn);
}
/**************************************************************************
* Function Name : MemChkHeapSize
* Inputs : HANDLE hHeap, ULONG dwFlags, PVOID pvMem
* Outputs :
* Returns :
* Description :
**************************************************************************/
ULONG MemChkHeapSize(HANDLE hHeap, ULONG ulFlags, PVOID pvMem)
{
DPFWARNING((L"MemChkHeapSize : Not impliemented"));
DebugBreak();
return (0);
}
/**************************************************************************
* Function Name : MemChkHeapReAlloc
* Inputs : HANDLE hHeap, ULONG dwFlags, PVOID pvMem, ULONG dwBytes
* Outputs :
* Returns :
* Description :
**************************************************************************/
PVOID MemChkHeapReAlloc(HANDLE hHeap, ULONG ulFlags, PVOID pvMem, ULONG ulBytes)
{
DPFWARNING((L"MemChkHeapReAlloc : Not impliemented"));
DebugBreak();
return (NULL);
}
/**************************************************************************
* Function Name : MemChkHeapFree
* Inputs : HANDLE hHeap, ULONG ulFlags, PVOID pvMem
* Outputs :
* Returns :
* Description :
**************************************************************************/
BOOL MemChkHeapFree(HANDLE hHeap, ULONG ulFlags, PVOID pvMem)
{
return (gsHeaps.psfnRoutines->pfnHeapFree(hHeap, ulFlags, pvMem));
}
/**************************************************************************
* Function Name : MemChkHeapAlloc
* Inputs : HANDLE hHeap, ULONG ulFlags, ULONG dwBytes
* Outputs :
* Returns :
* Description :
**************************************************************************/
PVOID MemChkHeapAlloc(HANDLE hHeap, ULONG ulFlags, ULONG ulBytes)
{
return (gsHeaps.psfnRoutines->pfnHeapAlloc(hHeap, ulFlags, ulBytes));
}
/**************************************************************************
* Function Name : FindAlloc
* Inputs : PHEAP_INFO psHeap, PVOID pvBufStart
* Outputs :
* Returns :
* Description :
**************************************************************************/
PALLOC_INFO FindAlloc(PHEAP_INFO psHeap, PVOID pvBufStart)
{
PALLOC_LIST psCurList=psHeap->psAllocList;
/* Look at each list */
while (psCurList != NULL)
{
ULONG ulIdx=0;
/* Read all items in this table */
for (ulIdx=0; ulIdx < ALLOC_PER_TABLE; ulIdx++)
{
if (psCurList->asAllocs[ulIdx].pvBufStart == pvBufStart)
{
return &psCurList->asAllocs[ulIdx];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -