common/daemon: common routines for all daemons.

In particular, the main daemon and subdaemons share the backtrace code,
with hooks for logging.

The daemon hook inserts the io_poll override, which means we no longer
need io_debug.[ch].  Though most daemons don't need it, they still link
against ccan/io, so it's harmess (suggested by @ZmnSCPxj).

This was tested manually to make sure we get backtraces still.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-03-29 12:36:45 +10:30 committed by Christian Decker
parent 8975fc2ceb
commit 1a4a59d221
24 changed files with 223 additions and 215 deletions

View File

@ -38,6 +38,7 @@ CHANNELD_COMMON_OBJS := \
common/crypto_state.o \ common/crypto_state.o \
common/crypto_sync.o \ common/crypto_sync.o \
common/cryptomsg.o \ common/cryptomsg.o \
common/daemon.o \
common/daemon_conn.o \ common/daemon_conn.o \
common/derive_basepoints.o \ common/derive_basepoints.o \
common/dev_disconnect.o \ common/dev_disconnect.o \
@ -48,7 +49,6 @@ CHANNELD_COMMON_OBJS := \
common/htlc_wire.o \ common/htlc_wire.o \
common/initial_channel.o \ common/initial_channel.o \
common/initial_commit_tx.o \ common/initial_commit_tx.o \
common/io_debug.o \
common/keyset.o \ common/keyset.o \
common/key_derive.o \ common/key_derive.o \
common/memleak.o \ common/memleak.o \

View File

@ -30,7 +30,6 @@
#include <common/derive_basepoints.h> #include <common/derive_basepoints.h>
#include <common/dev_disconnect.h> #include <common/dev_disconnect.h>
#include <common/htlc_tx.h> #include <common/htlc_tx.h>
#include <common/io_debug.h>
#include <common/key_derive.h> #include <common/key_derive.h>
#include <common/msg_queue.h> #include <common/msg_queue.h>
#include <common/peer_billboard.h> #include <common/peer_billboard.h>
@ -2753,6 +2752,6 @@ int main(int argc, char *argv[])
/* We only exit when shutdown is complete. */ /* We only exit when shutdown is complete. */
assert(shutdown_complete(peer)); assert(shutdown_complete(peer));
send_shutdown_complete(peer); send_shutdown_complete(peer);
subdaemon_shutdown(); daemon_shutdown();
return 0; return 0;
} }

View File

@ -46,6 +46,7 @@ CLOSINGD_COMMON_OBJS := \
common/crypto_state.o \ common/crypto_state.o \
common/crypto_sync.o \ common/crypto_sync.o \
common/cryptomsg.o \ common/cryptomsg.o \
common/daemon.o \
common/daemon_conn.o \ common/daemon_conn.o \
common/dev_disconnect.o \ common/dev_disconnect.o \
common/derive_basepoints.o \ common/derive_basepoints.o \

View File

@ -577,7 +577,7 @@ int main(int argc, char *argv[])
wire_sync_write(REQ_FD, wire_sync_write(REQ_FD,
take(towire_closing_complete(NULL, gossip_index))); take(towire_closing_complete(NULL, gossip_index)));
tal_free(ctx); tal_free(ctx);
subdaemon_shutdown(); daemon_shutdown();
return 0; return 0;
} }

View File

@ -8,6 +8,7 @@ COMMON_SRC_NOGEN := \
common/crypto_state.c \ common/crypto_state.c \
common/crypto_sync.c \ common/crypto_sync.c \
common/cryptomsg.c \ common/cryptomsg.c \
common/daemon.c \
common/daemon_conn.c \ common/daemon_conn.c \
common/derive_basepoints.c \ common/derive_basepoints.c \
common/dev_disconnect.c \ common/dev_disconnect.c \
@ -19,7 +20,6 @@ COMMON_SRC_NOGEN := \
common/htlc_wire.c \ common/htlc_wire.c \
common/initial_channel.c \ common/initial_channel.c \
common/initial_commit_tx.c \ common/initial_commit_tx.c \
common/io_debug.c \
common/json.c \ common/json.c \
common/json_escaped.c \ common/json_escaped.c \
common/key_derive.c \ common/key_derive.c \

