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);
}