for review: cleanup signal setting.

Tyson Dowd trd at cs.mu.OZ.AU
Thu May 14 13:29:19 AEST 1998


Hi,

Would you be able to review this, Tom?

===================================================================


Estimated hours taken: 5

More cleanup of the memory management code.
This time we clean up the signal handler setup code.

runtime/Mmakefile:
	Add new files.

runtime/mercury_memory.c:
	Rename setup_signal() to setup_signals().

runtime/mercury_memory_handlers.c:
runtime/mercury_memory_handlers.h:
	Clean up signal handling.  
	Use MR_setup_signal to setup signal handlers.
	Define bus_handler and segv_handler signal handlers, the
	old signal handlers are just one or the other (or both).

runtime/mercury_prof.c:
	Use MR_setup_signal to setup signal handler.

runtime/mercury_signal.c:
runtime/mercury_signal.h:
	New files -- a standard interface for setting up signal
	handlers (a porting base, if you like).  


Index: runtime/Mmakefile
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/Mmakefile,v
retrieving revision 1.26
diff -u -r1.26 Mmakefile
--- Mmakefile	1998/05/08 02:53:22	1.26
+++ Mmakefile	1998/05/12 04:56:32
@@ -51,6 +51,7 @@
 			mercury_prof_mem.h	\
 			mercury_regorder.h	\
 			mercury_regs.h		\
+			mercury_signal.h	\
 			mercury_spinlock.h	\
 			mercury_std.h		\
 			mercury_stacks.h	\
@@ -99,6 +100,7 @@
 			mercury_prof.c		\
 			mercury_prof_mem.c	\
 			mercury_regs.c		\
+			mercury_signal.c	\
 			mercury_spinlock.c	\
 			mercury_stack_trace.c	\
 			mercury_table.c		\
Index: runtime/mercury_memory.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_memory.c,v
retrieving revision 1.7
diff -u -r1.7 mercury_memory.c
--- mercury_memory.c	1998/05/08 02:53:29	1.7
+++ mercury_memory.c	1998/05/12 04:32:32
@@ -186,7 +186,7 @@
 
 	init_memory_arena();
 	init_zones();
-	setup_signal();
+	setup_signals();
 	if (memdebug) debug_memory();
 } /* end init_memory() */
 
Index: runtime/mercury_memory_handlers.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_memory_handlers.c,v
retrieving revision 1.2
diff -u -r1.2 mercury_memory_handlers.c
--- mercury_memory_handlers.c	1998/05/11 08:23:24	1.2
+++ mercury_memory_handlers.c	1998/05/13 04:57:47
@@ -15,6 +15,10 @@
 
 #include "mercury_imp.h"
 
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
 #ifdef HAVE_SIGCONTEXT_STRUCT
   /*
   ** Some versions of Linux call it struct sigcontext_struct, some call it
@@ -43,10 +47,6 @@
   #include <signal.h>
 #endif
 
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-
 #ifdef HAVE_SYS_SIGINFO
   #include <sys/siginfo.h>
 #endif 
@@ -64,6 +64,7 @@
 #endif
 
 #include "mercury_imp.h"
+#include "mercury_signal.h"
 #include "mercury_trace.h"
 #include "mercury_memory_zones.h"
 #include "mercury_memory_handlers.h"
@@ -83,6 +84,23 @@
   static	void	simple_sighandler(int);
 #endif
 
+
+#ifdef HAVE_SIGINFO
+  #if defined(HAVE_SIGCONTEXT_STRUCT)
+    #define     bus_handler	complex_sighandler
+    #define     segv_handler	complex_sighandler
+  #elif defined(HAVE_SIGINFO_T)
+    #define     bus_handler	complex_bushandler
+    #define     segv_handler	complex_segvhandler
+  #else
+    #error "HAVE_SIGINFO defined but don't know how to get it"
+  #endif
+#else
+    #define     bus_handler	simple_sighandler
+    #define     segv_handler	simple_sighandler
+#endif
+
+
 /*
 ** round_up(amount, align) returns `amount' rounded up to the nearest
 ** alignment boundary.  `align' must be a power of 2.
@@ -224,56 +242,12 @@
 } 
 
 void
-setup_signal(void)
+setup_signals(void)
 {
-#if defined(HAVE_SIGCONTEXT_STRUCT)
-	if (signal(SIGBUS, (void(*)(int)) complex_sighandler) == SIG_ERR)
-	{
-		perror("cannot set SIGBUS handler");
-		exit(1);
-	}
-
-	if (signal(SIGSEGV, (void(*)(int)) complex_sighandler) == SIG_ERR)
-	{
-		perror("cannot set SIGSEGV handler");
-		exit(1);
-	}
-
-#elif defined(HAVE_SIGINFO_T)
-
-	struct sigaction	act;
-
-	act.sa_flags = SA_SIGINFO | SA_RESTART;
-	if (sigemptyset(&act.sa_mask) != 0) {
-		perror("Mercury runtime: cannot set clear signal mask");
-		exit(1);
-	}
-
-	act.SIGACTION_FIELD = complex_bushandler;
-	if (sigaction(SIGBUS, &act, NULL) != 0) {
-		perror("Mercury runtime: cannot set SIGBUS handler");
-		exit(1);
-	}
-
-	act.SIGACTION_FIELD = complex_segvhandler;
-	if (sigaction(SIGSEGV, &act, NULL) != 0) {
-		perror("Mercury runtime: cannot set SIGSEGV handler");
-		exit(1);
-	}
-
-#else /* not HAVE_SIGINFO_T && not HAVE_SIGCONTEXT_STRUCT */
-
-	if (signal(SIGBUS, simple_sighandler) == SIG_ERR) {
-		perror("cannot set SIGBUS handler");
-		exit(1);
-	}
-
-	if (signal(SIGSEGV, simple_sighandler) == SIG_ERR) {
-		perror("cannot set SIGSEGV handler");
-		exit(1);
-	}
-
-#endif
+	MR_setup_signal(SIGBUS, bus_handler, TRUE,
+		"Mercury runtime: cannot set SIGBUS handler");
+	MR_setup_signal(SIGSEGV, segv_handler, TRUE,
+		"Mercury runtime: cannot set SIGSEGV handler");
 }
 
 static char *
