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