From 47293827bbd92ce227e5188c10b66deb9f85d5bf Mon Sep 17 00:00:00 2001 From: Tannin Date: Sat, 28 Sep 2013 21:13:57 +0200 Subject: - download progress is now visible in task bar - esp-tooltip now lists all masters, highlighting the missing ones - python plugin will now report a problem if the path contains a semicolon - leak detection now (somewaht) works around the fact that we don't always get a stack trace - bugfix: mod meta-file is now reliably created if it was missing - bugfix: parser for nxm-links didn't handle numbers in the mod name - bugfix: small memory leak --- src/shared/leaktrace.cpp | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) (limited to 'src/shared/leaktrace.cpp') diff --git a/src/shared/leaktrace.cpp b/src/shared/leaktrace.cpp index 0c618b68..83ed4fd0 100644 --- a/src/shared/leaktrace.cpp +++ b/src/shared/leaktrace.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -32,8 +33,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(m_FunctionName) + m_CodeLine; + } } std::string toString() const { initDbgIfNecessary(); @@ -45,6 +56,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 +72,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 +85,9 @@ bool operator<(const StackData &LHS, const StackData &RHS) { } - static struct __TraceData { - void regTrace(void *pointer) { - m_Traces[reinterpret_cast(pointer)] = StackData(); + void regTrace(void *pointer, const char *functionName, int line) { + m_Traces[reinterpret_cast(pointer)] = StackData(functionName, line); } void deregTrace(void *pointer) { auto iter = m_Traces.find(reinterpret_cast(pointer)); @@ -83,14 +97,19 @@ static struct __TraceData { } ~__TraceData() { - std::map result; + std::map > 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)(5, iter->second.size()); ++i) { + printf("%p, ", iter->second[i]); + } + printf("\n"); } } @@ -98,9 +117,9 @@ static struct __TraceData { } __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) -- cgit v1.3.1