This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/40466] New: uw_frame_state_for can segfault when called by _Unwind_Backtrace from asynchronous signal handler
- From: "rkrische at uwaterloo dot ca" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 16 Jun 2009 20:20:15 -0000
- Subject: [Bug target/40466] New: uw_frame_state_for can segfault when called by _Unwind_Backtrace from asynchronous signal handler
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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