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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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>



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux