RCFProto

- Main Page
- Classes
- Files

- File List

All Classes Functions Typedefs
MemLeakDetect.h
1
2 // JL: This code originated from a CodeProject article:
3 // http://www.codeproject.com/KB/cpp/MemLeakDetect.aspx
4
5 #pragma once
6
7 #include "CallStack.hpp"
8
9 // CRT memory tracking only works in debug builds.
10 // Note also that stack traces are only available on x86 builds.
11 #if defined(_DEBUG)
12
13 #define _CRTDBG_MAP_ALLOC
14 #include <map>
15 #define _CRTBLD
16 #include <windows.h>
17
18 #include <..\crt\src\dbgint.h>
19 #include <dbghelp.h>
20 #include <crtdbg.h>
21
22 #include <boost/filesystem/path.hpp>
23
24 class CMemLeakDetect
25 {
26 public:
27
28 struct AllocBlockInfo : public CallStack
29 {
30 AllocBlockInfo() : address(NULL), size(0), lineNumber(0), occurance(0)
31 {
32 memset(fileName, 0, MLD_MAX_NAME_LENGTH * sizeof(TCHAR));
33 }
34
35 void* address;
36 DWORD size;
37 TCHAR fileName[MLD_MAX_NAME_LENGTH];
38 DWORD lineNumber;
39 DWORD occurance;
40 };
41
42 typedef std::map<LPVOID, AllocBlockInfo> KEYMAP;
43 typedef std::map<LPVOID, AllocBlockInfo>::iterator POSITION;
44 typedef std::pair<LPVOID, AllocBlockInfo> KEYVALUE;
45
46 class CMapMem
47 {
48 public:
49
50 KEYMAP m_Map;
51 POSITION m_Pos;
52
53 inline BOOL Lookup(LPVOID pAddr, AllocBlockInfo& aInfo) {
54
55 m_Pos = m_Map.find(pAddr);
56 //
57 if (m_Pos == m_Map.end())
58 {
59 return FALSE;
60 }
61 //
62 pAddr = m_Pos->first;
63 aInfo = m_Pos->second;
64
65 return TRUE;
66 };
67
68 inline POSITION end() {
69
70 return m_Map.end();
71 };
72
73 inline void RemoveKey(LPVOID pAddr) {
74
75 m_Map.erase(pAddr);
76 };
77
78 inline void RemoveAll() {
79 m_Map.clear();
80 };
81
82 void SetAt(LPVOID pAddr, AllocBlockInfo& aInfo) {
83
84 m_Map[pAddr] = aInfo;
85 };
86
87 inline POSITION GetStartPosition() {
88 POSITION pos = m_Map.begin();
89 return pos;
90 };
91
92 inline void GetNextAssoc(POSITION& pos, LPVOID& rAddr, AllocBlockInfo& aInfo) {
93
94 rAddr = pos->first;
95 aInfo = pos->second;
96 pos++;
97 };
98
99 void InitHashTable(int preAllocEntries, BOOL flag) {
100 preAllocEntries = NULL;
101 flag = NULL;
102 };
103
104 };
105
106 CMemLeakDetect(const TCHAR * outputDir = NULL);
107 ~CMemLeakDetect();
108 void Init();
109 void End();
110 void addMemoryTrace(void* addr, DWORD asize, TCHAR *fname, DWORD lnum);
111 void redoMemoryTrace(void* addr, void* oldaddr, DWORD asize, TCHAR *fname, DWORD lnum);
112 void removeMemoryTrace(void* addr, void* realdataptr);
113 void cleanupMemoryTrace();
114 void writeOutput(const TCHAR * szOutput);
115 void dumpMemoryTrace();
116 //
117
118 CMapMem m_AllocatedMemoryList;
119 DWORD memoccurance;
120 bool isLocked;
121 //
122 private:
123
124 public:
125 std::vector<std::basic_string<TCHAR> > m_funcsToIgnore;
126 boost::filesystem::path m_outputFolder;
127
128
129 private:
130 std::string m_outputPath;
131 std::ofstream m_output;
132 };
133
134 #else
135
136 // Dummy replacement for release.
137 class CMemLeakDetect
138 {
139 public:
140 CMemLeakDetect(const TCHAR * = NULL)
141 {
142 }
143 };
144
145 #endif
146
147 // JL: Example instrumentation usage - in a loop that causes memory growth,
148 // get stack traces of outstanding allocations after each iteration. Stack
149 // traces get written to a sequence of text files.
150
151 //std::auto_ptr<CMemLeakDetect> leakDetectorPtr;
152 //while (true)
153 //{
154 // leakDetectPtr.reset( new CMemLeakDetect() );
155 //
156 // // Leaky code here
157 // // ...
158 //
159 // // A new text file will be produced for each iteration.
160 // leakDetectPtr.reset();
161 //}