00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef _DEBUG
00020
00021 #if !defined(MEMLEAKDETECT_H)
00022 #define MEMLEAKDETECT_H
00023
00024 #define _CRTDBG_MAP_ALLOC
00025
00026 #include <map>
00027 #define _CRTBLD
00028 #include <windows.h>
00029 #include "dbgint.h"
00030 #include <ImageHlp.h>
00031 #include <crtdbg.h>
00032
00033
00034 #pragma comment( lib, "imagehlp.lib" )
00035
00036 using namespace std;
00037
00038
00039
00040
00041
00042 #define MLD_MAX_NAME_LENGTH 256
00043 #define MLD_MAX_TRACEINFO 256
00044 #define MLD_TRACEINFO_EMPTY _T("")
00045 #define MLD_TRACEINFO_NOSYMBOL _T("?(?)")
00046
00047 #ifdef MLD_CUSTOMSTACKWALK
00048 #define MLD_STACKWALKER symStackTrace2
00049 #else
00050 #define MLD_STACKWALKER symStackTrace
00051 #endif
00052
00053 #define AfxTrace MyTrace
00054
00055 typedef DWORD ADDR;
00056
00057 class CMemLeakDetect
00058 {
00059 public:
00060
00061 typedef struct {
00062 ADDRESS addrPC;
00063 ADDRESS addrFrame;
00064
00065 } STACKFRAMEENTRY;
00066
00067 typedef struct {
00068 void* address;
00069 DWORD size;
00070 TCHAR fileName[MLD_MAX_NAME_LENGTH];
00071 DWORD lineNumber;
00072 DWORD occurance;
00073 STACKFRAMEENTRY traceinfo[MLD_MAX_TRACEINFO];
00074
00075 } AllocBlockInfo;
00076
00077
00078 typedef map<LPVOID, AllocBlockInfo> KEYMAP;
00079 typedef map<LPVOID, AllocBlockInfo>::iterator POSITION;
00080 typedef pair<LPVOID, AllocBlockInfo> KEYVALUE;
00081
00082 class CMapMem
00083 {
00084 public:
00085
00086 KEYMAP m_Map;
00087 POSITION m_Pos;
00088
00089 inline BOOL Lookup(LPVOID pAddr, AllocBlockInfo& aInfo) {
00090
00091 m_Pos = m_Map.find(pAddr);
00092
00093 if (m_Pos == m_Map.end())
00094 {
00095 return FALSE;
00096 }
00097
00098 pAddr = m_Pos->first;
00099 aInfo = m_Pos->second;
00100
00101 return TRUE;
00102 };
00103
00104 inline POSITION end() {
00105
00106 return m_Map.end();
00107 };
00108
00109 inline void RemoveKey(LPVOID pAddr) {
00110
00111 m_Map.erase(pAddr);
00112 };
00113
00114 inline void RemoveAll() {
00115 m_Map.clear();
00116 };
00117
00118 void SetAt(LPVOID pAddr, AllocBlockInfo& aInfo) {
00119
00120 m_Map[pAddr] = aInfo;
00121 };
00122
00123 inline POSITION GetStartPosition() {
00124 POSITION pos = m_Map.begin();
00125 return pos;
00126 };
00127
00128 inline void GetNextAssoc(POSITION& pos, LPVOID& rAddr, AllocBlockInfo& aInfo) {
00129
00130 rAddr = pos->first;
00131 aInfo = pos->second;
00132 pos++;
00133 };
00134
00135 void InitHashTable(int preAllocEntries, BOOL flag) {
00136 preAllocEntries = NULL;
00137 flag = NULL;
00138 };
00139
00140 };
00141
00142 CMemLeakDetect();
00143 ~CMemLeakDetect();
00144 void Init();
00145 void End();
00146 void Enable(bool enable) { enabled = enable; }
00147 void addMemoryTrace(void* addr, DWORD asize, TCHAR *fname, DWORD lnum);
00148 void redoMemoryTrace(void* addr, void* oldaddr, DWORD asize, TCHAR *fname, DWORD lnum);
00149 void removeMemoryTrace(void* addr, void* realdataptr);
00150 void cleanupMemoryTrace();
00151 void dumpMemoryTrace();
00152
00153
00154 CMapMem m_AllocatedMemoryList;
00155 DWORD memoccurance;
00156 bool isLocked;
00157
00158 private:
00159
00160 BOOL initSymInfo(TCHAR* lpUserPath);
00161 BOOL cleanupSymInfo();
00162 void symbolPaths( TCHAR* lpszSymbolPaths);
00163 void symStackTrace(STACKFRAMEENTRY* pStacktrace);
00164 void symStackTrace2(STACKFRAMEENTRY* pStacktrace);
00165 BOOL symFunctionInfoFromAddresses(ULONG fnAddress, ULONG stackAddress, char* lpszSymbol);
00166 BOOL symSourceInfoFromAddress(UINT address, TCHAR* lpszSourceInfo);
00167 BOOL symModuleNameFromAddress(UINT address, TCHAR* lpszModule);
00168
00169 HANDLE m_hProcess;
00170 PIMAGEHLP_SYMBOL m_pSymbol;
00171 DWORD m_dwsymBufSize;
00172
00173 bool enabled;
00174 };
00175 #endif
00176
00177 #endif