> -----Original Message----- > From: David Daney [mailto:ddaney@xxxxxxxxxxxxxxxxxx] > Sent: Thursday, July 01, 2010 11:17 AM > To: Lukasz Lempart > Cc: gcc-help@xxxxxxxxxxx > Subject: Re: SIGSEGV in _Unwind_Backtrace when compiling with -fomit- > frame-pointer > > 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 > Thanks David for the quick response. Looks like I'll have to explore other options. > > > 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>