It appears there is a long-standing and quite nasty bug in GCC. I believe all versions of GCC which allow for reordering of basic-blocks are affected. In the example I attached, func has two epilogues, but the unwind info looks like this:
<func>: [0x0-0x1d0], info at +0x0 v1, flags=0x0 (), len=32 bytes R2:prologue_gr(mask=[rp,ar.pfs],grsave=r37,rlen=11) P7:pfs_when(t=0) P7:mem_stack_f(t=1,size=4096) P7:pr_when(t=2) P3:pr_gr(reg=r40) P7:lc_when(t=7) P3:lc_gr(reg=r41) P7:rp_when(t=10) R3:body(rlen=46) B1:label_state(label=1) B2:epilogue(t=1,ecount=0) R1:body(rlen=30) B1:copy_state(label=1) Note that there is only one "epilogue" directive. The stack-popping instruction in the second "body" region is not marked at all, meaning that the unwind info will be incorrect once the stack got popped in the second "body" region. It's easiest to reproduce this bug with a libunwind-enabled gdb: $ gcc -v 2>&1 | grep 'version' gcc version 3.4.1 $ gcc -O2 -Wall .test-ptrace-misc.c ident.c -o test-ptrace-misc $ gdb ./test-ptrace-misc (gdb) b 0x4000000000000aa2 # this should be the last instruction in func (gdb) r Starting program: /home/davidm/src/unwind/build-opt/tests/test-ptrace-misc Program received signal SIGUSR1, User defined signal 1. 0x20000000000ef042 in kill () from /lib/tls/libc.so.6.1 (gdb) c Continuing. Breakpoint 1, 0x4000000000000aa2 in func () (gdb) bt #0 0x4000000000000aa2 in func () #1 0x4000000000000970 in func () #2 0x4000000000002070 in bar () #3 0x0000000000000000 in ?? () #4 0x0000000000000000 in ?? () ...etc... (You can verify that gdb is picking up libunwind by starting it with environment variable LD_DEBUG set to "files"; you should see a line along the lines of: 16559: file=libunwind-ia64.so; generating link map while gdb is starting up.) To fix this bug, GCC should be emitting a ".restore sp" directive in front of every instruction which pops the stack-pointer. -- Summary: bad unwind info due to multiple returns (missing epilogue) Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P2 Component: target AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: davidm at hpl dot hp dot com CC: davidm at hpl dot hp dot com,gcc-bugs at gcc dot gnu dot org,wilson at gcc dot gnu dot org GCC build triplet: ia64-hp-linux GCC host triplet: ia64-hp-linux GCC target triplet: ia64-hp-linux http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18010