diff options
| author | Tannin <devnull@localhost> | 2013-09-28 21:13:57 +0200 |
|---|---|---|
| committer | Tannin <devnull@localhost> | 2013-09-28 21:13:57 +0200 |
| commit | 47293827bbd92ce227e5188c10b66deb9f85d5bf (patch) | |
| tree | c8e9f34dc3105a3e73b41f8b2fb58d58439b06e0 /src/shared | |
| parent | 0a3169b808cf2b84ae7c77fd6cb0a7b0aa9a8df3 (diff) | |
- 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
Diffstat (limited to 'src/shared')
| -rw-r--r-- | src/shared/directoryentry.cpp | 7 | ||||
| -rw-r--r-- | src/shared/leaktrace.cpp | 37 | ||||
| -rw-r--r-- | src/shared/leaktrace.h | 4 |
3 files changed, 35 insertions, 13 deletions
diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index bd33fef6..8380181f 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -568,8 +568,9 @@ void DirectoryEntry::removeDirRecursive() for (auto iter = m_SubDirectories.begin(); iter != m_SubDirectories.end(); ++iter) {
(*iter)->removeDirRecursive();
+ delete *iter;
}
- m_SubDirectories.clear();
+ m_SubDirectories.clear();
}
void DirectoryEntry::removeDir(const std::wstring &path)
@@ -578,8 +579,10 @@ void DirectoryEntry::removeDir(const std::wstring &path) if (pos == std::string::npos) {
for (auto iter = m_SubDirectories.begin(); iter != m_SubDirectories.end(); ++iter) {
if (_wcsicmp((*iter)->getName().c_str(), path.c_str()) == 0) {
- (*iter)->removeDirRecursive();
+ DirectoryEntry *entry = *iter;
+ entry->removeDirRecursive();
m_SubDirectories.erase(iter);
+ delete entry;
break;
}
}
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 <DbgHelp.h>
#include <set>
#include <map>
+#include <vector>
#include <sstream>
@@ -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<unsigned long>(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<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,14 +97,19 @@ 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");
}
}
@@ -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)
diff --git a/src/shared/leaktrace.h b/src/shared/leaktrace.h index 78764260..4985925e 100644 --- a/src/shared/leaktrace.h +++ b/src/shared/leaktrace.h @@ -4,14 +4,14 @@ namespace LeakTrace {
-void TraceAlloc(void *ptr);
+void TraceAlloc(void *ptr, const char *functionName, int line);
void TraceDealloc(void *ptr);
};
#ifdef TRACE_LEAKS
-#define LEAK_TRACE LeakTrace::TraceAlloc(this)
+#define LEAK_TRACE LeakTrace::TraceAlloc(this, __FUNCTION__, __LINE__)
#define LEAK_UNTRACE LeakTrace::TraceDealloc(this)
#else // TRACE_LEAKS
|
