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/71951] libgcc_s built with -fomit-frame-pointer on aarch64 is broken


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71951

Wilco <wilco at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
   Last reconfirmed|                            |2017-07-28
                 CC|                            |wilco at gcc dot gnu.org
         Resolution|DUPLICATE                   |---
     Ever confirmed|0                           |1

--- Comment #13 from Wilco <wilco at gcc dot gnu.org> ---
(In reply to Icenowy Zheng from comment #12)
> (In reply to Wilco from comment #11)
> > (In reply to Icenowy Zheng from comment #10)
> > > In my environment (glibc 2.25, and both the building scripts of glibc and
> > > gcc have -fomit-frame-pointer automatically enabled), this bug is not fully
> > > resolved yet.
> > > 
> > > With GCC upgraded to 6.4.0, GDB debugger started to work correctly. (With
> > > GCC 6.3.0 GDB cannot even work and segfault at unwind code in libgcc).
> > > 
> > > However, if I still build GCC with -fomit-frame-pointer in CFLAGS, the
> > > backtrace() function of glibc cannot work, and segfault at line 240 of
> > > libgcc/unwind-dw2.c .
> > > 
> > > By reading the source code, I think the unwind code is still trying to get
> > > CFA from the register x29, and when debugging I found that the x29 register
> > > in the unwind context is 0 (because of -fomit-frame-pointer), so line 240 is
> > > dereferencing a NULL pointer, so it segfaulted.
> > > 
> > > Maybe the behavior that accessing x29 register to get CFA is not correct?
> > 
> > Well if everything built with -fomit-frame-pointer then it is definitely
> > wrong to read x29. Can you give more info similar to comment #3?
> 
> I didn't remember a lot as this issue is already fixed in our build system
> by removing -fomit-frame-pointer.
> 
> But I remember part of the stacktrace:
> 
> _Unwind_GetGR(index=29) at libgcc/unwind-dw2.c:240 <= segfault here
> _Unwind_GetPtr(index=29) at libgcc/unwind-dw2.c:251
> uw_update_context_1() at libgcc/unwind-dw2.c:1410
> _Unwind_Backtrace() at libgcc/unwind.inc (line number forgot)
> backtrace() in libc.so.6

Right, so it's trivial to reproduce since every call to backtrace will crash
immediately if libgcc is built with -fomit-frame-pointer in any GCC version.

The issue is due to the weird way the generic unwind code works - there is no
code to setup the frame pointer. So in order to unwind any function with a
frame pointer, the very first function that is unwound (_Unwind_Backtrace in
this case) must use the frame pointer. That way the frame pointer is restored
and its value can now be read by _Unwind_GetGR without crashing.

A quick workaround is:

#define LIBGCC2_UNWIND_ATTRIBUTE __attribute__((optimize
("no-omit-frame-pointer")))

Oddly enough I don't see any other targets do this, so this problem may be
widespread... Note this workaround wouldn't work if there could be multiple
frame pointers or several registers which may contain a frame pointer.

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