diff --git a/include/lib/graft/backtrace.h b/include/lib/graft/backtrace.h index c2899ef2..b73f0d06 100644 --- a/include/lib/graft/backtrace.h +++ b/include/lib/graft/backtrace.h @@ -3,6 +3,10 @@ #include #ifdef __cplusplus + +#include +std::string graft_bt_str(); + extern "C" { #endif void graft_bt(); diff --git a/src/lib/graft/backtrace.cpp b/src/lib/graft/backtrace.cpp index 0fcbb699..98370736 100644 --- a/src/lib/graft/backtrace.cpp +++ b/src/lib/graft/backtrace.cpp @@ -28,6 +28,72 @@ typedef struct { sigset_t uc_sigmask; } sig_ucontext_t; +#ifdef __cplusplus + +std::string graft_bt_str() +{ + void *trace[TRACE_SIZE_MAX]; + char **messages = (char **) NULL; + + char *funcname = (char*) malloc(FUNC_NAME_SIZE_MAX); + int i, trace_size = backtrace(trace, TRACE_SIZE_MAX); + + if (trace_size == 0) + { + return "\t\n"; + } + + std::ostringstream oss; + + messages = backtrace_symbols(trace, trace_size); + for (i = 1; i < trace_size && messages; ++i) + { + char *begin_name = NULL, *begin_offset = NULL, *end_offset = NULL, *p; + for (p = messages[i]; *p; ++p) + { + if (*p == '(') + begin_name = p; + else if (*p == '+') + begin_offset = p; + else if (*p == ')' && begin_offset) { + end_offset = p; + break; + } + } + + if (begin_name && begin_offset && end_offset && begin_name < begin_offset) + { + int status; + size_t funcnamesize = FUNC_NAME_SIZE_MAX; + + *begin_name++ = '\0'; + *begin_offset++ = '\0'; + *end_offset = '\0'; + + p = abi::__cxa_demangle(begin_name, funcname, &funcnamesize, &status); + if (status == 0) + { + funcname = p; + oss << "\t#" << i << " " << messages[i] << " : " << funcname << "+" << begin_offset << "\n"; + } + else + { + oss << "\t#" << i << " " << messages[i] << " : " << begin_name << "()+" << begin_offset << "\n"; + } + } + else + { + oss << "\t#" << i << " " << messages[i] << "\n"; + } + } + free(messages); + free(funcname); + + return oss.str(); +} + +#endif //__cplusplus + void graft_bt() { void *trace[TRACE_SIZE_MAX]; diff --git a/src/supernode/main.cpp b/src/supernode/main.cpp index e886ea3c..7832ef0b 100644 --- a/src/supernode/main.cpp +++ b/src/supernode/main.cpp @@ -15,8 +15,9 @@ std::terminate_handler prev_terminate = nullptr; // the workflow, the error propagates back to the client. void terminate() { - std::cerr << "\nTerminate called, dump stack:\n"; - graft_bt(); + std::ostringstream oss; + oss << "\nTerminate called, dump stack:\n"; + oss << graft_bt_str(); //dump exception info std::exception_ptr eptr = std::current_exception(); @@ -28,14 +29,17 @@ void terminate() } catch(std::exception& ex) { - std::cerr << "\nTerminate caused by exception : '" << ex.what() << "'\n"; + oss << "\nTerminate caused by exception : '" << ex.what() << "'\n"; } catch(...) { - std::cerr << "\nTerminate caused by unknown exception.\n"; + oss << "\nTerminate caused by unknown exception.\n"; } } + LOG_ERROR("") << oss.str(); + std::cerr << oss.str(); + prev_terminate(); } @@ -54,12 +58,6 @@ int main(int argc, const char** argv) } catch (const graft::exit_error& e) { LOG_ERROR("The program is terminated because of error: ") << e.what(); return -1; - } catch (const std::exception & e) { - LOG_ERROR("Exception thrown: ") << e.what(); - throw; - } catch(...) { - LOG_ERROR("Exception of unknown type!"); - throw; } return 0;