From 04dcceef5921e0a0b5318bc752135d0f318588a1 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Sun, 30 Mar 2014 01:18:30 +0100 Subject: [PATCH] Implement Utility::GetSymbolName and Utility::GetSymbolSource for Windows. Refs #5870 --- lib/base/stacktrace.cpp | 41 ++++++++--------------------------------- lib/base/stacktrace.h | 6 ++---- lib/base/utility.cpp | 41 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 39 deletions(-) diff --git a/lib/base/stacktrace.cpp b/lib/base/stacktrace.cpp index 182774ea3..dd7db0a5e 100644 --- a/lib/base/stacktrace.cpp +++ b/lib/base/stacktrace.cpp @@ -22,6 +22,7 @@ #include "base/utility.h" #include "base/convert.h" #include "base/application.h" +#include "base/initialize.h" #ifdef HAVE_BACKTRACE_SYMBOLS # include @@ -29,7 +30,7 @@ using namespace icinga; -boost::once_flag StackTrace::m_OnceFlag = BOOST_ONCE_INIT; +INITIALIZE_ONCE(&StackTrace::StaticInitialize); #ifdef _MSC_VER # pragma optimize("", off) @@ -37,8 +38,6 @@ boost::once_flag StackTrace::m_OnceFlag = BOOST_ONCE_INIT; StackTrace::StackTrace(void) { - boost::call_once(m_OnceFlag, &StackTrace::Initialize); - #ifdef HAVE_BACKTRACE_SYMBOLS m_Count = backtrace(m_Frames, sizeof(m_Frames) / sizeof(m_Frames[0])); #else /* HAVE_BACKTRACE_SYMBOLS */ @@ -57,8 +56,6 @@ StackTrace::StackTrace(void) #ifdef _WIN32 StackTrace::StackTrace(PEXCEPTION_POINTERS exi) { - boost::call_once(m_OnceFlag, &StackTrace::Initialize); - STACKFRAME64 frame; int architecture; @@ -91,7 +88,7 @@ StackTrace::StackTrace(PEXCEPTION_POINTERS exi) } #endif /* _WIN32 */ -void StackTrace::Initialize(void) +void StackTrace::StaticInitialize(void) { #ifdef _WIN32 (void) SymSetOptions(SYMOPT_UNDNAME | SYMOPT_LOAD_LINES); @@ -153,33 +150,11 @@ void StackTrace::Print(std::ostream& fp, int ignoreFrames) const # endif /* HAVE_BACKTRACE_SYMBOLS */ #else /* _WIN32 */ for (int i = ignoreFrames + 1; i < m_Count; i++) { - char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; - PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; - pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); - pSymbol->MaxNameLen = MAX_SYM_NAME; - - DWORD64 dwAddress = (DWORD64)m_Frames[i]; - DWORD dwDisplacement; - DWORD64 dwDisplacement64; - - IMAGEHLP_LINE64 line; - line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); - - fp << "\t(" << i - ignoreFrames - 1 << ") "; - - if (SymGetLineFromAddr64(GetCurrentProcess(), dwAddress, &dwDisplacement, &line)) - fp << line.FileName << ":" << line.LineNumber; - else - fp << "(unknown file/line)"; - - fp << ": "; - - if (SymFromAddr(GetCurrentProcess(), dwAddress, &dwDisplacement64, pSymbol)) - fp << pSymbol->Name << "+" << dwDisplacement64; - else - fp << "(unknown function)"; - - fp << std::endl; + fp << "\t(" << i - ignoreFrames - 1 << ") " + << Utility::GetSymbolSource(m_Frames[i]) + << ": " + << Utility::GetSymbolName(m_Frames[i]) + << std::endl; } #endif /* _WIN32 */ } diff --git a/lib/base/stacktrace.h b/lib/base/stacktrace.h index cd6828ff8..655dfc6ab 100644 --- a/lib/base/stacktrace.h +++ b/lib/base/stacktrace.h @@ -43,13 +43,11 @@ public: void Print(std::ostream& fp, int ignoreFrames = 0) const; + static void StaticInitialize(void); + private: void *m_Frames[64]; int m_Count; - - static boost::once_flag m_OnceFlag; - - static void Initialize(void); }; I2_BASE_API std::ostream& operator<<(std::ostream& stream, const StackTrace& trace); diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index 189f77333..be921c6bb 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -128,7 +128,28 @@ String Utility::GetSymbolName(const void *addr) return dli.dli_sname; #endif /* HAVE_DLADDR */ - return ""; +#ifdef _WIN32 + char buffer[sizeof(SYMBOL_INFO)+MAX_SYM_NAME * sizeof(TCHAR)]; + PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; + pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); + pSymbol->MaxNameLen = MAX_SYM_NAME; + + DWORD64 dwAddress = (DWORD64)addr; + DWORD64 dwDisplacement; + + IMAGEHLP_LINE64 line; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + + if (SymFromAddr(GetCurrentProcess(), dwAddress, &dwDisplacement, pSymbol)) { + char output[256]; + if (UnDecorateSymbolName(pSymbol->Name, output, sizeof(output), UNDNAME_COMPLETE)) + return String(output) + "+" + Convert::ToString(dwDisplacement); + else + return String(pSymbol->Name) + "+" + Convert::ToString(dwDisplacement); + } +#endif /* _WIN32 */ + + return "(unknown function)"; } String Utility::GetSymbolSource(const void *addr) @@ -142,7 +163,23 @@ String Utility::GetSymbolSource(const void *addr) } #endif /* HAVE_DLADDR */ - return ""; +#ifdef _WIN32 + char buffer[sizeof(SYMBOL_INFO)+MAX_SYM_NAME * sizeof(TCHAR)]; + PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; + pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); + pSymbol->MaxNameLen = MAX_SYM_NAME; + + DWORD64 dwAddress = (DWORD64)addr; + DWORD dwDisplacement; + + IMAGEHLP_LINE64 line; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + + if (SymGetLineFromAddr64(GetCurrentProcess(), dwAddress, &dwDisplacement, &line)) + return String(line.FileName) + ":" + Convert::ToString(line.LineNumber); +#endif /* _WIN32 */ + + return "(unknown file/line)"; } /**