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

Reply via email to