111
common/daemon.c Normal file
View File

@ -0,0 +1,111 @@
#include <backtrace-supported.h>
#include <backtrace.h>
#include <ccan/err/err.h>
#include <ccan/io/io.h>
#include <ccan/str/str.h>
#include <common/daemon.h>
#include <common/status.h>
#include <common/utils.h>
#include <common/version.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <wally_core.h>
#if BACKTRACE_SUPPORTED
static struct backtrace_state *backtrace_state;
static void (*bt_print)(const char *fmt, ...) PRINTF_FMT(1,2);
static void (*bt_exit)(void);
static int backtrace_status(void *unused UNUSED, uintptr_t pc,
const char *filename, int lineno,
const char *function)
{
bt_print("backtrace: %s:%d (%s) %p",
filename, lineno, function, (void *)pc);
return 0;
}
static void crashdump(int sig)
{
/* We do stderr first, since it's most reliable. */
warnx("Fatal signal %d", sig);
backtrace_print(backtrace_state, 0, stderr);
/* Now send to parent. */
bt_print("FATAL SIGNAL %d", sig);
backtrace_full(backtrace_state, 0, backtrace_status, NULL, NULL);
/* Probably shouldn't return. */
bt_exit();
/* This time it will kill us instantly. */
kill(getpid(), sig);
}
static void crashlog_activate(void)
{
struct sigaction sa;
sa.sa_handler = crashdump;
sigemptyset(&sa.sa_mask);
/* We want to fall through to default handler */
sa.sa_flags = SA_RESETHAND;
sigaction(SIGILL, &sa, NULL);
sigaction(SIGABRT, &sa, NULL);
sigaction(SIGFPE, &sa, NULL);
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGBUS, &sa, NULL);
}
#endif
static int daemon_poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
const char *t;
t = taken_any();
if (t)
errx(1, "Outstanding taken pointers: %s", t);
clean_tmpctx();
return poll(fds, nfds, timeout);
}
void daemon_setup(const char *argv0,
void (*backtrace_print)(const char *fmt, ...),
void (*backtrace_exit)(void))
{
err_set_progname(argv0);
bt_print = backtrace_print;
bt_exit = backtrace_exit;
#if BACKTRACE_SUPPORTED
#if DEVELOPER
/* Suppresses backtrace (breaks valgrind) */
if (!getenv("LIGHTNINGD_DEV_NO_BACKTRACE"))
backtrace_state = backtrace_create_state(argv0, 0, NULL, NULL);
#else
backtrace_state = backtrace_create_state(argv0, 0, NULL, NULL);
#endif
crashlog_activate();
#endif
/* We handle write returning errors! */
signal(SIGPIPE, SIG_IGN);
secp256k1_ctx = wally_get_secp_context();
setup_tmpctx();
io_poll_override(daemon_poll);
}
void daemon_shutdown(void)
{
tal_free(tmpctx);
wally_cleanup(0);
}

13
common/daemon.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef LIGHTNING_COMMON_DAEMON_H
#define LIGHTNING_COMMON_DAEMON_H
#include "config.h"
/* Common setup for all daemons */
void daemon_setup(const char *argv0,
void (*backtrace_print)(const char *fmt, ...),
void (*backtrace_exit)(void));
/* Shutdown for a valgrind-clean exit (frees everything) */
void daemon_shutdown(void);
#endif /* LIGHTNING_COMMON_DAEMON_H */

View File

@ -1,17 +0,0 @@
#include <ccan/err/err.h>
#include <ccan/take/take.h>
#include <common/io_debug.h>
#include <common/utils.h>
int debug_poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
const char *t;
t = taken_any();
if (t)
errx(1, "Outstanding taken pointers: %s", t);
clean_tmpctx();
return poll(fds, nfds, timeout);
}

