diff options
| author | ajs <ajs> | 2005-01-12 17:27:27 +0000 | 
|---|---|---|
| committer | ajs <ajs> | 2005-01-12 17:27:27 +0000 | 
| commit | 40abf2392ba9f14935dab556f43e674cb5c47cf3 (patch) | |
| tree | 3c5ff5794940f408b411c5d0204e27dac1014378 /lib/sigevent.c | |
| parent | 6cf9df088e10baefe04139897f8745a42ea0c772 (diff) | |
2005-01-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
	* configure.ac: Test for header file <ucontext.h> (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.
Diffstat (limited to 'lib/sigevent.c')
| -rw-r--r-- | lib/sigevent.c | 56 | 
1 files changed, 45 insertions, 11 deletions
diff --git a/lib/sigevent.c b/lib/sigevent.c index 5ac226a4c2..7acdad290a 100644 --- a/lib/sigevent.c +++ b/lib/sigevent.c @@ -23,6 +23,15 @@  #include <sigevent.h>  #include <log.h> +#ifdef HAVE_UCONTEXT_H +#ifdef GNU_LINUX +/* get REG_EIP from ucontext.h */ +#define __USE_GNU +#endif /* GNU_LINUX */ +#include <ucontext.h> +#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));  | 
