[Gc] GC under FreeBSD does not forward SIGSEGV to SA_SIGINFO handler

Andrew Gray andrew.gray at anu.edu.au
Sun Apr 18 02:42:24 PDT 2004


Hi,

Further to my previous message, I have written a patch against
gc6.3alpha5 to fix the problem with SIGSEGV not being forwarded
correctly to an SA_SIGINFO handler under FreeBSD.  The patch is
attached to this message.

As well as the changes to fix the bug, the patch changes the name and
usage of the SIGINFO #define.  This was done partly to avoid a clash
with a SIGINFO #define via the FreeBSD signal.h file.  Previously the
second argument in the SA_SIGINFO prototype was "struct SIGINFO", it
is now "SIGINFO_T".  This change also avoids refering to the
undocumented "__siginfo" structure tag.

The test program in the attached sigsegvtest.c file was used to
confirm that the patch fixes the problem.  The output using
gc6.3alpha5 under FreeBSD 4.8 was:

Caught fault
sig = 11
info = 0000000c

The output using gc6.3alpha5 with the patch applied was:

Caught fault
sig = 11
info = bfbffa60
info->si_code = 12

The only other testing I have done on the patch was the "make check"
test under FreeBSD 4.8, which passed.

Please consider including this patch with future versions of GC.
Please let me know if any further testing or changes to the patch
would useful.  Thanks.

--
Andrew Gray, Research Programmer
Department of Computer Science, FEIT
The Australian National University
-------------- next part --------------
diff -ur gc6.3alpha5/include/private/gcconfig.h gc6.3alpha5patch/include/private/gcconfig.h
--- gc6.3alpha5/include/private/gcconfig.h	Tue Mar 23 11:41:50 2004
+++ gc6.3alpha5patch/include/private/gcconfig.h	Sat Apr 17 23:57:11 2004
@@ -1907,6 +1907,10 @@
 #   define SUNOS5SIGS
 # endif
 
+# if defined(FREEBSD) && (__FreeBSD__ >= 4)
+#   define SUNOS5SIGS
+# endif
+
 # if defined(SVR4) || defined(LINUX) || defined(IRIX5) || defined(HPUX) \
 	    || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
 	    || defined(DGUX) || defined(BSD) || defined(SUNOS4) \
diff -ur gc6.3alpha5/os_dep.c gc6.3alpha5patch/os_dep.c
--- gc6.3alpha5/os_dep.c	Tue Mar 30 09:27:20 2004
+++ gc6.3alpha5patch/os_dep.c	Sun Apr 18 18:17:12 2004
@@ -129,7 +129,7 @@
 
 #ifdef UNIX_LIKE
 # include <fcntl.h>
-# ifdef SUNOS5SIGS
+# if defined(SUNOS5SIGS) && !defined(FREEBSD)
 #  include <sys/siginfo.h>
 # endif
   /* Define SETJMP and friends to be the version that restores	*/
@@ -2225,9 +2225,9 @@
 # endif /* !DARWIN */
 # endif /* MSWIN32 || MSWINCE || DARWIN */
 
-#if defined(SUNOS4) || defined(FREEBSD)
+#if defined(SUNOS4) || (defined(FREEBSD) && !defined(SUNOS5SIGS))
     typedef void (* SIG_PF)();
-#endif /* SUNOS4 || FREEBSD */
+#endif /* SUNOS4 || (FREEBSD && !SUNOS5SIGS) */
 
 #if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX) \
     || defined(HURD)
@@ -2254,13 +2254,13 @@
 #endif /* IRIX5 || OSF1 || HURD */
 
 #if defined(SUNOS5SIGS)
-# ifdef HPUX
-#   define SIGINFO __siginfo
+# if defined(HPUX) || defined(FREEBSD)
+#   define SIGINFO_T siginfo_t
 # else
-#   define SIGINFO siginfo
+#   define SIGINFO_T struct siginfo
 # endif
 # ifdef __STDC__
-    typedef void (* REAL_SIG_PF)(int, struct SIGINFO *, void *);
+    typedef void (* REAL_SIG_PF)(int, SIGINFO_T *, void *);
 # else
     typedef void (* REAL_SIG_PF)();
 # endif
@@ -2356,7 +2356,7 @@
 
 /*ARGSUSED*/
 #if !defined(DARWIN)
-# if defined (SUNOS4) || defined(FREEBSD)
+# if defined (SUNOS4) || (defined(FREEBSD) && !defined(SUNOS5SIGS))
     void GC_write_fault_handler(sig, code, scp, addr)
     int sig, code;
     struct sigcontext *scp;
@@ -2371,7 +2371,7 @@
 #     define SIG_OK (sig == SIGBUS)
 #     define CODE_OK (code == BUS_PAGE_FAULT)
 #   endif
-# endif /* SUNOS4 || FREEBSD */
+# endif /* SUNOS4 || (FREEBSD && !SUNOS5SIGS) */
 
 # if defined(IRIX5) || defined(OSF1) || defined(HURD)
 #   include <errno.h>
