summaryrefslogtreecommitdiff
path: root/src/shared/util.cpp
diff options
context:
space:
mode:
authorTannin <devnull@localhost>2013-07-17 20:58:58 +0200
committerTannin <devnull@localhost>2013-07-17 20:58:58 +0200
commitd0f2c4fcf79222d5c6f3c17188a811b0a47833c6 (patch)
tree12c9e4f529caa0f5830c8dd52d785b3e2df5462b /src/shared/util.cpp
parent36ac91e0b765b1ae099e93054447beca8f461f74 (diff)
- now avoids a few unnecessary copy operations during generation of the directory structure
- bugfix: circular dependency caused a memory leak - bugfix: removing a single mod lead to the wrong mod being deleted
Diffstat (limited to 'src/shared/util.cpp')
-rw-r--r--src/shared/util.cpp35
1 files changed, 25 insertions, 10 deletions
diff --git a/src/shared/util.cpp b/src/shared/util.cpp
index 1c4bf5b6..4378e03c 100644
--- a/src/shared/util.cpp
+++ b/src/shared/util.cpp
@@ -24,6 +24,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <sstream>
#include <algorithm>
#include <DbgHelp.h>
+#include <set>
namespace MOShared {
@@ -147,24 +148,38 @@ VS_FIXEDFILEINFO GetFileVersion(const std::wstring &fileName)
std::string GetStack()
{
-#ifdef DEBUG
+#ifdef _DEBUG
HANDLE process = ::GetCurrentProcess();
- static bool firstCall = true;
- if (firstCall) {
- ::SymInitialize(process, NULL, TRUE);
- firstCall = false;
+ static std::set<DWORD> initialized;
+ if (initialized.find(::GetCurrentProcessId()) == initialized.end()) {
+ static bool firstCall = true;
+ if (firstCall) {
+ ::SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
+ firstCall = false;
+ }
+ if (!::SymInitialize(process, NULL, TRUE)) {
+ log("failed to initialize symbols: %d", ::GetLastError());
+ }
+ initialized.insert(::GetCurrentProcessId());
}
LPVOID stack[32];
WORD frames = ::CaptureStackBackTrace(0, 100, stack, NULL);
- SYMBOL_INFO_PACKAGE symbol;
- symbol.si.SizeOfStruct = sizeof(SYMBOL_INFO);
- symbol.si.MaxNameLen = MAX_SYM_NAME;
+
+ char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
+ PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
+ symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
+ symbol->MaxNameLen = MAX_SYM_NAME;
std::ostringstream stackStream;
for(unsigned int i = 0; i < frames; ++i) {
- ::SymFromAddr(process, (DWORD64)(stack[i]), 0, &symbol.si);
- stackStream << frames - i - 1 << ": " << symbol.si.Name << "\n";
+ DWORD64 addr = (DWORD64)stack[i];
+ DWORD64 displacement = 0;
+ if (!::SymFromAddr(::GetCurrentProcess(), addr, &displacement, symbol)) {
+ stackStream << frames - i - 1 << ": " << stack[i] << " - " << ::GetLastError() << " (error)\n";
+ } else {
+ stackStream << frames - i - 1 << ": " << symbol->Name << "\n";
+ }
}
return stackStream.str();
#else