diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2022-05-30 10:49:54 +0100 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2022-05-30 10:49:54 +0100 |
commit | 204a7a2c2e8601558905dc34c576a627045a9f21 (patch) | |
tree | 5a6c9e698d05d47ec010d608d28a6dc94110e6bb /src | |
parent | dd4daa8a2ba4986a2fc9bba17251f6955f2332b8 (diff) |
panic_coredump option. Bug 2892
Diffstat (limited to 'src')
-rw-r--r-- | src/src/exim.c | 34 | ||||
-rw-r--r-- | src/src/globals.c | 1 | ||||
-rw-r--r-- | src/src/globals.h | 1 | ||||
-rw-r--r-- | src/src/log.c | 5 | ||||
-rw-r--r-- | src/src/readconf.c | 7 |
5 files changed, 40 insertions, 8 deletions
diff --git a/src/src/exim.c b/src/src/exim.c index 1a4b44945..6fde16a9c 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -17,6 +17,11 @@ Also a few functions that don't naturally fit elsewhere. */ # include <gnu/libc-version.h> #endif +#ifndef _TIME_H +# include <time.h> +#endif +#include <execinfo.h> /*XXX maybe glibc-only? */ + #ifdef USE_GNUTLS # include <gnutls/gnutls.h> # if GNUTLS_VERSION_NUMBER < 0x030103 && !defined(DISABLE_OCSP) @@ -24,10 +29,6 @@ Also a few functions that don't naturally fit elsewhere. */ # endif #endif -#ifndef _TIME_H -# include <time.h> -#endif - extern void init_lookup_list(void); @@ -261,6 +262,29 @@ exit(1); * Handler for SIGSEGV * ***********************************************/ +#define STACKDUMP_MAX 24 +void +stackdump(ucontext_t * ucontext) +{ +void * buf[STACKDUMP_MAX]; +char ** ss; +int nptrs = backtrace(buf, STACKDUMP_MAX); + +log_write(0, LOG_MAIN|LOG_PANIC, "backtrace\n"); +log_write(0, LOG_MAIN|LOG_PANIC, "---\n"); +if ((ss = backtrace_symbols(buf, nptrs))) + { + for (int i = 0; i < nptrs; i++) + log_write(0, LOG_MAIN|LOG_PANIC, "\t%s\n", ss[i]); + free(ss); + } +else + log_write(0, LOG_MAIN|LOG_PANIC, "backtrace_symbols: %s\n", strerror(errno)); +log_write(0, LOG_MAIN|LOG_PANIC, "---\n"); +} +#undef STACKDUMP_MAX + + static void #ifdef SA_SIGINFO segv_handler(int sig, siginfo_t * info, void * uctx) @@ -281,6 +305,7 @@ else log_write(0, LOG_MAIN|LOG_PANIC, "SIGSEGV (maybe attempt to write to immutable memory)"); if (process_info_len > 0) log_write(0, LOG_MAIN|LOG_PANIC, "SIGSEGV (%.*s)", process_info_len, process_info); +stackdump(uctx); signal(SIGSEGV, SIG_DFL); kill(getpid(), sig); } @@ -291,6 +316,7 @@ segv_handler(int sig) log_write(0, LOG_MAIN|LOG_PANIC, "SIGSEGV (maybe attempt to write to immutable memory)"); if (process_info_len > 0) log_write(0, LOG_MAIN|LOG_PANIC, "SIGSEGV (%.*s)", process_info_len, process_info); +stackdump(); signal(SIGSEGV, SIG_DFL); kill(getpid(), sig); } diff --git a/src/src/globals.c b/src/src/globals.c index ff246feb4..70e3f568b 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1207,6 +1207,7 @@ uid_t originator_uid; uschar *override_local_interfaces = NULL; uschar *override_pid_file_path = NULL; +BOOL panic_coredump = FALSE; pcre2_general_context * pcre_gen_ctx = NULL; pcre2_compile_context * pcre_cmp_ctx = NULL; pcre2_match_context * pcre_mtc_ctx = NULL; diff --git a/src/src/globals.h b/src/src/globals.h index fe099e402..ca5b0ccc9 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -792,6 +792,7 @@ extern uid_t originator_uid; /* Uid of ditto */ extern uschar *override_local_interfaces; /* Value of -oX argument */ extern uschar *override_pid_file_path; /* Value of -oP argument */ +extern BOOL panic_coredump; /* SEGV rather than exit, on LOG_PANIC_DIE */ extern pcre2_general_context * pcre_gen_ctx; /* pcre memory management */ extern pcre2_compile_context * pcre_cmp_ctx; extern pcre2_match_context * pcre_mtc_ctx; diff --git a/src/src/log.c b/src/src/log.c index 8ca973f2d..a46d523db 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -1278,7 +1278,10 @@ if (flags & LOG_PANIC) /* Give up if the DIE flag is set */ if ((flags & LOG_PANIC_DIE) != LOG_PANIC) - die(NULL, US"Unexpected failure, please try later"); + if (panic_coredump) + kill(getpid(), SIGSEGV); /* deliberate trap */ + else + die(NULL, US"Unexpected failure, please try later"); } } diff --git a/src/src/readconf.c b/src/src/readconf.c index 06bc50fd8..c74b70b55 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -243,6 +243,7 @@ static optionlist optionlist_config[] = { #ifdef LOOKUP_ORACLE { "oracle_servers", opt_stringptr, {&oracle_servers} }, #endif + { "panic_coredump", opt_bool, {&panic_coredump} }, { "percent_hack_domains", opt_stringptr, {&percent_hack_domains} }, #ifdef EXIM_PERL { "perl_at_start", opt_bool, {&opt_perl_at_start} }, @@ -2667,8 +2668,8 @@ switch(ol->type & opt_mask) break; case opt_bit: - printf("%s%s\n", ((*((int *)value)) & (1 << ((ol->type >> 16) & 31)))? - "" : "no_", name); + printf("%s%s\n", (*((int *)value)) & (1 << ((ol->type >> 16) & 31)) + ? "" : "no_", name); break; case opt_expand_bool: @@ -2693,7 +2694,7 @@ switch(ol->type & opt_mask) case opt_bool: case opt_bool_verify: case opt_bool_set: - printf("%s%s\n", (*((BOOL *)value))? "" : "no_", name); + printf("%s%s\n", *((BOOL *)value) ? "" : "no_", name); break; case opt_func: |