This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/18010] New: bad unwind info due to multiple returns (missing epilogue)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]