summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2022-05-30 10:49:54 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2022-05-30 10:49:54 +0100
commit204a7a2c2e8601558905dc34c576a627045a9f21 (patch)
tree5a6c9e698d05d47ec010d608d28a6dc94110e6bb /src
parentdd4daa8a2ba4986a2fc9bba17251f6955f2332b8 (diff)
panic_coredump option. Bug 2892
Diffstat (limited to 'src')
-rw-r--r--src/src/exim.c34
-rw-r--r--src/src/globals.c1
-rw-r--r--src/src/globals.h1
-rw-r--r--src/src/log.c5
-rw-r--r--src/src/readconf.c7
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: