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