diff --git a/Makefile b/Makefile index 626dc1451..70143105b 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ endif DEVELOPER := 1 ifeq ($(DEVELOPER),1) -DEV_CFLAGS=-DDEVELOPER=1 +DEV_CFLAGS=-DDEVELOPER=1 -DCCAN_TAL_DEBUG=1 -DCCAN_TAKE_DEBUG=1 else DEV_CFLAGS=-DDEVELOPER=0 endif @@ -143,7 +143,7 @@ ALL_PROGRAMS = CWARNFLAGS := -Werror -Wall -Wundef -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wold-style-definition CDEBUGFLAGS := -std=gnu11 -g -fstack-protector -CFLAGS = $(CWARNFLAGS) $(CDEBUGFLAGS) -I $(CCANDIR) $(EXTERNAL_INCLUDE_FLAGS) -I . $(FEATURES) $(COVFLAGS) $(DEV_CFLAGS) -DSHACHAIN_BITS=48 -DCCAN_TAKE_DEBUG=1 +CFLAGS = $(CWARNFLAGS) $(CDEBUGFLAGS) -I $(CCANDIR) $(EXTERNAL_INCLUDE_FLAGS) -I . $(FEATURES) $(COVFLAGS) $(DEV_CFLAGS) -DSHACHAIN_BITS=48 LDLIBS = -lgmp -lsqlite3 $(COVFLAGS) diff --git a/lightningd/Makefile b/lightningd/Makefile index 0d92e3151..1b1aed7b5 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -66,6 +66,7 @@ LIGHTNINGD_SRC := \ # Source files without corresponding headers LIGHTNINGD_SRC_NOHDR := \ lightningd/dev_ping.c \ + lightningd/memdump.c LIGHTNINGD_OBJS := $(LIGHTNINGD_SRC:.c=.o) $(LIGHTNINGD_SRC_NOHDR:.c=.o) diff --git a/lightningd/memdump.c b/lightningd/memdump.c new file mode 100644 index 000000000..22f9bbdcf --- /dev/null +++ b/lightningd/memdump.c @@ -0,0 +1,63 @@ +/* Only possible if we're in developer mode. */ +#ifdef DEVELOPER +#include +#include + +static void json_add_ptr(struct json_result *response, const char *name, + const void *ptr) +{ + char ptrstr[STR_MAX_CHARS(void *)]; + sprintf(ptrstr, "%p", ptr); + json_add_string(response, name, ptrstr); +} + +static void add_memdump(struct json_result *response, + const char *name, const tal_t *root, + struct command *cmd) +{ + const tal_t *i; + + json_array_start(response, name); + for (i = tal_first(root); i; i = tal_next(i)) { + const char *name = tal_name(i); + + /* Don't try to dump this command! */ + if (i == cmd || i == cmd->jcon) + continue; + + /* Don't dump logs, we know they grow. */ + if (name && streq(name, "struct log_book")) + continue; + + json_object_start(response, NULL); + json_add_ptr(response, "parent", tal_parent(i)); + json_add_ptr(response, "value", i); + if (name) + json_add_string(response, "label", name); + + if (tal_first(i)) + add_memdump(response, "children", i, cmd); + json_object_end(response); + } + json_array_end(response); +} + +static void json_memdump(struct command *cmd, + const char *buffer UNNEEDED, + const jsmntok_t *params UNNEEDED) +{ + struct json_result *response = new_json_result(cmd); + + add_memdump(response, NULL, NULL, cmd); + + command_success(cmd, response); +} + +static const struct json_command dev_memdump_command = { + "dev-memdump", + json_memdump, + "Dump the memory objects currently used", + "Debugging tool for memory leaks" +}; +AUTODATA(json_command, &dev_memdump_command); +#endif /* DEVELOPER */