lightningd: --dev-debugger=<subdaemon>

Or for blackbox tests --gdb1=<subdaemon> / --gdb2=<subdaemon>.

This makes the subdaemon wait as soon as it's execed, so we can attach
the debugger.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2017-02-24 16:22:56 +10:30
parent a72dd8d9de
commit edc30b12ea
11 changed files with 73 additions and 14 deletions

View File

@ -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

View File

@ -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 \

21
lightningd/debug.c Normal file
View File

@ -0,0 +1,21 @@
#include <ccan/str/str.h>
#include <lightningd/debug.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
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;
}
}
}

7
lightningd/debug.h Normal file
View File

@ -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 */

View File

@ -16,6 +16,7 @@
#include <fcntl.h>
#include <inttypes.h>
#include <lightningd/cryptomsg.h>
#include <lightningd/debug.h>
#include <lightningd/gossip/gen_gossip_control_wire.h>
#include <lightningd/gossip/gen_gossip_status_wire.h>
#include <secp256k1_ecdh.h>
@ -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());

View File

@ -2,7 +2,6 @@
#include "type_to_string.h"
#include <assert.h>
#include <bitcoin/privkey.h>
#include <ccan/breakpoint/breakpoint.h>
#include <ccan/build_assert/build_assert.h>
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
#include <ccan/endian/endian.h>
@ -11,6 +10,7 @@
#include <ccan/read_write_all/read_write_all.h>
#include <ccan/short_types/short_types.h>
#include <errno.h>
#include <lightningd/debug.h>
#include <lightningd/handshake/gen_handshake_control_wire.h>
#include <lightningd/handshake/gen_handshake_status_wire.h>
#include <lightningd/hsm/client.h>
@ -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);

View File

@ -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=<subdaemon>", opt_subdaemon_debug, NULL,
ld, "Wait for gdb attach at start of <subdaemon>");
/* Handle options and config; move to .lightningd */
newdir = handle_opts(&ld->dstate, argc, argv);
/* Activate crash log now we're in the right place. */

View File

@ -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;
};

View File

@ -11,6 +11,7 @@
#include <lightningd/channel.h>
#include <lightningd/commit_tx.h>
#include <lightningd/crypto_sync.h>
#include <lightningd/debug.h>
#include <lightningd/key_derive.h>
#include <lightningd/opening/gen_opening_control_wire.h>
#include <lightningd/opening/gen_opening_status_wire.h>
@ -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);

View File

@ -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;
}

View File

@ -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 */