View File

@ -1,9 +0,0 @@
#ifndef LIGHTNING_COMMON_IO_DEBUG_H
#define LIGHTNING_COMMON_IO_DEBUG_H
#include "config.h"
#include <poll.h>
/* Replacement poll which checks for memory leaks in middle of ccan/io loop. */
int debug_poll(struct pollfd *fds, nfds_t nfds, int timeout);
#endif /* LIGHTNING_COMMON_IO_DEBUG_H */

View File

@ -1,7 +1,3 @@
#include <backtrace-supported.h>
#include <backtrace.h>
#include <ccan/err/err.h>
#include <ccan/str/str.h>
#include <common/dev_disconnect.h> #include <common/dev_disconnect.h>
#include <common/status.h> #include <common/status.h>
#include <common/subdaemon.h> #include <common/subdaemon.h>
@ -14,48 +10,20 @@
#include <unistd.h> #include <unistd.h>
#include <wally_core.h> #include <wally_core.h>
#if BACKTRACE_SUPPORTED static void status_backtrace_print(const char *fmt, ...)
static struct backtrace_state *backtrace_state;
static int backtrace_status(void *unused UNUSED, uintptr_t pc,
const char *filename, int lineno,
const char *function)
{ {
fprintf(stderr, "backtrace: %s:%d (%s) %p\n", va_list ap;
filename, lineno, function, (void *)pc);
status_trace("backtrace: %s:%d (%s) %p", va_start(ap, fmt);
filename, lineno, function, (void *)pc); status_vfmt(LOG_BROKEN, fmt, ap);
return 0; va_end(ap);
} }
static void crashdump(int sig) static void status_backtrace_exit(void)
{ {
/* We do stderr first, since it's most reliable. */ status_failed(STATUS_FAIL_INTERNAL_ERROR, "FATAL SIGNAL");
warnx("Fatal signal %d", sig);
backtrace_print(backtrace_state, 0, stderr);
/* Now send to parent. */
backtrace_full(backtrace_state, 0, backtrace_status, NULL, NULL);
status_failed(STATUS_FAIL_INTERNAL_ERROR, "FATAL SIGNAL %d", sig);
} }
static void crashlog_activate(void)
{
struct sigaction sa;
sa.sa_handler = crashdump;
sigemptyset(&sa.sa_mask);
/* We want to fall through to default handler */
sa.sa_flags = SA_RESETHAND;
sigaction(SIGILL, &sa, NULL);
sigaction(SIGABRT, &sa, NULL);
sigaction(SIGFPE, &sa, NULL);
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGBUS, &sa, NULL);
}
#endif
#if DEVELOPER #if DEVELOPER
extern volatile bool debugger_connected; extern volatile bool debugger_connected;
volatile bool debugger_connected; volatile bool debugger_connected;
@ -68,18 +36,6 @@ void subdaemon_setup(int argc, char *argv[])
exit(0); exit(0);
} }
err_set_progname(argv[0]);
#if BACKTRACE_SUPPORTED
backtrace_state = backtrace_create_state(argv[0], 0, NULL, NULL);
crashlog_activate();
#endif
/* We handle write returning errors! */
signal(SIGPIPE, SIG_IGN);
secp256k1_ctx = wally_get_secp_context();
setup_tmpctx();
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
if (streq(argv[i], "--log-io")) if (streq(argv[i], "--log-io"))
logging_io = true; logging_io = true;
@ -100,10 +56,7 @@ void subdaemon_setup(int argc, char *argv[])
} }
} }
#endif #endif
daemon_setup(argv[0], status_backtrace_print, status_backtrace_exit);
} }
void subdaemon_shutdown(void)
{
tal_free(tmpctx);
wally_cleanup(0);
}

View File

