Browse Source

pytest: backtrace on internal errors in subdaemons.

A backtrace which makes it much easier to figure out what's happening.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
pr-2587
Rusty Russell 6 years ago
parent
commit
e847ca221a
  1. 18
      common/daemon.c
  2. 3
      common/daemon.h
  3. 5
      common/status.c

18
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)

3
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);

5
common/status.c

@ -5,6 +5,7 @@
#include <ccan/fdpass/fdpass.h>
#include <ccan/read_write_all/read_write_all.h>
#include <ccan/tal/str/str.h>
#include <common/daemon.h>
#include <common/daemon_conn.h>
#include <common/gen_status_wire.h>
#include <common/status.h>
@ -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);
}

Loading…
Cancel
Save