[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#800900: hurd-i386: changeset from r6489 breaks SIGBUS handling



Hi,

I've reduced the testcase to the attached H5detect.c.
The behavior is different depending on whether we link with "-lpthread":

pini@exodar:~/tmp$ /usr/bin/gcc -o H5detect H5detect.c
pini@exodar:~/tmp$ ./H5detect
verify_signal_handlers for signal 10 did 5 tries. Found 2 failures and 3
successes
Signal handler sigbus_handler for signal 10 failed
pini@exodar:~/tmp$ /usr/bin/gcc -o H5detect H5detect.c -lpthread
pini@exodar:~/tmp$ ./H5detect
Bus error


If I comment out the fprintf statement line 60, both builds run fine.
o_O

Thanks,

_g.
#include <signal.h>
#include <setjmp.h>
#include <stdio.h>

static int sigbus_handler_called_g = 0;	/* how many times called */
static int signal_handler_tested_g = 0;	/* how many times tested */
static int verify_signal_handlers(int signum, void (*handler)(int));
static jmp_buf jbuf_g;

/*-------------------------------------------------------------------------
 * Function:	sigbus_handler
 *
 * Purpose:	Handler for SIGBUS. We use signal() instead of sigaction()
 *		because it's more portable to non-Posix systems. Although
 *		it's not nearly as nice to work with, it does the job for
 *		this simple stuff.
 *
 * Return:	Returns via H5LONGJMP to jbuf_g.
 *
 * Programmer:	Robb Matzke
 *		Thursday, March 18, 1999
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static void
sigbus_handler(int signo)
{
    /* Use sigprocmask to unblock the signal if sigsetjmp/siglongjmp are not */
    /* supported. */
    sigset_t set;

    sigemptyset(&set);
    sigaddset(&set, SIGBUS);
    sigprocmask(SIG_UNBLOCK, &set, NULL);

    sigbus_handler_called_g++;
    signal(SIGBUS, sigbus_handler);
    longjmp(jbuf_g, SIGBUS);
}


/* Verify the signal handler for signal signum works correctly multiple times.
 * One possible cause of failure is that the signal handling is blocked or
 * changed to SIG_DFL after H5LONGJMP.
 * Return  0 for success, -1 for failure.
 */
static int verify_signal_handlers(int signum, void (*handler)(int))
{						      
    void	(*save_handler)(int) = signal(signum, handler);    
    int i, val;
    int ntries=5;
    volatile int nfailures=0;
    volatile int nsuccesses=0;
									      
    for (i=0;i<ntries; i++){    
	val=setjmp(jbuf_g);
        /* Uncomment to succeed */
        /* fprintf(stderr, "===> blah\n"); */
	if (val==0)
	{    
	    /* send self the signal to trigger the handler */    
	    signal_handler_tested_g++;
	    raise(signum);    
	    /* Should not reach here. Record error. */
	    nfailures++;
	}else{
	    if (val==signum){ 
		/* return from signum handler. Record a sucess. */
		nsuccesses++;
	    }else{
		fprintf(stderr, "Unknown return value (%d) from setjmp",
		    val);    
		nfailures++;
	    }
	}
    }    
    /* restore save handler, check results and report failures */
    signal(signum, save_handler);
    if (nfailures>0 || nsuccesses != ntries){
	fprintf(stderr, "verify_signal_handlers for signal %d did %d tries. "
	       "Found %d failures and %d successes\n",
	       signum, ntries, nfailures, nsuccesses);
	return(-1);
    }else{
	/* all succeeded */
	return(0);
    }
}    

/*-------------------------------------------------------------------------
 * Function:	main
 *
 * Purpose:	Main entry point.
 *
 * Return:	Success:	exit(0)
 *
 *		Failure:	exit(1)
 *
 * Programmer:	Robb Matzke
 *		matzke@llnl.gov
 *		Jun 12, 1996
 *
 * Modifications:
 *	Albert Cheng, 2004/05/20
 *	Some compilers, e.g., Intel C v7.0, took a long time to compile
 *      with optimization when a module routine contains many code lines.
 *      Divide up all those types detections macros into subroutines, both
 *      to avoid the compiler optimization error and cleaner codes.
 *
 *-------------------------------------------------------------------------
 */
int
main(void)
{
    /* verify the SIGBUS and SIGSEGV handlers work properly */
    if (verify_signal_handlers(SIGBUS, sigbus_handler) != 0) {
        fprintf(stderr, "Signal handler %s for signal %d failed\n",
                "sigbus_handler", SIGBUS);
    }
    return 0;
}

Attachment: signature.asc
Description: OpenPGP digital signature


Reply to: