// g++-8 -g -O1 -o exception5 exception5.cpp #include #include #include #include #include #include #include #include int main2(); /* Obtain a backtrace and print it to stdout. https://www.gnu.org/software/libc/manual/html_node/Backtraces.html */ void print_trace(void) { void * array[10]; memset(array, 0, sizeof(array)); const int size = backtrace (array, 10); char **strings = backtrace_symbols (array, size); // extract the exe name std::string exe; if(size > 0) { exe = strings[0]; const size_t s = exe.find("("); if(std::string::npos != s) { exe.erase(s, exe.length()); } } //printf ("Obtained %zd stack frames.\n", size); printf("\nBacktrace:\n"); // skip first, as it is this handler for (int i = 0; i < size; i++) { if(0 != i) { printf("\n"); } printf("[%d]: %s\n", i, strings[i]); // extract the address, search for "+0x" std::string addr(strings[i]); // skip any line that does not include the exe name if(std::string::npos == addr.find(exe)) { //printf("Skip as no [%s] in this stack\n", exe.c_str()); addr.clear(); } else { size_t s = addr.find("+0x"); if(std::string::npos != s) { // Move past the "+" ++s; addr.erase(0, s); s = addr.find(")"); if(std::string::npos != s) { addr.erase(s, addr.length()); } } } //printf("exe '%s' addr '%s' array '%p'\n", exe.c_str(), addr.c_str(), array[i]); if(!addr.empty()) { char syscom[256]; // -p -a sprintf(syscom,"addr2line -s -f -C -e %s %s", exe.c_str(), addr.c_str()); //printf("%s\n", syscom); int result = system(syscom); if(0 != result) { printf("system [%s] result: %d\n", syscom, result); } } } free (strings); raise(SIGSEGV); } void test() { try { main2(); } catch( const std::exception &e) { const bool use_printf = true; if(use_printf) { printf("Unhandled C++ exception: [%s]\n", e.what()); } else { const std::string what(e.what()); std::cout << "Unhandled C++ exception: [" << e.what() << "]\n"; } print_trace(); } } int main() { test(); } int main2() { std::vector v; return v.at(0); }