Index: runtime/mercury_memory_handlers.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_memory_handlers.h,v
retrieving revision 1.1
diff -u -r1.1 mercury_memory_handlers.h
--- mercury_memory_handlers.h	1998/05/08 02:53:36	1.1
+++ mercury_memory_handlers.h	1998/05/12 04:32:36
@@ -31,10 +31,10 @@
 
 /*
 **
-** setup_signal() will setup the default signal handlers.
+** setup_signals() will setup the default signal handlers.
 **
 */
 
-void	setup_signal(void);
+void	setup_signals(void);
 
 #endif /* not MERCURY_MEMORY_HANDLERS_H */
Index: runtime/mercury_prof.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_prof.c,v
retrieving revision 1.5
diff -u -r1.5 mercury_prof.c
--- mercury_prof.c	1997/12/07 21:43:31	1.5
+++ mercury_prof.c	1998/05/13 06:21:52
@@ -21,6 +21,7 @@
 #include	"mercury_heap_profile.h" /* for MR_prof_output_mem_tables() */
 #include	"mercury_prof_mem.h"	 /* for prof_malloc() */
 
+#include	"mercury_signal.h"
 #include        "mercury_std.h"
 #include	"mercury_timing.h"
 
@@ -204,6 +205,8 @@
 
 #endif /* PROFILE_TIME or PROFILE_CALLS or PROFILE_MEMORY */
 
+/* ======================================================================== */
+
 #ifdef	PROFILE_TIME
 
 static void
@@ -216,46 +219,6 @@
 	}
 }
 
-static void
-checked_signal(int sig, void (*handler)(int))
-{
-	/*
-	** We really need sigaction and SA_RESTART, otherwise profiling signals
-	** might interrupt I/O, causing a profiled program to get I/O errors.
-	** But if we haven't got it, I guess we just have to punt...
-	*/
-#ifndef SA_RESTART
-#define SA_RESTART 0
-#endif
-
-#ifdef HAVE_SIGACTION
-	struct sigaction	act;
-	act.sa_flags = SA_RESTART;
-	if (sigemptyset(&act.sa_mask) != 0) {
-		perror("Mercury runtime: cannot set clear signal mask");
-		exit(1);
-	}
-	act.sa_handler = handler;
-#endif /* HAVE_SIGACTION */
-	errno = 0;
-
-#ifdef HAVE_SIGACTION
-	if (sigaction(sig, &act, NULL) != 0)
-#else
-	if (signal(sig, handler) == SIG_ERR)
-#endif /* HAVE_SIGACTION */
-	{
-		perror("Mercury runtime: cannot install signal handler");
-		exit(1);
-	}
-}
-
-#endif /* PROFILE_TIME */
-
-/* ======================================================================== */
-
-#ifdef PROFILE_TIME
-
 /*
 **	prof_turn_on_time_profiling:
 **		Sets up the profiling timer and starts it up. 
@@ -282,7 +245,8 @@
 	itime.it_interval.tv_sec = 0;
 	itime.it_interval.tv_usec = prof_sig_interval_in_usecs;
 
-	checked_signal(MR_itimer_sig, prof_time_profile);
+	MR_setup_signal(MR_itimer_sig, prof_time_profile, 
+		"Mercury runtime: cannot install signal handler");
 	checked_setitimer(MR_itimer_type, &itime);
 }
 
New File: runtime/mercury_signal.c
===================================================================
/*
** Copyright (C) 1998 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/

/*
** This module defines functions for setting up signal handlers.
*/

