2015-05-27 15:48:45 +03:00
|
|
|
#include "backtrace.hh"
|
2014-08-12 03:30:13 +04:00
|
|
|
|
2015-05-29 15:35:54 +03:00
|
|
|
#include "string.hh"
|
2014-08-12 03:30:13 +04:00
|
|
|
|
2015-11-05 19:59:29 +03:00
|
|
|
#if defined(__GLIBC__) || defined(__APPLE__)
|
2014-08-12 03:30:13 +04:00
|
|
|
# include <execinfo.h>
|
|
|
|
#elif defined(__CYGWIN__)
|
|
|
|
# include <windows.h>
|
2015-06-16 20:49:56 +03:00
|
|
|
# include <dbghelp.h>
|
2015-05-29 15:46:49 +03:00
|
|
|
# include <stdio.h>
|
2014-08-12 03:30:13 +04:00
|
|
|
#endif
|
|
|
|
|
2015-11-05 19:59:29 +03:00
|
|
|
#if defined(__linux__) || defined(__APPLE__)
|
|
|
|
# include <stdlib.h>
|
|
|
|
#endif
|
|
|
|
|
2014-08-12 03:30:13 +04:00
|
|
|
namespace Kakoune
|
|
|
|
{
|
|
|
|
|
2015-05-27 15:48:45 +03:00
|
|
|
Backtrace::Backtrace()
|
2014-08-12 03:30:13 +04:00
|
|
|
{
|
2015-11-05 19:59:29 +03:00
|
|
|
#if defined(__GLIBC__) || defined(__APPLE__)
|
2014-08-12 03:30:13 +04:00
|
|
|
num_frames = backtrace(stackframes, max_frames);
|
|
|
|
#elif defined(__CYGWIN__)
|
|
|
|
num_frames = CaptureStackBackTrace(0, max_frames, stackframes, nullptr);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-05-29 15:35:54 +03:00
|
|
|
String Backtrace::desc() const
|
2014-08-12 03:30:13 +04:00
|
|
|
{
|
2015-11-05 19:59:29 +03:00
|
|
|
#if defined(__GLIBC__) || defined(__APPLE__)
|
2014-08-12 03:30:13 +04:00
|
|
|
char** symbols = backtrace_symbols(stackframes, num_frames);
|
2015-05-29 15:35:54 +03:00
|
|
|
ByteCount size = 0;
|
2014-08-12 03:30:13 +04:00
|
|
|
for (int i = 0; i < num_frames; ++i)
|
2016-02-05 02:52:06 +03:00
|
|
|
size += strlen(symbols[i]) + 1;
|
2014-08-12 03:30:13 +04:00
|
|
|
|
2015-05-29 15:35:54 +03:00
|
|
|
String res; res.reserve(size);
|
2014-08-12 03:30:13 +04:00
|
|
|
for (int i = 0; i < num_frames; ++i)
|
|
|
|
{
|
2015-05-29 15:35:54 +03:00
|
|
|
res += symbols[i];
|
|
|
|
res += "\n";
|
2014-08-12 03:30:13 +04:00
|
|
|
}
|
|
|
|
free(symbols);
|
|
|
|
return res;
|
|
|
|
#elif defined(__CYGWIN__)
|
2015-06-16 20:49:56 +03:00
|
|
|
HANDLE process = GetCurrentProcess();
|
|
|
|
|
|
|
|
static bool symbols_initialized = false;
|
|
|
|
if (not symbols_initialized)
|
|
|
|
{
|
|
|
|
SymInitialize(process, nullptr, true);
|
|
|
|
symbols_initialized = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
alignas(SYMBOL_INFO) char symbol_info_buffer[sizeof(SYMBOL_INFO) + 256];
|
|
|
|
SYMBOL_INFO* symbol_info = reinterpret_cast<SYMBOL_INFO*>(symbol_info_buffer);
|
|
|
|
symbol_info->MaxNameLen = 255;
|
|
|
|
symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO);
|
|
|
|
|
|
|
|
String res; // res.reserve(num_frames * 276);
|
2014-08-12 03:30:13 +04:00
|
|
|
for (int i = 0; i < num_frames; ++i)
|
|
|
|
{
|
2015-06-16 20:49:56 +03:00
|
|
|
SymFromAddr(process, (DWORD64)stackframes[i], 0, symbol_info);
|
|
|
|
char desc[276];
|
|
|
|
snprintf(desc, 276, "0x%0llx (%s)\n", symbol_info->Address, symbol_info->Name);
|
|
|
|
res += desc;
|
2014-08-12 03:30:13 +04:00
|
|
|
}
|
|
|
|
return res;
|
|
|
|
#else
|
|
|
|
return "<not implemented>";
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|