@ -1,10 +1,9 @@
#ifndef LIGHTNING_COMMON_SUBDAEMON_H #ifndef LIGHTNING_COMMON_SUBDAEMON_H
#define LIGHTNING_COMMON_SUBDAEMON_H #define LIGHTNING_COMMON_SUBDAEMON_H
#include "config.h" #include "config.h"
#include <common/daemon.h>
/* daemon_setup, but for subdaemons */
void subdaemon_setup(int argc, char *argv[]); void subdaemon_setup(int argc, char *argv[]);
/* Shutdown for a valgrind-clean exit (frees everything) */
void subdaemon_shutdown(void);
#endif /* LIGHTNING_COMMON_SUBDAEMON_H */ #endif /* LIGHTNING_COMMON_SUBDAEMON_H */

View File

@ -39,11 +39,11 @@ GOSSIPD_COMMON_OBJS := \
common/crypto_state.o \ common/crypto_state.o \
common/crypto_sync.o \ common/crypto_sync.o \
common/cryptomsg.o \ common/cryptomsg.o \
common/daemon.o \
common/daemon_conn.o \ common/daemon_conn.o \
common/dev_disconnect.o \ common/dev_disconnect.o \
common/features.o \ common/features.o \
common/gen_status_wire.o \ common/gen_status_wire.o \
common/io_debug.o \
common/msg_queue.o \ common/msg_queue.o \
common/ping.o \ common/ping.o \
common/pseudorand.o \ common/pseudorand.o \

View File

@ -17,7 +17,6 @@
#include <common/cryptomsg.h> #include <common/cryptomsg.h>
#include <common/daemon_conn.h> #include <common/daemon_conn.h>
#include <common/features.h> #include <common/features.h>
#include <common/io_debug.h>
#include <common/ping.h> #include <common/ping.h>
#include <common/status.h> #include <common/status.h>
#include <common/subdaemon.h> #include <common/subdaemon.h>
@ -2118,7 +2117,6 @@ int main(int argc, char *argv[])
struct daemon *daemon; struct daemon *daemon;
subdaemon_setup(argc, argv); subdaemon_setup(argc, argv);
io_poll_override(debug_poll);
daemon = tal(NULL, struct daemon); daemon = tal(NULL, struct daemon);
list_head_init(&daemon->peers); list_head_init(&daemon->peers);
@ -2147,7 +2145,7 @@ int main(int argc, char *argv[])
timer_expired(daemon, expired); timer_expired(daemon, expired);
} }
} }
subdaemon_shutdown(); daemon_shutdown();
return 0; return 0;
} }
#endif #endif

View File

@ -21,12 +21,12 @@ LIGHTNINGD_HSM_OBJS := $(LIGHTNINGD_HSM_SRC:.c=.o)
# Common source we use. # Common source we use.
HSMD_COMMON_OBJS := \ HSMD_COMMON_OBJS := \
common/bip32.o \ common/bip32.o \
common/daemon.o \
common/daemon_conn.o \ common/daemon_conn.o \
common/derive_basepoints.o \ common/derive_basepoints.o \
common/funding_tx.o \ common/funding_tx.o \
common/gen_status_wire.o \ common/gen_status_wire.o \
common/hash_u5.o \ common/hash_u5.o \
common/io_debug.o \
common/key_derive.o \ common/key_derive.o \
common/msg_queue.o \ common/msg_queue.o \
common/permute_tx.o \ common/permute_tx.o \

View File

@ -18,7 +18,6 @@
#include <common/derive_basepoints.h> #include <common/derive_basepoints.h>
#include <common/funding_tx.h> #include <common/funding_tx.h>
#include <common/hash_u5.h> #include <common/hash_u5.h>
#include <common/io_debug.h>
#include <common/key_derive.h> #include <common/key_derive.h>
#include <common/status.h> #include <common/status.h>
#include <common/subdaemon.h> #include <common/subdaemon.h>
@ -829,7 +828,6 @@ int main(int argc, char *argv[])
struct client *client; struct client *client;
subdaemon_setup(argc, argv); subdaemon_setup(argc, argv);
io_poll_override(debug_poll);
client = new_client(NULL, NULL, HSM_CAP_MASTER | HSM_CAP_SIGN_GOSSIP, handle_client, STDIN_FILENO); client = new_client(NULL, NULL, HSM_CAP_MASTER | HSM_CAP_SIGN_GOSSIP, handle_client, STDIN_FILENO);
@ -842,7 +840,7 @@ int main(int argc, char *argv[])
/* When conn closes, everything is freed. */ /* When conn closes, everything is freed. */
tal_steal(client->dc.conn, client); tal_steal(client->dc.conn, client);
io_loop(NULL, NULL); io_loop(NULL, NULL);
subdaemon_shutdown(); daemon_shutdown();
return 0; return 0;
} }

View File

@ -20,6 +20,7 @@ LIGHTNINGD_COMMON_OBJS := \
common/channel_config.o \ common/channel_config.o \
common/configdir.o \ common/configdir.o \
common/crypto_state.o \ common/crypto_state.o \
common/daemon.o \
common/derive_basepoints.o \ common/derive_basepoints.o \
common/features.o \ common/features.o \
common/funding_tx.o \ common/funding_tx.o \
@ -28,7 +29,6 @@ LIGHTNINGD_COMMON_OBJS := \
common/hash_u5.o \ common/hash_u5.o \
common/htlc_state.o \ common/htlc_state.o \
common/htlc_wire.o \ common/htlc_wire.o \
common/io_debug.o \
common/key_derive.o \ common/key_derive.o \
common/json.o \ common/json.o \
common/json_escaped.o \ common/json_escaped.o \

View File

@ -18,7 +18,7 @@
#include <ccan/tal/grab_file/grab_file.h> #include <ccan/tal/grab_file/grab_file.h>
#include <ccan/tal/path/path.h> #include <ccan/tal/path/path.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <common/io_debug.h> #include <common/daemon.h>
#include <common/memleak.h> #include <common/memleak.h>
#include <common/timeout.h> #include <common/timeout.h>
#include <common/utils.h> #include <common/utils.h>
@ -277,21 +277,8 @@ int main(int argc, char *argv[])
bool newdir; bool newdir;
u32 first_blocknum; u32 first_blocknum;
err_set_progname(argv[0]); daemon_setup(argv[0], log_backtrace_print, log_backtrace_exit);
#if DEVELOPER
/* Suppresses backtrace (breaks valgrind) */
if (!getenv("LIGHTNINGD_DEV_NO_BACKTRACE"))
backtrace_state = backtrace_create_state(argv[0], 0, NULL, NULL);
#else
backtrace_state = backtrace_create_state(argv[0], 0, NULL, NULL);
#endif
ld = new_lightningd(NULL); ld = new_lightningd(NULL);
secp256k1_ctx = wally_get_secp_context();
setup_tmpctx();
io_poll_override(debug_poll);
/* Figure out where our daemons are first. */ /* Figure out where our daemons are first. */
ld->daemon_dir = find_daemon_dir(ld, argv[0]); ld->daemon_dir = find_daemon_dir(ld, argv[0]);
@ -399,7 +386,7 @@ int main(int argc, char *argv[])
begin_topology(ld->topology); begin_topology(ld->topology);
/* Activate crash log now we're not reporting startup failures. */ /* Activate crash log now we're not reporting startup failures. */
crashlog_activate(argv[0], ld->log); crashlog = ld->log;
for (;;) { for (;;) {
struct timer *expired; struct timer *expired;
@ -426,7 +413,6 @@ int main(int argc, char *argv[])
#if DEVELOPER #if DEVELOPER
memleak_cleanup(); memleak_cleanup();
#endif #endif
take_cleanup(); daemon_shutdown();
wally_cleanup(0);
return 0; return 0;
} }

View File

