Implement Utility::GetSymbolName and Utility::GetSymbolSource for Windows.

Refs #5870
This commit is contained in:
Gunnar Beutner 2014-03-30 01:18:30 +01:00
parent 14084735da
commit 04dcceef59
3 changed files with 49 additions and 39 deletions

View File

@ -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 <execinfo.h>
@ -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 */
}

View File

@ -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);

View File

@ -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)";
}
/**