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>