SIGSEGV in _Unwind_Backtrace when compiling with -fomit-frame-pointer

David Daney ddaney@caviumnetworks.com
Thu Jul 1 18:16:00 GMT 2010


On 07/01/2010 10:59 AM, Lukasz Lempart wrote:
> Hello,
>
> I am running into problems when unwinding the stack from a signal handler. The source code for my test application is included. Basically the application computes the Fibonacci sequence and a backtrace is triggered by SIGALRM every second.
>

Unwinding from asynchronous signal handlers (like SIGALRM) is not 
supported by default.  Synchronous signals like SIGSEGV should work.

The problem is that the metadata used by the unwinder is only present 
for instructions that could cause a Synchronous signal.

In theory, you might be able to pass -fasynchronous-unwind-tables to the 
compiler, but you would have to use it for all code in your program 
including any libraries that were used (like libc and libpthread).

David Daney


> I am running x86_64 Centos 4 on 2.6.9-67.ELsmp kernel and g++ version is 4.1.2-42.
>
> The application is compiled with:
>
> g++ -fomit-frame-pointer -o backtrace-test bactrace-test.cc
>
> I would like to know if anyone has come across a similar issue and if there are any solutions for this problem.
>
> Thank you in advance for your help.
>
> Best regards,
>
> Luke
>
> P.S. My brief analysis follows:
>
> (gdb) f 6
> #6  uw_frame_state_for (context=0x7fbfffd0b0, fs=<value optimized out>)
>      at ../../../libgcc/../gcc/config/i386/linux-unwind.h:51
> 51      ../../../libgcc/../gcc/config/i386/linux-unwind.h: No such file or directory.
>          in ../../../libgcc/../gcc/config/i386/linux-unwind.h
> (gdb) p $rip
> $36 = (void (*)()) 0x2a9578a11f<uw_frame_state_for+655>
> (gdb) disas
> ...
> 0x0000002a9578a115<uw_frame_state_for+645>:    xchg   %ax,%ax
> 0x0000002a9578a118<uw_frame_state_for+648>:    mov    0x98(%r13),%rdx
> 0x0000002a9578a11f<uw_frame_state_for+655>:    cmpb   $0x48,(%rdx)
> ...
>
> The problem is that the value in %rdx is 5.
>
> (gdb) x/20a 0x98 + $r13 - 8*10
> 0x7fbfffd0f8:   0x7fbffff1c0    0x7fbffff1c8
> 0x7fbfffd108:   0x7fbffff1d0    0x7fbffff1d8
> 0x7fbfffd118:   0x7fbffff1e0    0x7fbffff1e8
> 0x7fbfffd128:   0x7fbffff1f0    0x7fbffff3e0
> 0x7fbfffd138:   0x0     0x7fbffff3e8<-- this is what we want in %rdx
> 0x7fbfffd148:   0x5     0x0<-- this is what we get in %rdx
> 0x7fbfffd158:   0x0     0x0
> 0x7fbfffd168:   0x400708<_Z3fibi>       0x4000000000000000
> 0x7fbfffd178:   0x0     0x0
> 0x7fbfffd188:   0x0     0x0
>
> Looks like we are off by an 8 byte address because the actual location on the stack of the return address is in the previous memory location.
>
> (gdb) x/a 0x7fbffff3e8
> 0x7fbffff3e8:   0x40073f<_Z3fibi+55>



More information about the Gcc-help mailing list