diff --git a/components/common/cpp/src/exception.cpp b/components/common/cpp/src/exception.cpp index cf74b297ab3218a0786b66127c96ec4cc7d64ea1..46897adea1ef16ffa739a8fda961fd9d5fc6f70f 100644 --- a/components/common/cpp/src/exception.cpp +++ b/components/common/cpp/src/exception.cpp @@ -3,40 +3,84 @@ #define LOGURU_REPLACE_GLOG 1 #include <loguru.hpp> -#ifndef WIN32 +#ifdef __GNUC__ #include <execinfo.h> +#include <dlfcn.h> +#include <cxxabi.h> #endif using ftl::exception; using std::string; -static std::string getBackTrace() { -#ifndef WIN32 +static std::string demangle(const char* name) { + if (!name) { + return "[unknown symbol]"; + } +#ifdef __GNUC__ + int status; + char* demangled = abi::__cxa_demangle(name, NULL, 0, &status); + if (!demangled) { + return std::string(name); + } + else { + auto result = string(demangled); + free(demangled); + return result; + } +#else + return std::string(name); +#endif +} +static std::string addr_to_string(const void* addr) { + std::stringstream ss; + ss << addr; + return ss.str(); +} + +static std::string getBackTrace() { +#ifdef __GNUC__ string result; - void *trace[16]; - int trace_size = 0; + void *trace[16]; + int trace_size = 0; + trace_size = backtrace(trace, 16); + char **messages = backtrace_symbols(trace, trace_size); - trace_size = backtrace(trace, 16); + result = "[bt] Trace:\n"; - result = "[bt] Trace:\n"; + /* skip first stack frame (points here) */ + for (int i=2; i < trace_size; ++i) { + result += string("[bt] #") + std::to_string(i-1) + string(" "); - char **messages = backtrace_symbols(trace, trace_size); + Dl_info info; + if (dladdr(trace[i], &info) && info.dli_saddr) { + auto name = demangle(info.dli_sname); + string fname = info.dli_fname ? info.dli_fname: "[unknown file]"; + + result += fname + + + " " + + " [" + addr_to_string(info.dli_saddr) + "]" // exact address of symbol + + string(", in ") + + name; + } + else { + result += messages[i]; + } + result += "\n"; + } - /* skip first stack frame (points here) */ - for (int i=2; i<trace_size; ++i) { - //printf("[bt] #%d %s\n", i, messages[i]); - result += string("[bt] #") + std::to_string(i-1) + string(" ") + messages[i] + string("\n"); - } + free(messages); return result; +#elif _MSC_VER + return ""; #else return ""; #endif } exception::exception(const char *msg) : msg_(msg), processed_(false) { - trace_ = std::move(getBackTrace()); + trace_ = std::move(getBackTrace()); } exception::exception(const ftl::Formatter &msg) : msg_(msg.str()), processed_(false) { @@ -45,7 +89,7 @@ exception::exception(const ftl::Formatter &msg) : msg_(msg.str()), processed_(fa exception::~exception() { if (!processed_) { - LOG(ERROR) << "Unreported exception: " << what(); + LOG(ERROR) << "Unhandled exception: " << what(); LOG(ERROR) << trace_; } -} \ No newline at end of file +}