@ -23,6 +23,9 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
/* Once we're up and running, this is set up. */
struct log *crashlog;
struct log_entry { struct log_entry {
struct list_node list; struct list_node list;
struct timeabs time; struct timeabs time;
@ -464,86 +467,19 @@ void opt_register_logging(struct lightningd *ld)
"log to file instead of stdout"); "log to file instead of stdout");
} }
#if BACKTRACE_SUPPORTED void log_backtrace_print(const char *fmt, ...)
static int log_backtrace(void *log, uintptr_t pc,
const char *filename, int lineno,
const char *function)
{ {
log_broken(log, "backtrace: %s:%u (%s) %p", va_list ap;
filename, lineno, function, (void *)pc);
return 0; if (!crashlog)
return;
va_start(ap, fmt);
logv(crashlog, LOG_BROKEN, fmt, ap);
va_end(ap);
} }
static void log_backtrace_error(void *log, const char *msg, static void log_dump_to_file(int fd, const struct log_book *lr)
int errnum)
{
log_broken(log, "error getting backtrace: %s (%d)",
msg, errnum);
}
static struct log *crashlog;
/* FIXME: Dump peer logs! */
static void log_crash(int sig)
{
const char *logfile = NULL;
if (sig) {
log_broken(crashlog, "FATAL SIGNAL %i RECEIVED", sig);
if (backtrace_state)
backtrace_full(backtrace_state, 0, log_backtrace, log_backtrace_error,
crashlog);
}
if (crashlog->lr->print == log_to_stdout) {
int fd;
/* We expect to be in config dir. */
logfile = "crash.log";
fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600);
if (fd < 0) {
logfile = "/tmp/lightning-crash.log";
fd = open(logfile, O_WRONLY|O_CREAT, 0600);
}
/* Dump entire log. */
if (fd >= 0) {
log_dump_to_file(fd, crashlog->lr);
close(fd);
} else
logfile = NULL;
}
if (sig) {
fprintf(stderr, "Fatal signal %d. ", sig);
if (backtrace_state)
backtrace_print(backtrace_state, 0, stderr);
}
if (logfile)
fprintf(stderr, "Log dumped in %s", logfile);
fprintf(stderr, "\n");
}
#endif
void crashlog_activate(const char *argv0 UNUSED, struct log *log)
{
#if BACKTRACE_SUPPORTED
struct sigaction sa;
crashlog = log;
sa.sa_handler = log_crash;
sigemptyset(&sa.sa_mask);
/* We want to fall through to default handler */
sa.sa_flags = SA_RESETHAND;
sigaction(SIGILL, &sa, NULL);
sigaction(SIGABRT, &sa, NULL);
sigaction(SIGFPE, &sa, NULL);
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGBUS, &sa, NULL);
#endif
}
void log_dump_to_file(int fd, const struct log_book *lr)
{ {
const struct log_entry *i; const struct log_entry *i;
char buf[100]; char buf[100];
@ -571,6 +507,34 @@ void log_dump_to_file(int fd, const struct log_book *lr)
write_all(fd, "\n\n", strlen("\n\n")); write_all(fd, "\n\n", strlen("\n\n"));
} }
/* FIXME: Dump peer logs! */
void log_backtrace_exit(void)
{
if (!crashlog)
return;
/* If we're not already pointing at a log file, make one */
if (crashlog->lr->print == log_to_stdout) {
const char *logfile = NULL;
int fd;
/* We expect to be in config dir. */
logfile = "crash.log";
fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600);
if (fd < 0) {
logfile = "/tmp/lightning-crash.log";
fd = open(logfile, O_WRONLY|O_CREAT, 0600);
}
/* Dump entire log. */
if (fd >= 0) {
log_dump_to_file(fd, crashlog->lr);
close(fd);
fprintf(stderr, "Log dumped in %s\n", logfile);
}
}
}
void fatal(const char *fmt, ...) void fatal(const char *fmt, ...)
{ {
va_list ap; va_list ap;
@ -580,15 +544,12 @@ void fatal(const char *fmt, ...)
fprintf(stderr, "\n"); fprintf(stderr, "\n");
va_end(ap); va_end(ap);
#if BACKTRACE_SUPPORTED if (!crashlog)
/* Early on, we just dump errors to stderr. */ exit(1);
if (crashlog) {
va_start(ap, fmt); va_start(ap, fmt);
logv(crashlog, LOG_BROKEN, fmt, ap); logv(crashlog, LOG_BROKEN, fmt, ap);
va_end(ap); va_end(ap);
log_crash(0);
}
#endif
abort(); abort();
} }

