diff --git a/apps/openmw-mp/stacktrace.cpp b/apps/openmw-mp/stacktrace.cpp new file mode 100644 index 000000000..858462a93 --- /dev/null +++ b/apps/openmw-mp/stacktrace.cpp @@ -0,0 +1,73 @@ +// +// Created by koncord on 25.10.17. +// + +#include "stacktrace.hpp" +#include + +#ifndef _WIN32 + +#include + +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 + +void stacktrace() +{ + +} + +#endif \ No newline at end of file diff --git a/apps/openmw-mp/stacktrace.hpp b/apps/openmw-mp/stacktrace.hpp new file mode 100644 index 000000000..283cf3143 --- /dev/null +++ b/apps/openmw-mp/stacktrace.hpp @@ -0,0 +1,10 @@ +// +// Created by koncord on 25.10.17. +// + +#ifndef OPENMW_STACKTRACE_HPP +#define OPENMW_STACKTRACE_HPP + +void stacktrace(); + +#endif //OPENMW_STACKTRACE_HPP