diff options
author | ajs <ajs> | 2004-11-23 18:19:14 +0000 |
---|---|---|
committer | ajs <ajs> | 2004-11-23 18:19:14 +0000 |
commit | 59a06a915da9129a4e756c2b4d42449aa71a0ee4 (patch) | |
tree | 44090f696cbec97cab5e5b090b22c7431a5d6490 /lib/log.c | |
parent | d246bd965898f0ba6781f2b2048af9a5eba079d3 (diff) |
2004-11-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* sigevent.c: (signal_init) Set up some default signal handlers
so that processes will issue an error message before terminating
or dumping core.
(trap_default_signals) New function to set up signal handlers
for various signals that may kill the process.
(exit_handler) Call zlog_signal, then _exit.
(core_handler) Call zlog_signal, then abort.
* log.h: Declare new function zlog_signal.
* log.c: (zlog_signal) New function to log information about
a received signal before the process dies. Try to log a
backtrace also.
(quagga_signal_handler,signal_set) Should be static.
Diffstat (limited to 'lib/log.c')
-rw-r--r-- | lib/log.c | 98 |
1 files changed, 98 insertions, 0 deletions
@@ -163,6 +163,104 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) vty_log (zlog_proto_names[zl->protocol], format, args); } +static char * +str_append(char *dst, int len, const char *src) +{ + while ((len-- > 0) && *src) + *dst++ = *src++; + return dst; +} + +static char * +num_append(char *s, int len, u_long x) +{ + char buf[30]; + char *t = &buf[29]; + + *t = '\0'; + while (x && (t > buf)) + { + *--t = '0'+(x % 10); + x /= 10; + } + return str_append(s,len,t); +} + +/* Note: the goal here is to use only async-signal-safe functions. */ +void +zlog_signal(int signo, const char *action) +{ + time_t now; + char buf[sizeof("DEFAULT: Received signal S at T; aborting...")+60]; + char *s = buf; + +#define LOC s,buf+sizeof(buf)-s + + time(&now); + if (zlog_default) + { + s = str_append(LOC,zlog_proto_names[zlog_default->protocol]); + *s++ = ':'; + *s++ = ' '; + } + s = str_append(LOC,"Received signal "); + s = num_append(LOC,signo); + s = str_append(LOC," at "); + s = num_append(LOC,now); + s = str_append(LOC,"; "); + s = str_append(LOC,action); + *s++ = '\n'; + +#define DUMP(FP) write(fileno(FP),buf,s-buf); + if (!zlog_default) + DUMP(stderr) + else + { + if ((zlog_default->flags & ZLOG_FILE) && zlog_default->fp) + DUMP(zlog_default->fp) + if (zlog_default->flags & ZLOG_STDOUT) + DUMP(stdout) + if (zlog_default->flags & ZLOG_STDERR) + DUMP(stderr) + /* Is there a signal-safe way to send a syslog message? */ + } +#undef DUMP + + /* Now try for a backtrace. */ +#ifdef HAVE_GLIBC_BACKTRACE + { + void *array[20]; + size_t size; + + size = backtrace(array,sizeof(array)/sizeof(array[0])); + s = buf; + s = str_append(LOC,"Backtrace for "); + s = num_append(LOC,size); + s = str_append(LOC," stack frames:\n"); + +#define DUMP(FP) { \ + write(fileno(FP),buf,s-buf); \ + backtrace_symbols_fd(array, size, fileno(FP)); \ +} + + if (!zlog_default) + DUMP(stderr) + else + { + if ((zlog_default->flags & ZLOG_FILE) && zlog_default->fp) + DUMP(zlog_default->fp) + if (zlog_default->flags & ZLOG_STDOUT) + DUMP(stdout) + if (zlog_default->flags & ZLOG_STDERR) + DUMP(stderr) + /* Is there a signal-safe way to send a syslog message? */ + } +#undef DUMP + } +#endif /* HAVE_GLIBC_BACKTRACE */ +#undef LOC +} + void zlog (struct zlog *zl, int priority, const char *format, ...) { |