diff --git a/common/daemon.c b/common/daemon.c index cf8f46ae9..fc93c1793 100644 --- a/common/daemon.c +++ b/common/daemon.c @@ -32,17 +32,25 @@ static int backtrace_status(void *unused UNUSED, uintptr_t pc, return 0; } -static void crashdump(int sig) +void send_backtrace(const char *why) { /* We do stderr first, since it's most reliable. */ - warnx("Fatal signal %d (version %s)", sig, version()); + warnx("%s (version %s)", why, version()); if (backtrace_state) backtrace_print(backtrace_state, 0, stderr); /* Now send to parent. */ - bt_print("FATAL SIGNAL %d (version %s)", sig, version()); + bt_print("%s (version %s)", why, version()); if (backtrace_state) backtrace_full(backtrace_state, 0, backtrace_status, NULL, NULL); +} + +static void crashdump(int sig) +{ + char why[100]; + + snprintf(why, 100, "FATAL SIGNAL %d", sig); + send_backtrace(why); /* Probably shouldn't return. */ bt_exit(); @@ -66,6 +74,10 @@ static void crashlog_activate(void) sigaction(SIGSEGV, &sa, NULL); sigaction(SIGBUS, &sa, NULL); } +#else +void send_backtrace(const char *why) +{ +} #endif int daemon_poll(struct pollfd *fds, nfds_t nfds, int timeout) diff --git a/common/daemon.h b/common/daemon.h index 5a0a01fb0..3fbfb570a 100644 --- a/common/daemon.h +++ b/common/daemon.h @@ -11,6 +11,9 @@ void daemon_setup(const char *argv0, /* Exposed for lightningd's use. */ int daemon_poll(struct pollfd *fds, nfds_t nfds, int timeout); +/* Print a backtrace to stderr, and via backtrace_print */ +void send_backtrace(const char *why); + /* Shutdown for a valgrind-clean exit (frees everything) */ void daemon_shutdown(void); diff --git a/common/status.c b/common/status.c index 3eef72264..9c59cf336 100644 --- a/common/status.c +++ b/common/status.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -167,6 +168,10 @@ void status_failed(enum status_failreason reason, const char *fmt, ...) str = tal_vfmt(NULL, fmt, ap); va_end(ap); + /* Give a nice backtrace when this happens! */ + if (reason == STATUS_FAIL_INTERNAL_ERROR) + send_backtrace(str); + status_send_fatal(take(towire_status_fail(NULL, reason, str)), -1, -1); }