View File

@ -87,15 +87,17 @@ void log_each_line_(const struct log_book *lr,
void *arg); void *arg);
void log_dump_to_file(int fd, const struct log_book *lr);
void opt_register_logging(struct lightningd *ld); void opt_register_logging(struct lightningd *ld);
void crashlog_activate(const char *argv0, struct log *log);
char *arg_log_to_file(const char *arg, struct lightningd *ld); char *arg_log_to_file(const char *arg, struct lightningd *ld);
/* Before the crashlog is activated, just prints to stderr. */ /* Once this is set, we dump fatal with a backtrace to this log */
extern struct log *crashlog;
void NORETURN PRINTF_FMT(1,2) fatal(const char *fmt, ...); void NORETURN PRINTF_FMT(1,2) fatal(const char *fmt, ...);
void log_backtrace_print(const char *fmt, ...);
void log_backtrace_exit(void);
/* Adds an array showing log entries */ /* Adds an array showing log entries */
void json_add_log(struct json_result *result, void json_add_log(struct json_result *result,
const struct log_book *lr, enum log_level minlevel); const struct log_book *lr, enum log_level minlevel);

View File

@ -10,9 +10,15 @@ void activate_peers(struct lightningd *ld UNNEEDED)
/* Generated stub for begin_topology */ /* Generated stub for begin_topology */
void begin_topology(struct chain_topology *topo UNNEEDED) void begin_topology(struct chain_topology *topo UNNEEDED)
{ fprintf(stderr, "begin_topology called!\n"); abort(); } { fprintf(stderr, "begin_topology called!\n"); abort(); }
/* Generated stub for crashlog_activate */ /* Could not find declaration for crashlog */
void crashlog_activate(const char *argv0 UNNEEDED, struct log *log UNNEEDED) /* Generated stub for daemon_setup */
{ fprintf(stderr, "crashlog_activate called!\n"); abort(); } void daemon_setup(const char *argv0 UNNEEDED,
void (*backtrace_print)(const char *fmt UNNEEDED, ...) UNNEEDED,
void (*backtrace_exit)(void))
{ fprintf(stderr, "daemon_setup called!\n"); abort(); }
/* Generated stub for daemon_shutdown */
void daemon_shutdown(void)
{ fprintf(stderr, "daemon_shutdown called!\n"); abort(); }
/* Generated stub for db_begin_transaction_ */ /* Generated stub for db_begin_transaction_ */
void db_begin_transaction_(struct db *db UNNEEDED, const char *location UNNEEDED) void db_begin_transaction_(struct db *db UNNEEDED, const char *location UNNEEDED)
{ fprintf(stderr, "db_begin_transaction_ called!\n"); abort(); } { fprintf(stderr, "db_begin_transaction_ called!\n"); abort(); }
@ -28,9 +34,6 @@ s64 db_get_intvar(struct db *db UNNEEDED, char *varname UNNEEDED, s64 defval UNN
/* Generated stub for db_reopen_after_fork */ /* Generated stub for db_reopen_after_fork */
void db_reopen_after_fork(struct db *db UNNEEDED) void db_reopen_after_fork(struct db *db UNNEEDED)
{ fprintf(stderr, "db_reopen_after_fork called!\n"); abort(); } { fprintf(stderr, "db_reopen_after_fork called!\n"); abort(); }
/* Generated stub for debug_poll */
int debug_poll(struct pollfd *fds UNNEEDED, nfds_t nfds UNNEEDED, int timeout UNNEEDED)
{ fprintf(stderr, "debug_poll called!\n"); abort(); }
/* Generated stub for fatal */ /* Generated stub for fatal */
void fatal(const char *fmt UNNEEDED, ...) void fatal(const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "fatal called!\n"); abort(); } { fprintf(stderr, "fatal called!\n"); abort(); }
@ -56,6 +59,12 @@ struct json_escaped *json_escape(const tal_t *ctx UNNEEDED, const char *str TAKE
void log_(struct log *log UNNEEDED, enum log_level level UNNEEDED, const char *fmt UNNEEDED, ...) void log_(struct log *log UNNEEDED, enum log_level level UNNEEDED, const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "log_ called!\n"); abort(); } { fprintf(stderr, "log_ called!\n"); abort(); }
/* Generated stub for log_backtrace_exit */
void log_backtrace_exit(void)
{ fprintf(stderr, "log_backtrace_exit called!\n"); abort(); }
/* Generated stub for log_backtrace_print */
void log_backtrace_print(const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "log_backtrace_print called!\n"); abort(); }
/* Generated stub for new_log */ /* Generated stub for new_log */
struct log *new_log(const tal_t *ctx UNNEEDED, struct log_book *record UNNEEDED, const char *fmt UNNEEDED, ...) struct log *new_log(const tal_t *ctx UNNEEDED, struct log_book *record UNNEEDED, const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "new_log called!\n"); abort(); } { fprintf(stderr, "new_log called!\n"); abort(); }
@ -141,6 +150,8 @@ char *opt_subd_dev_disconnect(const char *optarg UNNEEDED, struct lightningd *ld
{ fprintf(stderr, "opt_subd_dev_disconnect called!\n"); abort(); } { fprintf(stderr, "opt_subd_dev_disconnect called!\n"); abort(); }
#endif #endif
struct log *crashlog;
#undef main #undef main
int main(int argc UNUSED, char *argv[] UNUSED) int main(int argc UNUSED, char *argv[] UNUSED)
{ {

View File

@ -47,6 +47,7 @@ $(LIGHTNINGD_ONCHAIN_OBJS): $(LIGHTNINGD_HEADERS)
# Common source we use. # Common source we use.
ONCHAIND_COMMON_OBJS := \ ONCHAIND_COMMON_OBJS := \
common/daemon.o \
common/daemon_conn.o \ common/daemon_conn.o \
common/derive_basepoints.o \ common/derive_basepoints.o \
common/dev_disconnect.o \ common/dev_disconnect.o \

View File

@ -2315,7 +2315,7 @@ int main(int argc, char *argv[])
/* We're done! */ /* We're done! */
tal_free(ctx); tal_free(ctx);
subdaemon_shutdown(); daemon_shutdown();
return 0; return 0;
} }

View File

@ -40,6 +40,7 @@ OPENINGD_COMMON_OBJS := \
common/crypto_state.o \ common/crypto_state.o \
common/crypto_sync.o \ common/crypto_sync.o \
common/cryptomsg.o \ common/cryptomsg.o \
common/daemon.o \
common/daemon_conn.o \ common/daemon_conn.o \
common/derive_basepoints.o \ common/derive_basepoints.o \
common/dev_disconnect.o \ common/dev_disconnect.o \

View File

@ -776,7 +776,7 @@ int main(int argc, char *argv[])
status_trace("Sent %s with fd", status_trace("Sent %s with fd",
opening_wire_type_name(fromwire_peektype(msg))); opening_wire_type_name(fromwire_peektype(msg)));
tal_free(state); tal_free(state);
subdaemon_shutdown(); daemon_shutdown();
return 0; return 0;
} }
#endif /* TESTING */ #endif /* TESTING */