@@ -2413,11 +2413,11 @@
 
 # if defined(SUNOS5SIGS)
 #  ifdef __STDC__
-    void GC_write_fault_handler(int sig, struct SIGINFO *scp, void * context)
+    void GC_write_fault_handler(int sig, SIGINFO_T *scp, void * context)
 #  else
     void GC_write_fault_handler(sig, scp, context)
     int sig;
-    struct SIGINFO *scp;
+    SIGINFO_T *scp;
     void * context;
 #  endif
 #   ifdef HPUX
@@ -2428,9 +2428,14 @@
 		     || (scp -> si_code == SEGV_UNKNOWN) \
 		     || (scp -> si_code == BUS_OBJERR)
 #   else
-#     define SIG_OK (sig == SIGSEGV)
-#     define CODE_OK (scp -> si_code == SEGV_ACCERR)
-#   endif
+#     ifdef FREEBSD
+#       define SIG_OK (sig == SIGBUS)
+#       define CODE_OK (scp -> si_code == BUS_PAGE_FAULT)
+#     else
+#       define SIG_OK (sig == SIGSEGV)
+#       define CODE_OK (scp -> si_code == SEGV_ACCERR)
+#     endif
+#   endif    
 # endif /* SUNOS5SIGS */
 
 # if defined(MSWIN32) || defined(MSWINCE)
@@ -2549,11 +2554,17 @@
 		    return(EXCEPTION_CONTINUE_SEARCH);
 #		endif
             } else {
-#		if defined (SUNOS4) || defined(FREEBSD)
+#		if defined (SUNOS4) \
+                    || (defined(FREEBSD) && !defined(SUNOS5SIGS))
 		    (*old_handler) (sig, code, scp, addr);
 		    return;
 #		endif
 #		if defined (SUNOS5SIGS)
+                    /*
+                     * FIXME: For FreeBSD, this code should check if the 
+                     * old signal handler used the traditional BSD style and
+                     * if so call it using that style.
+                     */
 		    (*(REAL_SIG_PF)old_handler) (sig, scp, context);
 		    return;
 #		endif
@@ -2678,7 +2689,7 @@
         GC_err_printf0("Page size not multiple of HBLKSIZE\n");
         ABORT("Page size not multiple of HBLKSIZE");
     }
-#   if defined(SUNOS4) || defined(FREEBSD)
+#   if defined(SUNOS4) || (defined(FREEBSD) && !defined(SUNOS5SIGS))
       GC_old_bus_handler = signal(SIGBUS, GC_write_fault_handler);
       if (GC_old_bus_handler == SIG_IGN) {
         GC_err_printf0("Previously ignored bus error!?");
@@ -2702,13 +2713,13 @@
 #	endif
       }
 #   endif
-#   if defined(SUNOS5SIGS) || defined(IRIX5) || defined(LINUX) \
-       || defined(OSF1) || defined(HURD)
+#   if (defined(SUNOS5SIGS) && !defined(FREEBSD)) || defined(IRIX5) \
+       || defined(LINUX) || defined(OSF1) || defined(HURD)
       /* SUNOS5SIGS includes HPUX */
 #     if defined(GC_IRIX_THREADS)
       	sigaction(SIGSEGV, 0, &oldact);
       	sigaction(SIGSEGV, &act, 0);
-#     else
+#     else 
 	{
 	  int res = sigaction(SIGSEGV, &act, &oldact);
 	  if (res != 0) ABORT("Sigaction failed");
@@ -2734,8 +2745,9 @@
 	  GC_err_printf0("Replaced other SIGSEGV handler\n");
 #       endif
       }
-#   endif
-#   if defined(HPUX) || defined(LINUX) || defined(HURD)
+#   endif /* (SUNOS5SIGS && !FREEBSD) || IRIX5 || LINUX || OSF1 || HURD */
+#   if defined(HPUX) || defined(LINUX) || defined(HURD) \
+      || (defined(FREEBSD) && defined(SUNOS5SIGS))
       sigaction(SIGBUS, &act, &oldact);
       GC_old_bus_handler = oldact.sa_handler;
       if (GC_old_bus_handler == SIG_IGN) {
@@ -2747,7 +2759,7 @@
 	  GC_err_printf0("Replaced other SIGBUS handler\n");
 #       endif
       }
-#   endif /* HPUX || LINUX || HURD */
+#   endif /* HPUX || LINUX || HURD || (FREEBSD && SUNOS5SIGS) */
 #   if defined(MSWIN32)
       GC_old_segv_handler = SetUnhandledExceptionFilter(GC_write_fault_handler);
       if (GC_old_segv_handler != NULL) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: sigsegvtest.c
Type: image/x-xbitmap
Size: 708 bytes
Desc: not available
Url : http://napali.hpl.hp.com/pipermail/gc/attachments/20040418/f614bc03/sigsegvtest.xbm


More information about the Gc mailing list