Mercurial > dovecot > original-hg > dovecot-1.2
changeset 4840:a0a38a306c17 HEAD
Since getting core dumps can be sometimes difficult, if we now do abort()
ourself, we first log the backtrace. This works at least with Linux and
Solaris.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 19 Nov 2006 15:30:38 +0200 |
parents | b8a9a0fd65c5 |
children | c04ecbc7bdc8 |
files | configure.in src/lib/Makefile.am src/lib/backtrace-string.c src/lib/backtrace-string.h src/lib/failures.c |
diffstat | 5 files changed, 113 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Sun Nov 19 01:35:37 2006 +0200 +++ b/configure.in Sun Nov 19 15:30:38 2006 +0200 @@ -19,7 +19,7 @@ sys/uio.h sys/sysmacros.h sys/resource.h sys/select.h libgen.h \ sys/quota.h sys/fs/ufs_quota.h ufs/ufs/quota.h jfs/quota.h \ mntent.h sys/mnttab.h sys/event.h sys/time.h sys/mkdev.h linux/dqblk_xfs.h \ - xfs/xqm.h sasl.h sasl/sasl.h) + xfs/xqm.h sasl.h sasl/sasl.h execinfo.h ucontext.h) AC_ARG_ENABLE(ipv6, [ --enable-ipv6 Enable IPv6 support (default)], @@ -411,7 +411,7 @@ strcasecmp stricmp vsnprintf vsyslog writev pread \ setrlimit setproctitle seteuid setreuid setegid setresgid \ strtoull strtouq setpriority quotactl getmntent kqueue kevent \ - getrusage) + getrusage backtrace_symbols walkcontext) dnl * I/O loop function have_ioloop=no
--- a/src/lib/Makefile.am Sun Nov 19 01:35:37 2006 +0200 +++ b/src/lib/Makefile.am Sun Nov 19 15:30:38 2006 +0200 @@ -1,6 +1,7 @@ noinst_LIBRARIES = liblib.a liblib_a_SOURCES = \ + backtrace-string.c \ base64.c \ bsearch-insert-pos.c \ buffer.c \ @@ -89,6 +90,7 @@ noinst_HEADERS = \ array.h \ array-decl.h \ + backtrace-string.h \ base64.h \ bsearch-insert-pos.h \ buffer.h \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/backtrace-string.c Sun Nov 19 15:30:38 2006 +0200 @@ -0,0 +1,87 @@ +/* Copyright (c) 2006 Timo Sirainen */ + +#include "lib.h" +#include "str.h" +#include "backtrace-string.h" + +#define MAX_STACK_SIZE 30 +#define STACK_SKIP_COUNT 2 + +#if defined(HAVE_BACKTRACE_SYMBOLS) && defined(HAVE_EXECINFO_H) +/* Linux */ +#include <execinfo.h> +#include <stdlib.h> + +int backtrace_append(string_t *str) +{ + void *stack[MAX_STACK_SIZE]; + char **strings; + int ret, i; + + ret = backtrace(stack, sizeof(stack)/sizeof(stack[0])); + if (ret <= STACK_SKIP_COUNT) + return -1; + + strings = backtrace_symbols(stack, ret); + for (i = STACK_SKIP_COUNT; i < ret; i++) { + if (i > STACK_SKIP_COUNT) + str_append(str, " -> "); + str_append(str, strings[i]); + } + free(strings); + return 0; +} +#elif defined(HAVE_WALKCONTEXT) && defined(HAVE_UCONTEXT_H) +/* Solaris */ +#include <ucontext.h> + +struct walk_context { + string_t *str; + unsigned int pos; +}; + +static int walk_callback(uintptr_t ptr, int signo __attr_unused__, + void *context) +{ + struct walk_context *ctx = context; + + if (ctx->pos >= STACK_SKIP_COUNT) { + if (ctx->pos > STACK_SKIP_COUNT) + str_append(ctx->str, " -> "); + str_printfa(ctx->str, "0x%p", (void *)ptr); + } + ctx->pos++; + return 0; +} + +int backtrace_append(string_t *str) +{ + ucontext_t uc; + struct walk_context ctx; + + if (getcontext(&uc) < 0) + return -1; + + ctx.str = str; + ctx.pos = 0; + walkcontext(&uc, walk_callback, &ctx); + return 0; +} +#else +int backtrace_append(string_t *str __attr_unused__) +{ + return -1; +} +#endif + +int backtrace_get(const char **backtrace_r) +{ + string_t *str; + + str = t_str_new(512); + if (backtrace_append(str) < 0) + return -1; + + *backtrace_r = str_c(str); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/backtrace-string.h Sun Nov 19 15:30:38 2006 +0200 @@ -0,0 +1,8 @@ +#ifndef __BACKTRACE_STRING_H +#define __BACKTRACE_STRING_H + +/* Returns 0 if ok, -1 if failure. */ +int backtrace_append(string_t *str); +int backtrace_get(const char **backtrace_r); + +#endif
--- a/src/lib/failures.c Sun Nov 19 01:35:37 2006 +0200 +++ b/src/lib/failures.c Sun Nov 19 15:30:38 2006 +0200 @@ -2,6 +2,7 @@ #include "lib.h" #include "str.h" +#include "backtrace-string.h" #include "write-full.h" #include "fd-close-on-exec.h" #include "printf-upper-bound.h" @@ -120,7 +121,11 @@ static void __attr_format__(1, 0) default_panic_handler(const char *format, va_list args) { + const char *backtrace; + (void)default_handler("Panic: ", log_fd, format, args); + if (backtrace_get(&backtrace) == 0) + i_error("Backtrace: %s", backtrace); abort(); } @@ -290,8 +295,12 @@ void i_syslog_panic_handler(const char *fmt, va_list args) { + const char *backtrace; + (void)syslog_handler(LOG_CRIT, fmt, args); - abort(); + if (backtrace_get(&backtrace) == 0) + i_error("Backtrace: %s", backtrace); + abort(); } void i_syslog_fatal_handler(int status, const char *fmt, va_list args) @@ -384,7 +393,11 @@ static void __attr_noreturn__ __attr_format__(1, 0) i_internal_panic_handler(const char *fmt, va_list args) { + const char *backtrace; + (void)internal_handler('F', fmt, args); + if (backtrace_get(&backtrace) == 0) + i_error("Backtrace: %s", backtrace); abort(); }