You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw-tes3coop/apps/openmw-mp/stacktrace.cpp

96 lines
2.2 KiB
C++

//
// Created by koncord on 25.10.17.
//
#include "stacktrace.hpp"
#include <components/openmw-mp/Log.hpp>
#ifndef _WIN32
#include <cxxabi.h>
#include <execinfo.h>
void stacktrace()
{
LOG_MESSAGE_SIMPLE(Log::LOG_FATAL, "Stacktrace:");
void *array[50];
int size = backtrace(array, 50);
auto messages = backtrace_symbols(array, size);
size_t funcnamesize = 256;
auto funcname = (char *) malloc(funcnamesize);
//skip first stack frame (points here)
for (int i = 1; i < size && messages != nullptr; ++i)
{
char *beginName = nullptr, *beginOffset = nullptr, *endOffset = nullptr;
for (char *p = messages[i]; *p; ++p)
{
if (*p == '(')
beginName = p;
else if (*p == '+')
beginOffset = p;
else if (*p == ')' && beginOffset)
{
endOffset = p;
break;
}
}
if (beginName && beginOffset && endOffset && beginName < beginOffset)
{
*beginName++ = '\0';
*beginOffset++ = '\0';
*endOffset = '\0';
// mangled name is now in [beginName, beginOffset) and caller offset in [beginOffset, endOffset).
int status;
char *ret = abi::__cxa_demangle(beginName, funcname, &funcnamesize, &status);
if (status == 0)
{
funcname = ret; // use possibly realloc()-ed string
LOG_APPEND(Log::LOG_FATAL, "\t%s : %s+%s", messages[i], funcname, beginOffset);
}
else // demangling failed.
LOG_APPEND(Log::LOG_FATAL, "\t%s : %s()+%s", messages[i], beginName, beginOffset);
}
else
LOG_APPEND(Log::LOG_FATAL, "\t%s", messages[i]);
}
free(messages);
free(funcname);
}
#else
#include "stackwalker/StackWalker.h"
class StackWalkerClr: public StackWalker
{
std::string out;
virtual void OnOutput(LPCSTR szText)
{
out.append(szText);
}
public:
std::string &getData()
{
ShowCallstack();
return out;
}
};
void stacktrace()
{
LOG_MESSAGE_SIMPLE(Log::LOG_FATAL, "Stacktrace:");
StackWalkerClr swc;
LOG_APPEND(Log::LOG_FATAL, swc.getData().c_str());
}
#endif