// #define UNW_LOCAL_ONLY #include #include #include #include #include #include __attribute__((noinline)) void unw(void) { printf("Unwinding.\n"); unw_context_t context; memset(&context, 0, sizeof(context)); unw_getcontext(&context); unw_cursor_t cursor; if (unw_init_local(&cursor, &context) != 0) { printf("Init failed\n"); return; } while (1) { unw_word_t reg; if (unw_get_reg(&cursor, UNW_REG_IP, ®) < 0) { printf("Can't get RIP\n"); return; } // printf(" RIP: %p\n", (void*)(uintptr_t)reg); /* reg--; */ backtrace_symbols_fd((void *const*)®, 1, 1); /* if (unw_get_reg(&cursor, UNW_REG_SP, ®) < 0) { */ /* printf("Can't get RSP\n"); */ /* return; */ /* } */ /* printf("RSP: %p\n", (void*)(uintptr_t)reg); */ if (unw_step(&cursor) <= 0) { printf("Done\n"); return; } } } jmp_buf start; __attribute__((noinline,noreturn)) void throw(void *p, void *p2, void *p3, void *p4, int a) { unw(); asm volatile ("" :: "r"(p), "r"(p2), "r"(p3), "r"(p4) : "memory"); if (a) { longjmp(start, 1); } else { _exit(0); } } __attribute__((noinline)) void not_throw(void *p) { /* unw(); */ asm volatile ("" :: "r"(p) : "memory"); } __attribute__((noinline)) void f(int a, int b) { if (a) { uint32_t p = a; not_throw(&p); throw(&p, &a, &b, &p, a); } else { not_throw(&a); int p = 2; throw(&b, &p, &a, &b, a); } } __attribute__((noinline)) void g(int a, int b) { f(a, b - a); } __attribute__((noinline)) void h(int a, int b) { g(a + b, -a); } volatile int flag = 1; volatile int flag2 = 0; int main() { if (setjmp(start) == 0) { h(flag, flag2); } else { h(0, flag2); } return 0; }