From 40abf2392ba9f14935dab556f43e674cb5c47cf3 Mon Sep 17 00:00:00 2001 From: ajs Date: Wed, 12 Jan 2005 17:27:27 +0000 Subject: 2005-01-12 Andrew J. Schorr * configure.ac: Test for header file (for use in signal processing). * sigevent.c: (trap_default_signals) Use the SA_SIGINFO flag to pass additional siginfo_t and ucontext_t arguments to core_handler and exit_handler. (core_handler,exit_handler) Now invoked with 3 arguments (using SA_SIGINFO). Pass additional info to zlog_signal. (program_counter) New function to find program counter in ucontext_t, needs to be enhanced to support more platforms (currently works only on Linux/x86). * log.h: Change the zlog_signal prototype to add new arguments siginfo_t * and program_counter. * log.c: (zlog_signal) Add new arguments siginfo and program_counter. Include si_addr and program counter (if non-NULL) in message. And remove #ifdef HAVE_GLIBC_BACKTRACE around hex_append, since that is now used to render the si_addr and PC pointers. --- lib/sigevent.c | 56 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 11 deletions(-) (limited to 'lib/sigevent.c') diff --git a/lib/sigevent.c b/lib/sigevent.c index 5ac226a4c..7acdad290 100644 --- a/lib/sigevent.c +++ b/lib/sigevent.c @@ -23,6 +23,15 @@ #include #include +#ifdef HAVE_UCONTEXT_H +#ifdef GNU_LINUX +/* get REG_EIP from ucontext.h */ +#define __USE_GNU +#endif /* GNU_LINUX */ +#include +#endif /* HAVE_UCONTEXT_H */ + + /* master signals descriptor struct */ struct quagga_sigevent_master_t { @@ -124,7 +133,7 @@ quagga_signal_timer (struct thread *t) #endif /* SIGEVENT_SCHEDULE_THREAD */ /* Initialization of signal handles. */ -/* Signale wrapper. */ +/* Signal wrapper. */ static int signal_set (int signo) { @@ -152,17 +161,33 @@ signal_set (int signo) return 0; } +/* XXX This function should be enhanced to support more platforms + (it currently works only on Linux/x86). */ +static void * +program_counter(void *context) +{ +#ifdef HAVE_UCONTEXT_H +#ifdef GNU_LINUX +#ifdef REG_EIP + if (context) + return (void *)(((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP]); +#endif /* REG_EIP */ +#endif /* GNU_LINUX */ +#endif /* HAVE_UCONTEXT_H */ + return NULL; +} + static void -exit_handler(int signo) +exit_handler(int signo, siginfo_t *siginfo, void *context) { - zlog_signal(signo,"exiting..."); + zlog_signal(signo, "exiting...", siginfo, program_counter(context)); _exit(128+signo); } static void -core_handler(int signo) +core_handler(int signo, siginfo_t *siginfo, void *context) { - zlog_signal(signo,"aborting..."); + zlog_signal(signo, "aborting...", siginfo, program_counter(context)); abort(); } @@ -211,11 +236,11 @@ trap_default_signals(void) static const struct { const int *sigs; u_int nsigs; - void (*handler)(int); + void (*handler)(int signo, siginfo_t *info, void *context); } sigmap[] = { - { core_signals, sizeof(core_signals)/sizeof(core_signals[0]),core_handler }, - { exit_signals, sizeof(exit_signals)/sizeof(exit_signals[0]),exit_handler }, - { ignore_signals, sizeof(ignore_signals)/sizeof(ignore_signals[0]),SIG_IGN}, + { core_signals, sizeof(core_signals)/sizeof(core_signals[0]), core_handler}, + { exit_signals, sizeof(exit_signals)/sizeof(exit_signals[0]), exit_handler}, + { ignore_signals, sizeof(ignore_signals)/sizeof(ignore_signals[0]), NULL}, }; u_int i; @@ -230,9 +255,18 @@ trap_default_signals(void) (oact.sa_handler == SIG_DFL)) { struct sigaction act; - act.sa_handler = sigmap[i].handler; sigfillset (&act.sa_mask); - act.sa_flags = 0; + if (sigmap[i].handler == NULL) + { + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + } + else + { + /* Request extra arguments to signal handler. */ + act.sa_sigaction = sigmap[i].handler; + act.sa_flags = SA_SIGINFO; + } if (sigaction(sigmap[i].sigs[j],&act,NULL) < 0) zlog_warn("Unable to set signal handler for signal %d: %s", sigmap[i].sigs[j],safe_strerror(errno)); -- cgit v1.2.3