#include #include #include #define UNW_LOCAL_ONLY #include void my_unw_step_and_print_stack_native(void * a_uc) { unw_cursor_t temp_cursor; unw_word_t temp_ip, temp_sp; ucontext_t* temp_a_uc = (ucontext_t*) a_uc; unw_init_local(&temp_cursor, temp_a_uc); unw_set_reg(&temp_cursor, UNW_REG_IP, 1); std::cout << "\nStack Trace -----> \n"; while (unw_step(&temp_cursor) > 0) { unw_get_reg(&temp_cursor, UNW_REG_IP, &temp_ip); unw_get_reg(&temp_cursor, UNW_REG_SP, &temp_sp); char buffer[100]; unw_word_t offset, *poffset; poffset = &offset; unw_get_proc_name(&temp_cursor, (char *)buffer, 99, poffset); printf ("temp_ip = %lx, temp_sp = %lx, procedure--> %s\n", (long) temp_ip, (long) temp_sp, buffer); } std::cout << "\n\n"; } void bail(){ std::cout << "\nInside bail ()\n"; void (*fp)() = NULL; fp(); } void foo () { std::cout << "\nInside foo ()\n"; bail(); } void foo1() { std::cout << "\nInside foo1()"; foo (); } void foo2() { std::cout << "\nInside foo2()"; foo1(); } void foo3() { std::cout << "\nInside foo3()"; foo2(); } void foo4() { std::cout << "\nInside foo4()"; foo3(); } void foo5() { std::cout << "\nInside foo5()"; foo4(); } void foo6() { std::cout << "\nInside foo6()"; foo5(); } void foo7() { std::cout << "\nInside foo7()"; foo6(); } void foo8() { std::cout << "\nInside foo8()"; foo7(); } void foo9() { std::cout << "\nInside foo9()"; foo8(); } void segv_handler (int signum, siginfo_t* info, void *old_context){ std::cout << "\nInside segv_handler\n"; //Let OS supply context my_unw_step_and_print_stack_native(old_context); std::cout << "\n\nBAILING...\n\n"; //Bail on SIGSEGV default bahavior signal(SIGSEGV, SIG_DFL); } void test_signal_handler(int signum){ std::cout << "\nInside test_signal_handler. I should not be here...\n"; //Bail on SIGSEGV (default behavior) signal(SIGSEGV, SIG_DFL); } int main(){ struct sigaction new_sigaction, old_sigaction; new_sigaction.sa_sigaction = segv_handler; new_sigaction.sa_flags = SA_SIGINFO; sigemptyset (&new_sigaction.sa_mask); sigaddset(&new_sigaction.sa_mask, SIGSEGV); sigaction (SIGSEGV, NULL, &new_sigaction); if (old_sigaction.sa_handler != SIG_IGN){ new_sigaction.sa_handler = test_signal_handler; new_sigaction.sa_sigaction = segv_handler; sigaction (SIGSEGV, &new_sigaction, &old_sigaction); } foo9(); return 0; }