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