mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-18 13:42:02 +00:00
84 lines
1.5 KiB
C++
84 lines
1.5 KiB
C++
#include <malloc.h>
|
|
#include <execinfo.h>
|
|
#include <cxxabi.h>
|
|
#include <string.h>
|
|
|
|
#include <sstream>
|
|
|
|
#include <DB/Core/StackTrace.h>
|
|
|
|
|
|
#define DBMS_STACK_TRACE_MAX_DEPTH 32
|
|
|
|
|
|
namespace DB
|
|
{
|
|
|
|
StackTrace::StackTrace()
|
|
{
|
|
frames.resize(DBMS_STACK_TRACE_MAX_DEPTH);
|
|
frames.resize(backtrace(&frames[0], frames.size()));
|
|
}
|
|
|
|
std::string StackTrace::toString() const
|
|
{
|
|
char ** symbols = backtrace_symbols(&frames[0], frames.size());
|
|
std::stringstream res;
|
|
|
|
if (!symbols)
|
|
return "Cannot get symbols for stack trace.\n";
|
|
|
|
try
|
|
{
|
|
for (size_t i = 0, size = frames.size(); i < size; ++i)
|
|
{
|
|
/// Делаем demangling имён. Имя находится в скобках, до символа '+'.
|
|
|
|
char * name_start = NULL;
|
|
char * name_end = NULL;
|
|
char * demangled_name = NULL;
|
|
int status = 0;
|
|
|
|
if (NULL != (name_start = strchr(symbols[i], '('))
|
|
&& NULL != (name_end = strchr(name_start, '+')))
|
|
{
|
|
++name_start;
|
|
*name_end = '\0';
|
|
demangled_name = abi::__cxa_demangle(name_start, 0, 0, &status);
|
|
*name_end = '+';
|
|
}
|
|
|
|
try
|
|
{
|
|
res << i << ". ";
|
|
|
|
if (NULL != demangled_name && 0 == status)
|
|
{
|
|
res.write(symbols[i], name_start - symbols[i]);
|
|
res << demangled_name << name_end;
|
|
}
|
|
else
|
|
res << symbols[i];
|
|
|
|
res << std::endl;
|
|
}
|
|
catch (...)
|
|
{
|
|
free(demangled_name);
|
|
throw;
|
|
}
|
|
free(demangled_name);
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
free(symbols);
|
|
throw;
|
|
}
|
|
|
|
free(symbols);
|
|
return res.str();
|
|
}
|
|
|
|
}
|