From edc30b12ea4f1251af6210183622800a7d785b38 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 24 Feb 2017 16:22:56 +1030 Subject: [PATCH] lightningd: --dev-debugger= Or for blackbox tests --gdb1= / --gdb2=. This makes the subdaemon wait as soon as it's execed, so we can attach the debugger. Signed-off-by: Rusty Russell --- daemon/test/scripts/helpers.sh | 18 ++++++++++++------ lightningd/Makefile | 1 + lightningd/debug.c | 21 +++++++++++++++++++++ lightningd/debug.h | 7 +++++++ lightningd/gossip/gossip.c | 3 ++- lightningd/handshake/handshake.c | 4 ++-- lightningd/lightningd.c | 6 +++++- lightningd/lightningd.h | 3 +++ lightningd/opening/opening.c | 3 ++- lightningd/subdaemon.c | 18 +++++++++++++++--- lightningd/subdaemon.h | 3 +++ 11 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 lightningd/debug.c create mode 100644 lightningd/debug.h diff --git a/daemon/test/scripts/helpers.sh b/daemon/test/scripts/helpers.sh index e0463c7c4..17dfc6b32 100644 --- a/daemon/test/scripts/helpers.sh +++ b/daemon/test/scripts/helpers.sh @@ -46,6 +46,12 @@ parse_cmdline() exit 1 fi ;; + x"--gdb1="*) + DAEMON1_EXTRA=--dev-debugger=${1#--gdb1=} + ;; + x"--gdb2="*) + DAEMON2_EXTRA=--dev-debugger=${1#--gdb2=} + ;; x"--reconnect") RECONNECT=reconnect ;; @@ -122,21 +128,21 @@ EOF [ $NUM_LIGHTNINGD = 2 ] || echo port=`findport 4010 $VARIANT` >> $DIR3/config } -# Use DIR REDIR REDIRERR GDBFLAG BINARY +# Use DIR REDIR REDIRERR GDBFLAG BINARY EXTRAARGS start_one_lightningd() { # Need absolute path for re-exec testing. local CMD CMD="$(readlink -f `pwd`/../../$5) --lightning-dir=$1" if [ -n "$4" ]; then - echo Press return once you run: gdb --args $CMD >&2 + echo Press return once you run: gdb --args $CMD $6 >&2 read REPLY else CMD="$PREFIX $CMD" - $CMD > $2 2> $3 & + $CMD $6 > $2 2> $3 & fi - echo $CMD + echo $CMD $6 } start_lightningd() @@ -153,8 +159,8 @@ start_lightningd() SHUTDOWN_BITCOIN=/bin/true fi - LIGHTNINGD1=`start_one_lightningd $DIR1 $REDIR1 $REDIRERR1 "$GDB1" $BINARY` - LIGHTNINGD2=`start_one_lightningd $DIR2 $REDIR2 $REDIRERR2 "$GDB2" $BINARY` + LIGHTNINGD1=`start_one_lightningd $DIR1 $REDIR1 $REDIRERR1 "$GDB1" $BINARY $DAEMON1_EXTRA` + LIGHTNINGD2=`start_one_lightningd $DIR2 $REDIR2 $REDIRERR2 "$GDB2" $BINARY $DAEMON2_EXTRA` [ $NUM_LIGHTNINGD = 2 ] || LIGHTNINGD3=`start_one_lightningd $DIR3 $REDIR3 $REDIRERR3 "$GDB3" $BINARY` if ! check "$LCLI1 getlog 2>/dev/null | $FGREP Hello"; then diff --git a/lightningd/Makefile b/lightningd/Makefile index 1d1f37243..6df64cebd 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -39,6 +39,7 @@ LIGHTNINGD_LIB_SRC := \ lightningd/commit_tx.c \ lightningd/cryptomsg.c \ lightningd/crypto_sync.c \ + lightningd/debug.c \ lightningd/funding_tx.c \ lightningd/htlc_tx.c \ lightningd/key_derive.c \ diff --git a/lightningd/debug.c b/lightningd/debug.c new file mode 100644 index 000000000..66c7af51e --- /dev/null +++ b/lightningd/debug.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include + +void subdaemon_debug(int argc, char *argv[]) +{ + int i; + bool printed = false; + + /* From debugger, tell gdb "return". */ + for (i = 1; i < argc; i++) { + while (streq(argv[i], "--debugger")) { + if (!printed) + fprintf(stderr, "gdb -ex 'attach %u' %s\n", + getpid(), argv[0]); + printed = true; + } + } +} diff --git a/lightningd/debug.h b/lightningd/debug.h new file mode 100644 index 000000000..064a6f152 --- /dev/null +++ b/lightningd/debug.h @@ -0,0 +1,7 @@ +#ifndef LIGHTNING_LIGHTNINGD_DEBUG_H +#define LIGHTNING_LIGHTNINGD_DEBUG_H +#include "config.h" + +void subdaemon_debug(int argc, char *argv[]); + +#endif /* LIGHTNING_LIGHTNINGD_DEBUG_H */ diff --git a/lightningd/gossip/gossip.c b/lightningd/gossip/gossip.c index 1e9fe4de2..fa039734f 100644 --- a/lightningd/gossip/gossip.c +++ b/lightningd/gossip/gossip.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -381,7 +382,7 @@ int main(int argc, char *argv[]) { struct daemon *daemon; - breakpoint(); + subdaemon_debug(argc, argv); if (argc == 2 && streq(argv[1], "--version")) { printf("%s\n", version()); diff --git a/lightningd/handshake/handshake.c b/lightningd/handshake/handshake.c index 4e5abd8ba..3d320ea8b 100644 --- a/lightningd/handshake/handshake.c +++ b/lightningd/handshake/handshake.c @@ -2,7 +2,6 @@ #include "type_to_string.h" #include #include -#include #include #include #include @@ -11,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -979,7 +979,7 @@ int main(int argc, char *argv[]) exit(0); } - breakpoint(); + subdaemon_debug(argc, argv); secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); status_setup(STATUS_FD); diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 869a60217..8c4dbef3a 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -74,6 +74,7 @@ static struct lightningd *new_lightningd(const tal_t *ctx) list_head_init(&ld->peers); ld->peer_counter = 0; ld->bip32_max_index = 0; + ld->dev_debug_subdaemon = NULL; list_head_init(&ld->utxos); ld->dstate.log_book = new_log_book(&ld->dstate, 20*1024*1024,LOG_INFORM); ld->log = ld->dstate.base_log = new_log(&ld->dstate, @@ -175,8 +176,11 @@ int main(int argc, char *argv[]) /* Figure out where we are first. */ ld->daemon_dir = find_my_path(ld, argv[0]); - /* Handle options and config; move to .lightningd */ register_opts(&ld->dstate); + opt_register_arg("--dev-debugger=", opt_subdaemon_debug, NULL, + ld, "Wait for gdb attach at start of "); + + /* Handle options and config; move to .lightningd */ newdir = handle_opts(&ld->dstate, argc, argv); /* Activate crash log now we're in the right place. */ diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h index 0636e0252..bedaa0e11 100644 --- a/lightningd/lightningd.h +++ b/lightningd/lightningd.h @@ -40,6 +40,9 @@ struct lightningd { struct ext_key *bip32_base; u32 bip32_max_index; + /* If we want to debug a subdaemon. */ + const char *dev_debug_subdaemon; + /* UTXOs we have available to spend. */ struct list_head utxos; }; diff --git a/lightningd/opening/opening.c b/lightningd/opening/opening.c index 204e4f424..00e907143 100644 --- a/lightningd/opening/opening.c +++ b/lightningd/opening/opening.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -683,7 +684,7 @@ int main(int argc, char *argv[]) exit(0); } - breakpoint(); + subdaemon_debug(argc, argv); /* We handle write returning errors! */ signal(SIGCHLD, SIG_IGN); diff --git a/lightningd/subdaemon.c b/lightningd/subdaemon.c index 8e3864041..c2ca50e24 100644 --- a/lightningd/subdaemon.c +++ b/lightningd/subdaemon.c @@ -46,7 +46,7 @@ static bool move_fd(int from, int to) } /* We use sockets, not pipes, because fds are bidir. */ -static int subdaemon(const char *dir, const char *name, +static int subdaemon(const char *dir, const char *name, bool debug, int *statusfd, int *reqfd, va_list ap) { int childreq[2], childstatus[2], execfail[2]; @@ -79,6 +79,7 @@ static int subdaemon(const char *dir, const char *name, if (childpid == 0) { int fdnum = 3; long max; + const char *debug_arg = NULL; if (reqfd) close(childreq[0]); @@ -109,7 +110,10 @@ static int subdaemon(const char *dir, const char *name, max = sysconf(_SC_OPEN_MAX); for (fd = fdnum; fd < max; fd++) close(fd); - execl(path_join(NULL, dir, name), name, NULL); + + if (debug) + debug_arg = "--debugger"; + execl(path_join(NULL, dir, name), name, debug_arg, NULL); child_errno_fail: err = errno; @@ -259,9 +263,11 @@ struct subdaemon *new_subdaemon(const tal_t *ctx, va_list ap; struct subdaemon *sd = tal(ctx, struct subdaemon); int req_fd, status_fd; + bool debug; + debug = ld->dev_debug_subdaemon && strends(name,ld->dev_debug_subdaemon); va_start(ap, finished); - sd->pid = subdaemon(ld->daemon_dir, name, &status_fd, + sd->pid = subdaemon(ld->daemon_dir, name, debug, &status_fd, reqname ? &req_fd : NULL, ap); va_end(ap); if (sd->pid == (pid_t)-1) { @@ -383,3 +389,9 @@ void subdaemon_req_(struct subdaemon *sd, list_add_tail(&sd->reqs, &sr->list); io_wake(sd); } + +char *opt_subdaemon_debug(const char *optarg, struct lightningd *ld) +{ + ld->dev_debug_subdaemon = optarg; + return NULL; +} diff --git a/lightningd/subdaemon.h b/lightningd/subdaemon.h index e0d722f36..73b0837b8 100644 --- a/lightningd/subdaemon.h +++ b/lightningd/subdaemon.h @@ -90,4 +90,7 @@ void subdaemon_req_(struct subdaemon *sd, int fd_out, int *fd_in, void (*reqcb)(struct subdaemon *, const u8 *, void *), void *reqcb_data); + +char *opt_subdaemon_debug(const char *optarg, struct lightningd *ld); + #endif /* LIGHTNING_LIGHTNINGD_SUBDAEMON_H */