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. --- ChangeLog | 5 +++++ configure.ac | 7 ++++++- lib/ChangeLog | 17 +++++++++++++++++ lib/log.c | 22 ++++++++++++---------- lib/log.h | 5 +++-- lib/sigevent.c | 56 +++++++++++++++++++++++++++++++++++++++++++++----------- 6 files changed, 88 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index fdcfd995..b6780eb3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-01-12 Andrew J. Schorr + + * configure.ac: Test for header file (for use in + signal processing). + 2005-01-12 Andrew J. Schorr * configure.ac: If configure is invoked with --enable-snmp, but diff --git a/configure.ac b/configure.ac index 61a00d95..ff424e8b 100755 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ ## Copyright (c) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro ## Portions Copyright (c) 2003 Paul Jakma ## -## $Id: configure.ac,v 1.86 2005/01/12 16:52:55 ajs Exp $ +## $Id: configure.ac,v 1.87 2005/01/12 17:27:27 ajs Exp $ AC_PREREQ(2.53) AC_INIT(Quagga, 0.98.0, [http://bugzilla.quagga.net]) @@ -1107,6 +1107,11 @@ if test "${enable_capabilities}" != "no"; then fi AC_SUBST(LIBCAP) +dnl ------------------- +dnl test for ucontext.h +dnl ------------------- +AC_CHECK_HEADERS(ucontext.h) + dnl --------------------------- dnl check for glibc 'backtrace' dnl --------------------------- diff --git a/lib/ChangeLog b/lib/ChangeLog index 4b245bec..4410fb24 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,20 @@ +2005-01-12 Andrew J. Schorr + + * 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. + 2005-01-12 Andrew J. Schorr * zebra.h: If not C99 and no va_copy macro available, fall back to diff --git a/lib/log.c b/lib/log.c index 1be1c0b0..fcf7c5d5 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.20 2004/12/10 22:43:17 ajs Exp $ + * $Id: log.c,v 1.21 2005/01/12 17:27:27 ajs Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -177,10 +177,6 @@ num_append(char *s, int len, u_long x) return str_append(s,len,t); } -#ifdef HAVE_GLIBC_BACKTRACE - -/* This function is used only in zlog_backtrace_sigsafe when glibc - backtraces are available. */ static char * hex_append(char *s, int len, u_long x) { @@ -199,8 +195,6 @@ hex_append(char *s, int len, u_long x) return str_append(s,len,t); } -#endif /* HAVE_GLIBC_BACKTRACE */ - static int syslog_fd = -1; /* Needs to be enhanced to support Solaris. */ @@ -264,10 +258,11 @@ syslog_sigsafe(int priority, const char *msg, size_t msglen) /* Note: the goal here is to use only async-signal-safe functions. */ void -zlog_signal(int signo, const char *action) +zlog_signal(int signo, const char *action, siginfo_t *siginfo, + void *program_counter) { time_t now; - char buf[sizeof("DEFAULT: Received signal S at T; aborting...")+60]; + char buf[sizeof("DEFAULT: Received signal S at T (si_addr 0xP, PC 0xP); aborting...")+100]; char *s = buf; char *msgstart = buf; #define LOC s,buf+sizeof(buf)-s @@ -284,7 +279,14 @@ zlog_signal(int signo, const char *action) s = num_append(LOC,signo); s = str_append(LOC," at "); s = num_append(LOC,now); - s = str_append(LOC,"; "); + s = str_append(LOC," (si_addr 0x"); + s = hex_append(LOC,(u_long)(siginfo->si_addr)); + if (program_counter) + { + s = str_append(LOC,", PC 0x"); + s = hex_append(LOC,(u_long)program_counter); + } + s = str_append(LOC,"); "); s = str_append(LOC,action); if (s < buf+sizeof(buf)) *s++ = '\n'; diff --git a/lib/log.h b/lib/log.h index 1f9f23cd..b8288298 100644 --- a/lib/log.h +++ b/lib/log.h @@ -1,5 +1,5 @@ /* - * $Id: log.h,v 1.14 2004/12/07 15:39:32 ajs Exp $ + * $Id: log.h,v 1.15 2005/01/12 17:27:27 ajs Exp $ * * Zebra logging funcions. * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -153,7 +153,8 @@ extern const char *zlog_proto_names[]; extern const char *safe_strerror(int errnum); /* To be called when a fatal signal is caught. */ -extern void zlog_signal(int signo, const char *action); +extern void zlog_signal(int signo, const char *action, + siginfo_t *siginfo, void *program_counter); /* Log a backtrace. */ extern void zlog_backtrace(int priority); diff --git a/lib/sigevent.c b/lib/sigevent.c index 5ac226a4..7acdad29 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.1