summaryrefslogtreecommitdiff
path: root/src/shared/leaktrace.cpp
diff options
context:
space:
mode:
authorTannin <devnull@localhost>2014-04-05 15:36:42 +0200
committerTannin <devnull@localhost>2014-04-05 15:36:42 +0200
commitcabed9b268c9f095d5e3b98a6797b0bcdcd38b1f (patch)
tree454b03b0c5664e90fe586e7b39603e34a526d35b /src/shared/leaktrace.cpp
parent98e5e57a845541acddf519a81957261f58008cb9 (diff)
parentc017f4a0d50b67a44e276bd5ae8929ed3990c62c (diff)
Merge with branch1.1
Diffstat (limited to 'src/shared/leaktrace.cpp')
-rw-r--r--src/shared/leaktrace.cpp39
1 files changed, 30 insertions, 9 deletions
diff --git a/src/shared/leaktrace.cpp b/src/shared/leaktrace.cpp
index 0c618b68..68e57609 100644
--- a/src/shared/leaktrace.cpp
+++ b/src/shared/leaktrace.cpp
@@ -3,7 +3,9 @@
#include <DbgHelp.h>
#include <set>
#include <map>
+#include <vector>
#include <sstream>
+#include <algorithm>
static const int FRAMES_TO_SKIP = 3; // StackData::StackData(), __TraceData::regTrace(), TraceAlloc()
@@ -32,8 +34,18 @@ class StackData {
friend bool operator==(const StackData &LHS, const StackData &RHS);
friend bool operator<(const StackData &LHS, const StackData &RHS);
public:
- StackData() {
+
+ StackData()
+ : m_FunctionName("Dummy"), m_CodeLine(0)
+ {}
+ StackData(const char *functionName, int line) {
m_Count = ::CaptureStackBackTrace(FRAMES_TO_SKIP, FRAMES_TO_CAPTURE, m_Stack, &m_Hash);
+ m_FunctionName = functionName;
+ m_CodeLine = line;
+ if (m_Count == 0) {
+ // TODO in this case the hash doesn't seem to be set. This is of course not a good solution
+ m_Hash = reinterpret_cast<unsigned long>(m_FunctionName) + m_CodeLine;
+ }
}
std::string toString() const {
initDbgIfNecessary();
@@ -45,6 +57,8 @@ public:
std::ostringstream stackStream;
+ stackStream << m_FunctionName << " [" << m_CodeLine << "]\n";
+
for(unsigned int i = 0; i < m_Count; ++i) {
DWORD64 displacement = 0;
if (!::SymFromAddr(::GetCurrentProcess(), (DWORD64)m_Stack[i], &displacement, symbol)) {
@@ -59,6 +73,8 @@ private:
LPVOID m_Stack[FRAMES_TO_CAPTURE];
USHORT m_Count;
ULONG m_Hash;
+ const char *m_FunctionName;
+ int m_CodeLine;
};
bool operator==(const StackData &LHS, const StackData &RHS) {
@@ -70,10 +86,9 @@ bool operator<(const StackData &LHS, const StackData &RHS) {
}
-
static struct __TraceData {
- void regTrace(void *pointer) {
- m_Traces[reinterpret_cast<unsigned long>(pointer)] = StackData();
+ void regTrace(void *pointer, const char *functionName, int line) {
+ m_Traces[reinterpret_cast<unsigned long>(pointer)] = StackData(functionName, line);
}
void deregTrace(void *pointer) {
auto iter = m_Traces.find(reinterpret_cast<unsigned long>(pointer));
@@ -83,24 +98,30 @@ static struct __TraceData {
}
~__TraceData() {
- std::map<StackData, int> result;
+ std::map<StackData, std::vector<unsigned long> > result;
for (auto iter = m_Traces.begin(); iter != m_Traces.end(); ++iter) {
- result[iter->second] += 1;
+ result[iter->second].push_back(iter->first);
}
for (auto iter = result.begin(); iter != result.end(); ++iter) {
printf("-----------------------------------\n"
"%d objects not freed, allocated at:\n%s",
- iter->second, iter->first.toString().c_str());
+ iter->second.size(), iter->first.toString().c_str());
+ printf("Addresses: ");
+ for (int i = 0; i < (std::min<int>)(5, iter->second.size()); ++i) {
+ printf("%p, ", iter->second[i]);
+ }
+ printf("\n");
}
}
std::map<unsigned long, StackData> m_Traces;
+
} __trace;
-void LeakTrace::TraceAlloc(void *ptr)
+void LeakTrace::TraceAlloc(void *ptr, const char *functionName, int line)
{
- __trace.regTrace(ptr);
+ __trace.regTrace(ptr, functionName, line);
}
void LeakTrace::TraceDealloc(void *ptr)