It appears that my initial analysis was not completely correct. The signal handlers are working, sort of. The first SIGBUS which the program gets is handled correctly, and then control is returned back to the program, however second one is not trapped and delivered to the program, which kills it. I don't know enough about the subtleties of signal handling in C (and it appears that there is an awful lot of them), but I've ran into the following piece of information while reading about it:
"On systems that support signal handling, POSIX.1 does not specify whether setjmp and longjmp save or restore the current set of blocked signals - if a program employs signal handling it should use POSIX's sigsetjmp/siglongjmp." [0] As we are handling signals, it appears that sigsetjmp/siglongjmp are the right thing to use, instead of their sig-less counterparts. I was able to come up with a simple test case (attached) which demonstrates the problem: while I would expect both SIGBUS'es to be caught by the handler, that's what I see on sparc when I run it: [EMAIL PROTECTED]:/tmp# ./a.out Caught signal 10 Back at setjmp #1 Bus error Replacing setjmp/longjump with sigsetjmp/siglongjump makes program to behave correctly. I've tried doing it for H5detect.c (using the attached patch) and the problem is now gone, H5detect runs fine and H5Tinit.c is generated successfully. Unfortunately, the build now fails in a different place: [ 77%] Building CXX object Servers/ServerManager/CMakeFiles/vtkPVServerManager.dir/vtkSMCameraManipulatorProxy.o [ 77%] Building CXX object Servers/ServerManager/CMakeFiles/vtkPVServerManager.dir/vtkSMCameraProxy.o In file included from /usr/include/stdio.h:903, from /usr/include/c++/4.3/cstdio:50, from /usr/include/c++/4.3/bits/char_traits.h:48, from /usr/include/c++/4.3/ios:46, from /usr/include/c++/4.3/ostream:45, from /usr/include/c++/4.3/iostream:45, from /tmp/paraview-3.2.3/VTK/Common/vtkIOStream.h:35, from /tmp/paraview-3.2.3/VTK/Common/vtkSystemIncludes.h:40, from /tmp/paraview-3.2.3/VTK/Common/vtkIndent.h:24, from /tmp/paraview-3.2.3/VTK/Common/vtkObjectBase.h:43, from /tmp/paraview-3.2.3/VTK/Common/vtkObject.h:41, from /tmp/paraview-3.2.3/Servers/ServerManager/vtkSMObject.h:24, from /tmp/paraview-3.2.3/Servers/ServerManager/vtkSMProxy.h:123, from /tmp/paraview-3.2.3/Servers/ServerManager/vtkSMCameraProxy.h:23, from /tmp/paraview-3.2.3/Servers/ServerManager/vtkSMCameraProxy.cxx:15: /usr/include/bits/stdio.h: In function 'int putchar_unlocked(int)': /usr/include/bits/stdio.h:108: error: expected primary-expression before 'unsigned' /usr/include/bits/stdio.h:108: error: expected `)' before 'unsigned' /usr/include/bits/stdio.h:108: error: expected `)' before ';' token make[3]: *** [Servers/ServerManager/CMakeFiles/vtkPVServerManager.dir/vtkSMCameraProxy.o] Error 1 make[3]: Leaving directory `/tmp/paraview-3.2.3/obj-sparc-linux-gnu' make[2]: *** [Servers/ServerManager/CMakeFiles/vtkPVServerManager.dir/all] Error 2 make[2]: Leaving directory `/tmp/paraview-3.2.3/obj-sparc-linux-gnu' make[1]: *** [all] Error 2 make[1]: Leaving directory `/tmp/paraview-3.2.3/obj-sparc-linux-gnu' make: *** [debian/stamp-makefile-build] Error 2 I'll try to investigate what happens here. [0] http://en.wikipedia.org/wiki/Longjmp Cheers. -- Jurij Smakov [EMAIL PROTECTED] Key: http://www.wooyd.org/pgpkey/ KeyID: C99E03CC
#include <stdio.h> #include <signal.h> #include <setjmp.h> sigjmp_buf blah; void my_handler(int signum) { signal(SIGBUS, my_handler); printf("Caught signal %d\n", signum); longjmp(blah, 1); } int main() { char c[2]; int i; void *p; signal(SIGBUS, my_handler); if(setjmp(blah)) { printf("Back at setjmp #1\n"); } else { p = (void *) &c[1]; i = *(int *)p; } if(setjmp(blah)) { printf("Back at setjmp #2\n"); } else { p = (void *) &c[1]; i = *(int *)p; } }
diff -aur paraview-3.2.3.orig/Utilities/hdf5/H5detect.c paraview-3.2.3/Utilities/hdf5/H5detect.c --- paraview-3.2.3.orig/Utilities/hdf5/H5detect.c 2007-01-15 15:44:26.000000000 +0000 +++ paraview-3.2.3/Utilities/hdf5/H5detect.c 2008-08-27 23:34:07.000000000 +0000 @@ -106,7 +106,7 @@ static void detect_C99_integers64(void); static void detect_alignments(void); static size_t align_g[] = {1, 2, 4, 8, 16}; -static jmp_buf jbuf_g; +static sigjmp_buf jbuf_g; /*------------------------------------------------------------------------- @@ -360,7 +360,7 @@ void (*_handler2)(int) = signal(SIGSEGV, sigsegv_handler); \ \ _buf = (char*)malloc(sizeof(TYPE)+align_g[NELMTS(align_g)-1]); \ - if (setjmp(jbuf_g)) _ano++; \ + if (sigsetjmp(jbuf_g, 1)) _ano++; \ if (_ano<NELMTS(align_g)) { \ *((TYPE*)(_buf+align_g[_ano])) = _val; /*possible SIGBUS or SEGSEGV*/ \ _val2 = *((TYPE*)(_buf+align_g[_ano])); /*possible SIGBUS or SEGSEGV*/ \ @@ -376,7 +376,7 @@ memcpy(_buf+align_g[_ano]+(INFO.offset/8),((char *)&_val)+(INFO.offset/8),(size_t)(INFO.precision/8)); \ _val2 = *((TYPE*)(_buf+align_g[_ano])); \ if(_val!=_val2) \ - longjmp(jbuf_g, 1); \ + siglongjmp(jbuf_g, 1); \ /* End Cray Check */ \ (INFO.align)=align_g[_ano]; \ } else { \ @@ -460,7 +460,7 @@ sigsegv_handler(int UNUSED signo) { signal(SIGSEGV, sigsegv_handler); - longjmp(jbuf_g, 1); + siglongjmp(jbuf_g, 1); } @@ -485,7 +485,7 @@ sigbus_handler(int UNUSED signo) { signal(SIGBUS, sigbus_handler); - longjmp(jbuf_g, 1); + siglongjmp(jbuf_g, 1); }