/*---------------------------------------------------------------------------*/

#include "mercury_imp.h"

#ifdef HAVE_SIGCONTEXT_STRUCT
  /*
  ** Some versions of Linux call it struct sigcontext_struct, some call it
  ** struct sigcontext.  The following #define eliminates the differences.
  */
  #define sigcontext_struct sigcontext /* must be before #include <signal.h> */

  /*
  ** On some systems (e.g. most versions of Linux) we need to #define
  ** __KERNEL__ to get sigcontext_struct from <signal.h>.
  ** This stuff must come before anything else that might include <signal.h>,
  ** otherwise the #define __KERNEL__ may not work.
  */
  #define __KERNEL__
  #include <signal.h>	/* must come third */
  #undef __KERNEL__

  /*
  ** Some versions of Linux define it in <signal.h>, others define it in
  ** <asm/sigcontext.h>.  We try both.
  */
  #ifdef HAVE_ASM_SIGCONTEXT
    #include <asm/sigcontext.h>
  #endif 
#else
  #include <signal.h>
#endif

#include <unistd.h>
#include <stdio.h>
#include <string.h>

#ifdef HAVE_SYS_SIGINFO
  #include <sys/siginfo.h>
#endif 

#ifdef	HAVE_MPROTECT
  #include <sys/mman.h>
#endif

#ifdef	HAVE_UCONTEXT
  #include <ucontext.h>
#endif

#ifdef	HAVE_SYS_UCONTEXT
  #include <sys/ucontext.h>
#endif

#include "mercury_imp.h"
#include "mercury_signal.h"

/*---------------------------------------------------------------------------*/

void
MR_setup_signal(int sig, void *handler, int need_info, 
		const char *error_message)
{
#if	defined(HAVE_SIGINFO_T)

	struct sigaction	act;

	if (need_info) {
		act.sa_flags = SA_SIGINFO | SA_RESTART;
	} else {
		act.sa_flags = SA_RESTART;
	}
	if (sigemptyset(&act.sa_mask) != 0) {
		perror("Mercury runtime: cannot set clear signal mask");
		exit(1);
	}
	errno = 0;

	act.SIGACTION_FIELD = handler;
	if (sigaction(sig, &act, NULL) != 0) {
		perror(error_message);
		exit(1);
	}

#else /* not HAVE_SIGINFO_T */

	if (signal(sig, handler) == SIG_ERR) {
		perror(error_message);
		exit(1);
	}
#endif /* not HAVE_SIGINFO_T */
}


New File: runtime/mercury_signal.h
===================================================================
/*
** Copyright (C) 1998 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/

/*
** mercury_signal.h - functions for setting up signal handlers.
**
** This defines a generic signal handler setup mechanism.
*/

#ifndef	MERCURY_SIGNAL_H
#define	MERCURY_SIGNAL_H

	/*
	** MR_setup_signal sets a signal handler (handler) to handle
	** signals of the given signal type (sig).  
	** If the handler cannot be setup, it aborts with the given
	** error message.
	** 
	** If the signal handler requires siginfo to be provided (e.g.
	** it needs access to stored registers), need_info must be 
	** TRUE.  Note that on some platforms, signal information is
	** provided regardless of the value of need_info.
	*/
extern void MR_setup_signal(int sig, void *handler, int need_info, 
	const char * error_message);


#endif /* not MERCURY_SIGNAL_H */


-- 
       Tyson Dowd           # There isn't any reason why Linux can't be
                            # implemented as an enterprise computing solution.
     trd at cs.mu.oz.au        # Find out what you've been missing while you've
http://www.cs.mu.oz.au/~trd # been rebooting Windows NT. -- InfoWorld, 1998.



More information about the developers mailing list