This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/18010] New: bad unwind info due to multiple returns (missing epilogue)
- From: "davidm at hpl dot hp dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 15 Oct 2004 11:14:20 -0000
- Subject: [Bug target/18010] New: bad unwind info due to multiple returns (missing epilogue)
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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