20 #if defined(ION_PLATFORM_LINUX) || defined(ION_PLATFORM_MAC) || \
21 defined(ION_PLATFORM_IOS)
22 # define ION_STACKTRACE_POSIX
23 # include <execinfo.h>
25 #elif defined(ION_PLATFORM_WINDOWS)
32 # pragma comment(lib, "dbghelp") // Add library in non-production build
33 # pragma comment(lib, "psapi") // Add library in non-production build
44 #if defined(ION_STACKTRACE_POSIX)
45 const int kMaxStackTraceDepth = 128;
47 addresses_.resize(kMaxStackTraceDepth);
48 const int depth = backtrace(&addresses_[0], kMaxStackTraceDepth);
49 addresses_.resize(depth);
51 #elif defined(ION_PLATFORM_WINDOWS)
52 const int kMaxStackTraceDepth = 62;
54 addresses_.resize(kMaxStackTraceDepth);
56 CaptureStackBackTrace(0, kMaxStackTraceDepth, &addresses_[0], NULL);
58 addresses_.resize(depth);
68 void StackTrace::ObtainSymbols()
const {
70 #if defined(ION_STACKTRACE_POSIX)
71 char** trace_cstrings =
73 backtrace_symbols(&addresses_[0], static_cast<int>(addresses_.size()));
74 for (
size_t i = 0; i < addresses_.size(); ++i) {
75 symbols_.push_back(std::string(trace_cstrings[i]));
79 #elif defined(ION_PLATFORM_WINDOWS)
80 const int kMaxNameLength = 255;
82 const int kSymbolSize =
83 sizeof(SYMBOL_INFO) + (kMaxNameLength *
sizeof(TCHAR));
84 char symbol_memory[kSymbolSize] = {0};
85 SYMBOL_INFO* symbol =
reinterpret_cast<SYMBOL_INFO*
>(symbol_memory);
86 symbol->MaxNameLen = kMaxNameLength;
87 symbol->SizeOfStruct =
sizeof(SYMBOL_INFO);
89 const HANDLE process = GetCurrentProcess();
90 SymInitialize(process, NULL, TRUE);
91 for (
size_t i = 0; i < addresses_.size(); ++i) {
92 const DWORD64 address =
reinterpret_cast<DWORD64
>(addresses_[i]);
93 const BOOL success = SymFromAddr(process, address, 0, symbol);
94 std::ostringstream output;
95 if (success == TRUE) {
96 output << symbol->Name;
98 output <<
"??? [0x" << std::hex << address <<
"]"
99 <<
"symbol not found; GetLastError() returns " << GetLastError();
101 symbols_.push_back(output.str());
113 #undef ION_STACKTRACE_POSIX
116 if (symbols_.empty())
123 const std::vector<std::string>& symbols =
GetSymbols();
124 std::ostringstream output;
125 for (
size_t i = 0; i < addresses.size(); ++i) {
126 output <<
"[" << addresses[i] <<
"]: " << symbols[i] << std::endl;
const std::vector< void * > & GetAddresses() const
Returns the stack as a vector of addresses.
const std::vector< std::string > & GetSymbols() const
Returns the stack as a vector of symbol names.
const std::string GetSymbolString() const
Returns formatted string containing symbolic function names for elements of the stack trace...