This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/40466] New: uw_frame_state_for can segfault when called by _Unwind_Backtrace from asynchronous signal handler


I need to walk the stack from within an asynchronous signal handler, and every
once in a while, the program crashes in uw_frame_state_for. I know that
unwinding through a signal handler is 'discouraged', and that proper unwinding
information may not always be there, but the unwinder should fail gracefully if
that is indeed the case and not crash the program.

See the test program below for reproducing this bug. Dynamic memory allocation
may be involved as the new/delete seems to be required to trigger the issue (at
least in the test program).

On x86-64, this problem affects at least 
  gcc-4.0.3, gcc-4.1.1, gcc-4.2.1, gcc-4.2.4-1ubuntu3, and  gcc-4.3.2

I have not been able to reproduce it on i486, ia64, or sparc-solaris.

----
Config:

Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ../src/configure --prefix=/u/usystem/software/gcc/gcc-4.3.2
--enable-languages=c,c++ --with-gmp=/u/usystem/software/gcc/gmp-4.2.4
--with-mpfr=/u/usystem/software/gcc/mpfr-2.3.2
Thread model: posix
gcc version 4.3.2 (GCC)

libc6:

2.7-10ubuntu4 

Kernel:

Linux 2.6.24-23-generic #1 SMP Wed Apr 1 21:43:24 UTC 2009 x86_64 GNU/Linux

------
%%%%%%
------

/* sigunwind.cc

   compile: g++ sigunwind.cc
   run:     ./a.out  
*/


#include <signal.h>
#include <sys/time.h>
#include <unwind.h>
#include <ucontext.h>
#include <stdlib.h>

#define __U_SIGCXT__ ucontext_t *
#define __U_SIGPARMS__ int sig, siginfo_t *sfp, __U_SIGCXT__ cxt

int main();

typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)
     (struct _Unwind_Context *, void *);

extern "C" _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *);


static _Unwind_Reason_Code extfn ( _Unwind_Context *context, void * arg ) {
    int i;
    void * rs = (void *)_Unwind_GetRegionStart(context);

    if ( rs == main ) {                 // if we go all the way through to main
        return _URC_HANDLER_FOUND;      // just stop unwinding
    } // if

    return _URC_NO_REASON;

}

void backtrace() {
     _Unwind_Reason_Code ret = _Unwind_Backtrace( extfn, NULL );
}

void rec( int i ) {
    if ( i <= 0 )
        return;
    int *b = new int;
    rec( i - 1 );
    delete b;
  }


void doit( __U_SIGPARMS__ ) {
        backtrace();
}


int main() {
    itimerval it;
    struct sigaction act;

    //set up signal handler
    act.sa_sigaction = (void (*)(int, siginfo_t*, void*))doit;
    sigemptyset( &act.sa_mask );
    sigaddset( &act.sa_mask, SIGALRM );         // disable during signal
handler
    sigaddset( &act.sa_mask, SIGVTALRM );
    act.sa_flags = SA_SIGINFO;


    if ( sigaction( SIGALRM, &act, NULL ) == -1 ) 
        exit( -1 );

    //set up alarm 
    it.it_interval.tv_sec = 0;
    it.it_interval.tv_usec = 50000;
    it.it_value.tv_sec = 0;   
    it.it_value.tv_usec = 50000;

    setitimer( ITIMER_REAL, &it, NULL ); 

    for ( ; ; ) {
        rec(10);                                // run until crash
    }

}


-- 
           Summary: uw_frame_state_for can segfault when called by
                    _Unwind_Backtrace from asynchronous signal handler
           Product: gcc
           Version: 4.3.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: rkrische at uwaterloo dot ca
GCC target triplet: x86_64-unknown-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40466


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]