forked from Mirror/frr
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.
This commit is contained in:
parent
6cf9df088e
commit
40abf2392b
|
@ -1,3 +1,8 @@
|
||||||
|
2005-01-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
|
||||||
|
|
||||||
|
* configure.ac: Test for header file <ucontext.h> (for use in
|
||||||
|
signal processing).
|
||||||
|
|
||||||
2005-01-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
|
2005-01-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
|
||||||
|
|
||||||
* configure.ac: If configure is invoked with --enable-snmp, but
|
* configure.ac: If configure is invoked with --enable-snmp, but
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
## Copyright (c) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
|
## Copyright (c) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
|
||||||
## Portions Copyright (c) 2003 Paul Jakma <paul@dishone.st>
|
## Portions Copyright (c) 2003 Paul Jakma <paul@dishone.st>
|
||||||
##
|
##
|
||||||
## $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_PREREQ(2.53)
|
||||||
|
|
||||||
AC_INIT(Quagga, 0.98.0, [http://bugzilla.quagga.net])
|
AC_INIT(Quagga, 0.98.0, [http://bugzilla.quagga.net])
|
||||||
|
@ -1107,6 +1107,11 @@ if test "${enable_capabilities}" != "no"; then
|
||||||
fi
|
fi
|
||||||
AC_SUBST(LIBCAP)
|
AC_SUBST(LIBCAP)
|
||||||
|
|
||||||
|
dnl -------------------
|
||||||
|
dnl test for ucontext.h
|
||||||
|
dnl -------------------
|
||||||
|
AC_CHECK_HEADERS(ucontext.h)
|
||||||
|
|
||||||
dnl ---------------------------
|
dnl ---------------------------
|
||||||
dnl check for glibc 'backtrace'
|
dnl check for glibc 'backtrace'
|
||||||
dnl ---------------------------
|
dnl ---------------------------
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
2005-01-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
|
||||||
|
|
||||||
|
* 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 <ajschorr@alumni.princeton.edu>
|
2005-01-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
|
||||||
|
|
||||||
* zebra.h: If not C99 and no va_copy macro available, fall back to
|
* zebra.h: If not C99 and no va_copy macro available, fall back to
|
||||||
|
|
22
lib/log.c
22
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
|
* Logging of zebra
|
||||||
* Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro
|
* 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);
|
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 *
|
static char *
|
||||||
hex_append(char *s, int len, u_long x)
|
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);
|
return str_append(s,len,t);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_GLIBC_BACKTRACE */
|
|
||||||
|
|
||||||
static int syslog_fd = -1;
|
static int syslog_fd = -1;
|
||||||
|
|
||||||
/* Needs to be enhanced to support Solaris. */
|
/* 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. */
|
/* Note: the goal here is to use only async-signal-safe functions. */
|
||||||
void
|
void
|
||||||
zlog_signal(int signo, const char *action)
|
zlog_signal(int signo, const char *action, siginfo_t *siginfo,
|
||||||
|
void *program_counter)
|
||||||
{
|
{
|
||||||
time_t now;
|
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 *s = buf;
|
||||||
char *msgstart = buf;
|
char *msgstart = buf;
|
||||||
#define LOC s,buf+sizeof(buf)-s
|
#define LOC s,buf+sizeof(buf)-s
|
||||||
|
@ -284,7 +279,14 @@ zlog_signal(int signo, const char *action)
|
||||||
s = num_append(LOC,signo);
|
s = num_append(LOC,signo);
|
||||||
s = str_append(LOC," at ");
|
s = str_append(LOC," at ");
|
||||||
s = num_append(LOC,now);
|
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);
|
s = str_append(LOC,action);
|
||||||
if (s < buf+sizeof(buf))
|
if (s < buf+sizeof(buf))
|
||||||
*s++ = '\n';
|
*s++ = '\n';
|
||||||
|
|
|
@ -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.
|
* Zebra logging funcions.
|
||||||
* Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro
|
* Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro
|
||||||
|
@ -153,7 +153,8 @@ extern const char *zlog_proto_names[];
|
||||||
extern const char *safe_strerror(int errnum);
|
extern const char *safe_strerror(int errnum);
|
||||||
|
|
||||||
/* To be called when a fatal signal is caught. */
|
/* 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. */
|
/* Log a backtrace. */
|
||||||
extern void zlog_backtrace(int priority);
|
extern void zlog_backtrace(int priority);
|
||||||
|
|
|
@ -23,6 +23,15 @@
|
||||||
#include <sigevent.h>
|
#include <sigevent.h>
|
||||||
#include <log.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 */
|
/* master signals descriptor struct */
|
||||||
struct quagga_sigevent_master_t
|
struct quagga_sigevent_master_t
|
||||||
{
|
{
|
||||||
|
@ -124,7 +133,7 @@ quagga_signal_timer (struct thread *t)
|
||||||
#endif /* SIGEVENT_SCHEDULE_THREAD */
|
#endif /* SIGEVENT_SCHEDULE_THREAD */
|
||||||
|
|
||||||
/* Initialization of signal handles. */
|
/* Initialization of signal handles. */
|
||||||
/* Signale wrapper. */
|
/* Signal wrapper. */
|
||||||
static int
|
static int
|
||||||
signal_set (int signo)
|
signal_set (int signo)
|
||||||
{
|
{
|
||||||
|
@ -152,17 +161,33 @@ signal_set (int signo)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* XXX This function should be enhanced to support more platforms
|
||||||
exit_handler(int signo)
|
(it currently works only on Linux/x86). */
|
||||||
|
static void *
|
||||||
|
program_counter(void *context)
|
||||||
{
|
{
|
||||||
zlog_signal(signo,"exiting...");
|
#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, siginfo_t *siginfo, void *context)
|
||||||
|
{
|
||||||
|
zlog_signal(signo, "exiting...", siginfo, program_counter(context));
|
||||||
_exit(128+signo);
|
_exit(128+signo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,11 +236,11 @@ trap_default_signals(void)
|
||||||
static const struct {
|
static const struct {
|
||||||
const int *sigs;
|
const int *sigs;
|
||||||
u_int nsigs;
|
u_int nsigs;
|
||||||
void (*handler)(int);
|
void (*handler)(int signo, siginfo_t *info, void *context);
|
||||||
} sigmap[] = {
|
} sigmap[] = {
|
||||||
{ core_signals, sizeof(core_signals)/sizeof(core_signals[0]),core_handler },
|
{ core_signals, sizeof(core_signals)/sizeof(core_signals[0]), core_handler},
|
||||||
{ exit_signals, sizeof(exit_signals)/sizeof(exit_signals[0]),exit_handler },
|
{ exit_signals, sizeof(exit_signals)/sizeof(exit_signals[0]), exit_handler},
|
||||||
{ ignore_signals, sizeof(ignore_signals)/sizeof(ignore_signals[0]),SIG_IGN},
|
{ ignore_signals, sizeof(ignore_signals)/sizeof(ignore_signals[0]), NULL},
|
||||||
};
|
};
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
|
@ -230,9 +255,18 @@ trap_default_signals(void)
|
||||||
(oact.sa_handler == SIG_DFL))
|
(oact.sa_handler == SIG_DFL))
|
||||||
{
|
{
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
act.sa_handler = sigmap[i].handler;
|
|
||||||
sigfillset (&act.sa_mask);
|
sigfillset (&act.sa_mask);
|
||||||
|
if (sigmap[i].handler == NULL)
|
||||||
|
{
|
||||||
|
act.sa_handler = SIG_IGN;
|
||||||
act.sa_flags = 0;
|
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)
|
if (sigaction(sigmap[i].sigs[j],&act,NULL) < 0)
|
||||||
zlog_warn("Unable to set signal handler for signal %d: %s",
|
zlog_warn("Unable to set signal handler for signal %d: %s",
|
||||||
sigmap[i].sigs[j],safe_strerror(errno));
|
sigmap[i].sigs[j],safe_strerror(errno));
|
||||||
|
|
Loading…
Reference in a new issue