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