2015-05-27 14:48:45 +02:00
|
|
|
#include "backtrace.hh"
|
2014-08-12 01:30:13 +02:00
|
|
|
|
2015-05-29 14:35:54 +02:00
|
|
|
#include "string.hh"
|
2014-08-12 01:30:13 +02:00
|
|
|
|
2015-11-05 17:59:29 +01:00
|
|
|
#if defined(__GLIBC__) || defined(__APPLE__)
|
2014-08-12 01:30:13 +02:00
|
|
|
# include <execinfo.h>
|
|
|
|
#elif defined(__CYGWIN__)
|
|
|
|
# include <windows.h>
|
2015-06-16 19:49:56 +02:00
|
|
|
# include <dbghelp.h>
|
2015-05-29 14:46:49 +02:00
|
|
|
# include <stdio.h>
|
2014-08-12 01:30:13 +02:00
|
|
|
#endif
|
|
|
|
|
2015-11-05 17:59:29 +01:00
|
|
|
#if defined(__linux__) || defined(__APPLE__)
|
|
|
|
# include <stdlib.h>
|
|
|
|
#endif
|
|
|
|
|
2014-08-12 01:30:13 +02:00
|
|
|
namespace Kakoune
|
|
|
|
{
|
|
|
|
|
2015-05-27 14:48:45 +02:00
|
|
|
Backtrace::Backtrace()
|
2014-08-12 01:30:13 +02:00
|
|
|
{
|
2015-11-05 17:59:29 +01:00
|
|
|
#if defined(__GLIBC__) || defined(__APPLE__)
|
2014-08-12 01:30:13 +02:00
|
|
|
num_frames = backtrace(stackframes, max_frames);
|
|
|
|
#elif defined(__CYGWIN__)
|
|
|
|
num_frames = CaptureStackBackTrace(0, max_frames, stackframes, nullptr);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-05-29 14:35:54 +02:00
|
|
|
String Backtrace::desc() const
|
2014-08-12 01:30:13 +02:00
|
|
|
{
|
2015-11-05 17:59:29 +01:00
|
|
|
#if defined(__GLIBC__) || defined(__APPLE__)
|
2014-08-12 01:30:13 +02:00
|
|
|
char** symbols = backtrace_symbols(stackframes, num_frames);
|
2015-05-29 14:35:54 +02:00
|
|
|
ByteCount size = 0;
|
2014-08-12 01:30:13 +02:00
|
|
|
for (int i = 0; i < num_frames; ++i)
|
2015-05-29 14:35:54 +02:00
|
|
|
size += StringView::strlen(symbols[i]) + 1;
|
2014-08-12 01:30:13 +02:00
|
|
|
|
2015-05-29 14:35:54 +02:00
|
|
|
String res; res.reserve(size);
|
2014-08-12 01:30:13 +02:00
|
|
|
for (int i = 0; i < num_frames; ++i)
|
|
|
|
{
|
2015-05-29 14:35:54 +02:00
|
|
|
res += symbols[i];
|
|
|
|
res += "\n";
|
2014-08-12 01:30:13 +02:00
|
|
|
}
|
|
|
|
free(symbols);
|
|
|
|
return res;
|
|
|
|
#elif defined(__CYGWIN__)
|
2015-06-16 19:49:56 +02: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 01:30:13 +02:00
|
|
|
for (int i = 0; i < num_frames; ++i)
|
|
|
|
{
|
2015-06-16 19:49:56 +02: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 01:30:13 +02:00
|
|
|
}
|
|
|
|
return res;
|
|
|
|
#else
|
|
|
|
return "<not implemented>";
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|