K 2.6 test6 strange signal behaviour

From: Ken Foskey
Date: Mon Oct 20 2003 - 08:07:31 EST



I have a problem with signals.

I get multiple signals from a single execution of the program. I have
attached a stripped source. Here is the critical snippet, you can see
the signal handler being set before each call:

signal( SIGSEGV, SignalHdl );
signal( SIGBUS, SignalHdl );
fprintf( stderr, "Running \n" );
result = func( eT, p );
fprintf( stderr, "Finished \n" );
signal( SIGSEGV, SIG_DFL );
signal( SIGBUS, SIG_DFL );

When I run the code, that does 2 derefs of NULL you will see 2 instances
of "Running" and the handler is not invoked at all for the second time.

./solar:


Getting from NULL
Setting Jump
Running
Signal 11 caught
After jump
Setting to NULL
Setting Jump
Running
Segmentation fault

I am running debian version of K 2.6 test6. This has occurred on all
versions of K2.6 though, not specific.

--
Thanks
KenF
OpenOffice.org developer
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>

/*************************************************************************
|* Typdeclarations for memory access test functions
*************************************************************************/
typedef int (*TestFunc)( void* );

/*************************************************************************
*************************************************************************/
static jmp_buf check_env;
static int bSignal;
static void SignalHdl( int sig )
{
bSignal = 1;

fprintf( stderr, "Signal %d caught\n", sig );
longjmp( check_env, sig );
}

/*************************************************************************
*************************************************************************/
void check( TestFunc func, void* p )
{
int result;

fprintf( stderr, "Setting Jump\n" );
if ( !setjmp( check_env ) )
{
signal( SIGSEGV, SignalHdl );
signal( SIGBUS, SignalHdl );
fprintf( stderr, "Running \n" );
result = func( p );
fprintf( stderr, "Finished \n" );
signal( SIGSEGV, SIG_DFL );
signal( SIGBUS, SIG_DFL );
}
fprintf( stderr, "After jump \n" );
}

/*************************************************************************
*************************************************************************/
static int GetAtAddress( void* p )
{
return *((char*)p);
}

/*************************************************************************
*************************************************************************/
static int SetAtAddress( void* p )
{
return *((char*)p) = 0;
}

/*************************************************************************
*************************************************************************/
void CheckGetAccess( void* p )
{
check( (TestFunc)GetAtAddress, p );
}
/*************************************************************************
*************************************************************************/
void CheckSetAccess( void* p )
{
check( (TestFunc)SetAtAddress, p );
}

/*************************************************************************
*************************************************************************/
int main( int argc, char* argv[] )
{
{
char* p = NULL;
fprintf( stderr, "Getting from NULL\n" );
CheckGetAccess( p );
fprintf( stderr, "Setting to NULL\n" );
CheckSetAccess( p );
fprintf( stderr, "After Setting to NULL\n" );
}

exit( 0 );
}