/* This program crashes inside libunwind (the exact stack trace will vary): #0 access_mem (as=0x1572a0, addr=5, val=0xbfbfcfd8, write=0, arg=0xbfbfd240) at x86/Ginit.c:116 #1 0x001504b3 in _Ux86_is_signal_frame (cursor=0xbfbfd044) at x86/Gis_signal_frame.c:60 #2 0x00150ec5 in _Ux86_step (cursor=0xbfbfd044) at x86/Gstep.c:54 #3 0x080486bb in signal_handler () #4 #5 0x080486f3 in fib2 () #6 0x00000005 in ?? () #7 0x0804870c in fib4 () #8 0x08048737 in fib6 () #9 0x0804875b in fib8 () #10 0x08048766 in fib9 () #11 0x08048778 in fib10 () #12 0x0804878a in fib11 () #13 0x080487b5 in fib13 () .... The fact that gdb thinks frame 6 is wierd makes me suspect gcc has emited bogus unwind info? When compiled with: gcc -Wall -Werror -fasynchronous-unwind-tables -fomit-frame-pointer -o unwind-test unwind-test.o /usr/lib/libunwind.so /usr/lib/libunwind-x86.so */ #include #include #include #include #include #include #define CHECK(s) check(s, #s "\n") static int check (int s, const char * w) { if (s >= 0) return s; write (2, w, strlen (w)); abort(); } static void signal_handler (int signal, siginfo_t * info, void * p) { unw_context_t context; CHECK (unw_getcontext (&context)); unw_cursor_t cursor; CHECK (unw_init_local (&cursor, &context)); do { } while (CHECK (unw_step (&cursor)) > 0); } /* A whole load of dummy functions to chew up CPU and stack space. */ int fib0 (void) { return 0; } int fib1 (void) { return 1; } #define FIB(A,B,C) int A (void) { return B() + C(); } FIB(fib2,fib1,fib0) FIB(fib3,fib2,fib1) FIB(fib4,fib3,fib2) FIB(fib5,fib4,fib3) FIB(fib6,fib5,fib4) FIB(fib7,fib6,fib5) FIB(fib8,fib7,fib6) FIB(fib9,fib8,fib7) FIB(fib10,fib9,fib8) FIB(fib11,fib10,fib9) FIB(fib12,fib11,fib10) FIB(fib13,fib12,fib11) FIB(fib14,fib13,fib12) FIB(fib15,fib14,fib13) FIB(fib16,fib15,fib14) FIB(fib17,fib16,fib15) FIB(fib18,fib17,fib16) FIB(fib19,fib18,fib17) FIB(fib20,fib19,fib18) FIB(fib21,fib20,fib19) FIB(fib22,fib21,fib20) FIB(fib23,fib22,fib21) FIB(fib24,fib23,fib22) FIB(fib25,fib24,fib23) FIB(fib26,fib25,fib24) FIB(fib27,fib26,fib25) FIB(fib28,fib27,fib26) FIB(fib29,fib28,fib27) FIB(fib30,fib29,fib28) FIB(fib31,fib30,fib29) FIB(fib32,fib31,fib30) FIB(fib33,fib32,fib31) FIB(fib34,fib33,fib32) FIB(fib35,fib34,fib33) FIB(fib36,fib35,fib34) FIB(fib37,fib36,fib35) FIB(fib38,fib37,fib36) FIB(fib39,fib38,fib37) FIB(fib40,fib39,fib38) FIB(fib41,fib40,fib39) FIB(fib42,fib41,fib40) FIB(fib43,fib42,fib41) FIB(fib44,fib43,fib42) FIB(fib45,fib44,fib43) FIB(fib46,fib45,fib44) FIB(fib47,fib46,fib45) FIB(fib48,fib47,fib46) FIB(fib49,fib48,fib47) FIB(fib50,fib49,fib48) FIB(fib51,fib50,fib49) int main() { /* Get SIGPROF to run our signal handler. */ struct sigaction action; memset (&action, 0, sizeof action); action.sa_sigaction = signal_handler; action.sa_flags = SA_RESTART | SA_SIGINFO; sigemptyset (&action.sa_mask); sigaction (SIGPROF, &action, NULL); struct itimerval timer; /* Fire 500 times / second. */ timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 2000; timer.it_value .tv_sec = 0; timer.it_value .tv_usec = 2000; setitimer (ITIMER_PROF, &timer, NULL); printf ("%i\n", fib43()); return 0; }