From a9f26b7d07799236991ae727bcc10879cb167cac Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 21 Sep 2023 15:06:26 +0930 Subject: [PATCH] common/daemon.c: remove #ifdef DEVELOPER in favor of runtime flag. Also requires us to expose memleak when !DEVELOPER, however we only ever used the memleak tracking when the LIGHTNINGD_DEV_MEMLEAK environment variable was set, so keep that. Signed-off-by: Rusty Russell --- channeld/full_channel.c | 2 - common/daemon.c | 91 ++++++++++++++------------- common/daemon.h | 5 +- common/memleak.c | 17 ++--- common/memleak.h | 8 --- common/status.c | 2 - common/status.h | 2 - common/subdaemon.c | 8 ++- common/subdaemon.h | 4 +- connectd/connectd.c | 25 ++++---- connectd/connectd.h | 3 + gossipd/routing.c | 2 - lightningd/jsonrpc.c | 2 - lightningd/lightningd.c | 4 -- lightningd/plugin.c | 2 - onchaind/test/run-grind_feerate-bug.c | 2 +- onchaind/test/run-grind_feerate.c | 2 +- plugins/bkpr/test/run-bkpr_db.c | 6 +- plugins/bkpr/test/run-recorder.c | 6 +- plugins/libplugin.c | 39 ++++++------ plugins/libplugin.h | 7 ++- 21 files changed, 109 insertions(+), 130 deletions(-) diff --git a/channeld/full_channel.c b/channeld/full_channel.c index 888cf86f9..57115c7a3 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -18,13 +18,11 @@ /* Needs to be at end, since it doesn't include its own hdrs */ #include "full_channel_error_names_gen.h" -#if DEVELOPER static void memleak_help_htlcmap(struct htable *memtable, struct htlc_map *htlcs) { memleak_scan_htable(memtable, &htlcs->raw); } -#endif /* DEVELOPER */ /* This is a dangerous thing! Because we apply HTLCs in many places * in bulk, we can temporarily go negative. You must check balance_ok() diff --git a/common/daemon.c b/common/daemon.c index e8f40f534..1ccc4171d 100644 --- a/common/daemon.c +++ b/common/daemon.c @@ -96,34 +96,7 @@ static void crashlog_activate(void) sigaction(SIGSEGV, &sa, NULL); sigaction(SIGBUS, &sa, NULL); } -#else -void send_backtrace(const char *why) -{ -} -const char *backtrace_symname(const tal_t *ctx, const void *addr) -{ - return "unknown (backtrace unsupported)"; -} -#endif - -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); - - if (wally_tal_ctx) - errx(1, "Outstanding tal_wally_start!"); - - clean_tmpctx(); - - return poll(fds, nfds, timeout); -} - -#if DEVELOPER && BACKTRACE_SUPPORTED static void steal_notify(tal_t *child, enum tal_notify_type n, tal_t *newparent) { tal_t *p = newparent; @@ -154,8 +127,33 @@ static void remove_steal_notifiers(void) /* We remove this from root, assuming everything else freed. */ tal_del_notifier(NULL, add_steal_notifier); } +#else +void send_backtrace(const char *why) +{ +} + +const char *backtrace_symname(const tal_t *ctx, const void *addr) +{ + return "unknown (backtrace unsupported)"; +} #endif +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); + + if (wally_tal_ctx) + errx(1, "Outstanding tal_wally_start!"); + + clean_tmpctx(); + + return poll(fds, nfds, timeout); +} + void daemon_setup(const char *argv0, void (*backtrace_print)(const char *fmt, ...), void (*backtrace_exit)(void)) @@ -164,22 +162,14 @@ void daemon_setup(const char *argv0, #if BACKTRACE_SUPPORTED bt_print = backtrace_print; bt_exit = backtrace_exit; -#if DEVELOPER + /* Suppresses backtrace (breaks valgrind) */ if (!getenv("LIGHTNINGD_DEV_NO_BACKTRACE")) backtrace_state = backtrace_create_state(argv0, 0, NULL, NULL); - add_steal_notifiers(NULL); -#else - backtrace_state = backtrace_create_state(argv0, 0, NULL, NULL); -#endif crashlog_activate(); #endif -#if DEVELOPER - /* This has significant overhead, so we only enable it if told */ - if (getenv("LIGHTNINGD_DEV_MEMLEAK")) - memleak_init(); -#endif + memleak_init(); /* We handle write returning errors! */ signal(SIGPIPE, SIG_IGN); @@ -191,18 +181,27 @@ void daemon_shutdown(void) { common_shutdown(); -#if DEVELOPER && BACKTRACE_SUPPORTED +#if BACKTRACE_SUPPORTED + /* Harmless if it wasn't applied */ remove_steal_notifiers(); #endif } -void daemon_maybe_debug(char *argv[]) +bool daemon_developer_mode(char *argv[]) { -#if DEVELOPER - for (int i = 1; argv[i]; i++) { - if (!streq(argv[i], "--debugger")) - continue; + bool developer = false, debug = false; + for (int i = 1; argv[i]; i++) { + if (streq(argv[i], "--debugger")) + debug = true; + else if (streq(argv[i], "--developer")) + developer = true; + } + + if (!developer) + return false; + + if (debug) { /* Don't let this mess up stdout, so redir to /dev/null */ char *cmd = tal_fmt(NULL, "${DEBUG_TERM:-gnome-terminal --} gdb -ex 'attach %u' %s >/dev/null &", getpid(), argv[0]); fprintf(stderr, "Running %s\n", cmd); @@ -214,5 +213,9 @@ void daemon_maybe_debug(char *argv[]) /* Continue in the debugger. */ kill(getpid(), SIGSTOP); } -#endif /* DEVELOPER */ + + /* This checks for any tal_steal loops! */ + add_steal_notifiers(NULL); + + return true; } diff --git a/common/daemon.h b/common/daemon.h index 2db8cf437..1c9013b86 100644 --- a/common/daemon.h +++ b/common/daemon.h @@ -21,7 +21,8 @@ const char *backtrace_symname(const tal_t *ctx, const void *addr); /* Shutdown for a valgrind-clean exit (frees everything) */ void daemon_shutdown(void); -/* Kick in a debugger if they set --debugger */ -void daemon_maybe_debug(char *argv[]); +/* If --developer is set, set up extra developer checks, kick in a + * debugger if they set --debugger, and return true. */ +bool daemon_developer_mode(char *argv[]); #endif /* LIGHTNING_COMMON_DAEMON_H */ diff --git a/common/memleak.c b/common/memleak.c index 9e778c28d..fa6ee54b0 100644 --- a/common/memleak.c +++ b/common/memleak.c @@ -7,7 +7,7 @@ * but tal hierarchies tends to get freed at exit, so we need something * more sophisticated). * - * Memleak detection is only active if DEVELOPER is set. It does several + * Memleak detection is only active if $LIGHTNINGD_DEV_MEMLEAK is set. It does several * things: * 1. attaches a backtrace list to every allocation, so we can tell * where it came from. @@ -32,7 +32,6 @@ struct backtrace_state *backtrace_state; -#if DEVELOPER static bool memleak_track; struct memleak_helper { @@ -324,9 +323,11 @@ struct htable *memleak_start(const tal_t *ctx) void memleak_init(void) { - memleak_track = true; - if (backtrace_state) - add_backtrace_notifiers(NULL); + if (getenv("LIGHTNINGD_DEV_MEMLEAK")) { + memleak_track = true; + if (backtrace_state) + add_backtrace_notifiers(NULL); + } } static int dump_syminfo(void *data, uintptr_t pc UNUSED, @@ -381,9 +382,3 @@ bool dump_memleak(struct htable *memtable, return found_leak; } -#else /* !DEVELOPER */ -void *notleak_(void *ptr, bool plus_children UNNEEDED) -{ - return ptr; -} -#endif /* !DEVELOPER */ diff --git a/common/memleak.h b/common/memleak.h index e28ae53bf..f12c57be0 100644 --- a/common/memleak.h +++ b/common/memleak.h @@ -38,7 +38,6 @@ void memleak_init(void); void *notleak_(void *ptr, bool plus_children); -#if DEVELOPER /** * memleak_add_helper: help memleak look inside this tal object * @p: the tal object @@ -55,10 +54,6 @@ void *notleak_(void *ptr, bool plus_children); typesafe_cb_preargs(void, const tal_t *, \ (cb), (p), \ struct htable *)) -#else -/* Don't refer to cb at all if !DEVELOPER */ -#define memleak_add_helper(p, cb) -#endif /* For update-mock: memleak_add_helper_ mock empty */ void memleak_add_helper_(const tal_t *p, void (*cb)(struct htable *memtable, @@ -147,10 +142,7 @@ const void *memleak_get(struct htable *memtable, const uintptr_t **backtrace); extern struct backtrace_state *backtrace_state; -#if DEVELOPER -/* Only defined if DEVELOPER */ bool dump_memleak(struct htable *memtable, void PRINTF_FMT(1,2) (*print)(const char *fmt, ...)); -#endif #endif /* LIGHTNING_COMMON_MEMLEAK_H */ diff --git a/common/status.c b/common/status.c index d2d770523..e17c06473 100644 --- a/common/status.c +++ b/common/status.c @@ -234,7 +234,6 @@ void master_badmsg(u32 type_expected, const u8 *msg) type_expected, tal_hex(tmpctx, msg)); } -#if DEVELOPER /* Print BROKEN status: callback for dump_memleak. */ void memleak_status_broken(const char *fmt, ...) { @@ -243,4 +242,3 @@ void memleak_status_broken(const char *fmt, ...) status_vfmt(LOG_BROKEN, NULL, fmt, ap); va_end(ap); } -#endif diff --git a/common/status.h b/common/status.h index 4d96a3745..22458ad78 100644 --- a/common/status.h +++ b/common/status.h @@ -70,9 +70,7 @@ void status_send_fatal(const u8 *msg TAKES) NORETURN; /* Only for sync status! */ void status_send_fd(int fd); -#if DEVELOPER /* Print BROKEN status: callback for dump_memleak. */ void memleak_status_broken(const char *fmt, ...); -#endif #endif /* LIGHTNING_COMMON_STATUS_H */ diff --git a/common/subdaemon.c b/common/subdaemon.c index 523a4e3ac..035049a94 100644 --- a/common/subdaemon.c +++ b/common/subdaemon.c @@ -18,8 +18,10 @@ static void status_backtrace_exit(void) status_failed(STATUS_FAIL_INTERNAL_ERROR, "FATAL SIGNAL"); } -void subdaemon_setup(int argc, char *argv[]) +bool subdaemon_setup(int argc, char *argv[]) { + bool developer; + if (argc == 2 && streq(argv[1], "--version")) { printf("%s\n", version()); exit(0); @@ -30,7 +32,7 @@ void subdaemon_setup(int argc, char *argv[]) logging_io = true; } - daemon_maybe_debug(argv); - + developer = daemon_developer_mode(argv); daemon_setup(argv[0], status_backtrace_print, status_backtrace_exit); + return developer; } diff --git a/common/subdaemon.h b/common/subdaemon.h index ad159ee62..e54853774 100644 --- a/common/subdaemon.h +++ b/common/subdaemon.h @@ -5,7 +5,7 @@ struct htable; -/* daemon_setup, but for subdaemons */ -void subdaemon_setup(int argc, char *argv[]); +/* daemon_setup, but for subdaemons: returns true if --developer */ +bool subdaemon_setup(int argc, char *argv[]); #endif /* LIGHTNING_COMMON_SUBDAEMON_H */ diff --git a/connectd/connectd.c b/connectd/connectd.c index 6d78a26ac..5484a9f11 100644 --- a/connectd/connectd.c +++ b/connectd/connectd.c @@ -1862,7 +1862,6 @@ static void peer_final_msg(struct io_conn *conn, multiplex_final_msg(peer, take(finalmsg)); } -#if DEVELOPER static void dev_connect_memleak(struct daemon *daemon, const u8 *msg) { struct htable *memtable; @@ -1881,6 +1880,7 @@ static void dev_connect_memleak(struct daemon *daemon, const u8 *msg) found_leak))); } +#if DEVELOPER static void dev_suppress_gossip(struct daemon *daemon, const u8 *msg) { daemon->dev_suppress_gossip = true; @@ -2082,10 +2082,11 @@ static struct io_plan *recv_req(struct io_conn *conn, goto out; case WIRE_CONNECTD_DEV_MEMLEAK: -#if DEVELOPER - dev_connect_memleak(daemon, msg); - goto out; -#endif + if (daemon->developer) { + dev_connect_memleak(daemon, msg); + goto out; + } + /* Fall thru */ case WIRE_CONNECTD_DEV_SUPPRESS_GOSSIP: #if DEVELOPER dev_suppress_gossip(daemon, msg); @@ -2152,14 +2153,12 @@ static struct io_plan *recv_gossip(struct io_conn *conn, return daemon_conn_read_next(conn, daemon->gossipd); } -/*~ This is a hook used by the memleak code (if DEVELOPER=1): it can't see - * pointers inside hash tables, so we give it a hint here. */ -#if DEVELOPER +/*~ This is a hook used by the memleak code: it can't see pointers + * inside hash tables, so we give it a hint here. */ static void memleak_daemon_cb(struct htable *memtable, struct daemon *daemon) { memleak_scan_htable(memtable, &daemon->peers->raw); } -#endif /* DEVELOPER */ static void gossipd_failed(struct daemon_conn *gossipd) { @@ -2168,15 +2167,17 @@ static void gossipd_failed(struct daemon_conn *gossipd) int main(int argc, char *argv[]) { + struct daemon *daemon; + bool developer; + setup_locale(); - struct daemon *daemon; - /* Common subdaemon setup code. */ - subdaemon_setup(argc, argv); + developer = subdaemon_setup(argc, argv); /* Allocate and set up our simple top-level structure. */ daemon = tal(NULL, struct daemon); + daemon->developer = developer; daemon->connection_counter = 1; daemon->peers = tal(daemon, struct peer_htable); daemon->listeners = tal_arr(daemon, struct io_listener *, 0); diff --git a/connectd/connectd.h b/connectd/connectd.h index 8605155fc..1161784d0 100644 --- a/connectd/connectd.h +++ b/connectd/connectd.h @@ -126,6 +126,9 @@ struct daemon { /* Who am I? */ struct node_id id; + /* --developer? */ + bool developer; + /* pubkey equivalent. */ struct pubkey mykey; diff --git a/gossipd/routing.c b/gossipd/routing.c index 5e2d1243d..3ad0df29a 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -227,7 +227,6 @@ static bool timestamp_reasonable(struct routing_state *rstate, u32 timestamp) return true; } -#if DEVELOPER static void memleak_help_routing_tables(struct htable *memtable, struct routing_state *rstate) { @@ -246,7 +245,6 @@ static void memleak_help_routing_tables(struct htable *memtable, memleak_scan_htable(memtable, &n->chan_map->raw); } } -#endif /* DEVELOPER */ /* Once an hour, or at 10000 entries, we expire old ones */ static void txout_failure_age(struct routing_state *rstate) diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index d3aa23b12..767394c83 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -1239,13 +1239,11 @@ static void destroy_jsonrpc(struct jsonrpc *jsonrpc) strmap_clear(&jsonrpc->usagemap); } -#if DEVELOPER static void memleak_help_jsonrpc(struct htable *memtable, struct jsonrpc *jsonrpc) { memleak_scan_strmap(memtable, &jsonrpc->usagemap); } -#endif /* DEVELOPER */ void jsonrpc_setup(struct lightningd *ld) { diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 02c2e0bc5..77c59a40f 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -82,10 +82,8 @@ #include static void destroy_alt_subdaemons(struct lightningd *ld); -#if DEVELOPER static void memleak_help_alt_subdaemons(struct htable *memtable, struct lightningd *ld); -#endif /* DEVELOPER */ /*~ The core lightning object: it's passed everywhere, and is basically a * global variable. This new_xxx pattern is something we'll see often: @@ -377,13 +375,11 @@ static void destroy_alt_subdaemons(struct lightningd *ld) strmap_clear(&ld->alt_subdaemons); } -#if DEVELOPER static void memleak_help_alt_subdaemons(struct htable *memtable, struct lightningd *ld) { memleak_scan_strmap(memtable, &ld->alt_subdaemons); } -#endif /* DEVELOPER */ const char *subdaemon_path(const tal_t *ctx, const struct lightningd *ld, const char *name) { diff --git a/lightningd/plugin.c b/lightningd/plugin.c index d7dee75d1..4c902cc72 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -45,13 +45,11 @@ struct plugin_rpccall { struct jsonrpc_request *request; }; -#if DEVELOPER static void memleak_help_pending_requests(struct htable *memtable, struct plugins *plugins) { memleak_scan_strmap(memtable, &plugins->pending_requests); } -#endif /* DEVELOPER */ static const char *state_desc(const struct plugin *plugin) { diff --git a/onchaind/test/run-grind_feerate-bug.c b/onchaind/test/run-grind_feerate-bug.c index 0f8cd861b..a2214250f 100644 --- a/onchaind/test/run-grind_feerate-bug.c +++ b/onchaind/test/run-grind_feerate-bug.c @@ -194,7 +194,7 @@ void status_failed(enum status_failreason code UNNEEDED, void status_setup_sync(int fd UNNEEDED) { fprintf(stderr, "status_setup_sync called!\n"); abort(); } /* Generated stub for subdaemon_setup */ -void subdaemon_setup(int argc UNNEEDED, char *argv[]) +bool subdaemon_setup(int argc UNNEEDED, char *argv[]) { fprintf(stderr, "subdaemon_setup called!\n"); abort(); } /* Generated stub for to_self_wscript */ u8 *to_self_wscript(const tal_t *ctx UNNEEDED, diff --git a/onchaind/test/run-grind_feerate.c b/onchaind/test/run-grind_feerate.c index 7c4761818..6dead6504 100644 --- a/onchaind/test/run-grind_feerate.c +++ b/onchaind/test/run-grind_feerate.c @@ -256,7 +256,7 @@ void status_fmt(enum log_level level UNNEEDED, void status_setup_sync(int fd UNNEEDED) { fprintf(stderr, "status_setup_sync called!\n"); abort(); } /* Generated stub for subdaemon_setup */ -void subdaemon_setup(int argc UNNEEDED, char *argv[]) +bool subdaemon_setup(int argc UNNEEDED, char *argv[]) { fprintf(stderr, "subdaemon_setup called!\n"); abort(); } /* Generated stub for to_self_wscript */ u8 *to_self_wscript(const tal_t *ctx UNNEEDED, diff --git a/plugins/bkpr/test/run-bkpr_db.c b/plugins/bkpr/test/run-bkpr_db.c index 43bb60291..49e5d1e3f 100644 --- a/plugins/bkpr/test/run-bkpr_db.c +++ b/plugins/bkpr/test/run-bkpr_db.c @@ -24,9 +24,9 @@ /* Generated stub for account_entry_tag_str */ const char *account_entry_tag_str(enum account_entry_tag tag UNNEEDED) { fprintf(stderr, "account_entry_tag_str called!\n"); abort(); } -/* Generated stub for daemon_maybe_debug */ -void daemon_maybe_debug(char *argv[]) -{ fprintf(stderr, "daemon_maybe_debug called!\n"); abort(); } +/* Generated stub for daemon_developer_mode */ +bool daemon_developer_mode(char *argv[]) +{ fprintf(stderr, "daemon_developer_mode called!\n"); abort(); } /* Generated stub for daemon_setup */ void daemon_setup(const char *argv0 UNNEEDED, void (*backtrace_print)(const char *fmt UNNEEDED, ...) UNNEEDED, diff --git a/plugins/bkpr/test/run-recorder.c b/plugins/bkpr/test/run-recorder.c index 90be3e2c9..ee45b90b2 100644 --- a/plugins/bkpr/test/run-recorder.c +++ b/plugins/bkpr/test/run-recorder.c @@ -30,9 +30,9 @@ /* Generated stub for account_entry_tag_str */ const char *account_entry_tag_str(enum account_entry_tag tag UNNEEDED) { fprintf(stderr, "account_entry_tag_str called!\n"); abort(); } -/* Generated stub for daemon_maybe_debug */ -void daemon_maybe_debug(char *argv[]) -{ fprintf(stderr, "daemon_maybe_debug called!\n"); abort(); } +/* Generated stub for daemon_developer_mode */ +bool daemon_developer_mode(char *argv[]) +{ fprintf(stderr, "daemon_developer_mode called!\n"); abort(); } /* Generated stub for daemon_setup */ void daemon_setup(const char *argv0 UNNEEDED, void (*backtrace_print)(const char *fmt UNNEEDED, ...) UNNEEDED, diff --git a/plugins/libplugin.c b/plugins/libplugin.c index 39ea24263..aa3eb9a43 100644 --- a/plugins/libplugin.c +++ b/plugins/libplugin.c @@ -44,6 +44,8 @@ struct plugin { struct io_conn *stdin_conn; struct io_conn *stdout_conn; + bool developer; + /* to append to all our command ids */ const char *id; @@ -109,10 +111,8 @@ struct plugin { const char **notif_topics; size_t num_notif_topics; -#if DEVELOPER /* Lets them remove ptrs from leak detection. */ void (*mark_mem)(struct plugin *plugin, struct htable *memtable); -#endif }; /* command_result is mainly used as a compile-time check to encourage you @@ -947,14 +947,9 @@ handle_getmanifest(struct command *getmanifest_cmd, if (streq(p->notif_subs[i].name, "shutdown")) has_shutdown_notif = true; } -#if DEVELOPER /* For memleak detection, always get notified of shutdown. */ - if (!has_shutdown_notif) + if (!has_shutdown_notif && p->developer) json_add_string(params, NULL, "shutdown"); -#else - /* Don't care this is unused: compiler don't complain! */ - (void)has_shutdown_notif; -#endif json_array_end(params); json_array_start(params, "hooks"); @@ -1509,7 +1504,6 @@ void plugin_log(struct plugin *p, enum log_level l, const char *fmt, ...) va_end(ap); } -#if DEVELOPER /* Hack since we have no extra ptr to log_memleak */ static struct plugin *memleak_plugin; static void PRINTF_FMT(1,2) log_memleak(const char *fmt, ...) @@ -1551,9 +1545,9 @@ void plugin_set_memleak_handler(struct plugin *plugin, void (*mark_mem)(struct plugin *plugin, struct htable *memtable)) { - plugin->mark_mem = mark_mem; + if (plugin->developer) + plugin->mark_mem = mark_mem; } -#endif /* DEVELOPER */ static void ld_command_handle(struct plugin *plugin, const jsmntok_t *toks) @@ -1600,11 +1594,10 @@ static void ld_command_handle(struct plugin *plugin, /* If that's a notification. */ if (!cmd->id) { -#if DEVELOPER bool is_shutdown = streq(cmd->methodname, "shutdown"); - if (is_shutdown) + if (is_shutdown && plugin->developer) memleak_check(plugin, cmd); -#endif + for (size_t i = 0; i < plugin->num_notif_subs; i++) { if (streq(cmd->methodname, plugin->notif_subs[i].name) @@ -1616,11 +1609,9 @@ static void ld_command_handle(struct plugin *plugin, } } -#if DEVELOPER /* We subscribe them to this always */ - if (is_shutdown) + if (is_shutdown && plugin->developer) plugin_exit(plugin, 0); -#endif plugin_err(plugin, "Unregistered notification %.*s", json_tok_full_len(methtok), @@ -1810,6 +1801,7 @@ static struct io_plan *stdout_conn_init(struct io_conn *conn, static struct plugin *new_plugin(const tal_t *ctx, const char *argv0, + bool developer, const char *(*init)(struct plugin *p, const char *buf, const jsmntok_t *), @@ -1834,6 +1826,7 @@ static struct plugin *new_plugin(const tal_t *ctx, name = path_basename(p, argv0); name[path_ext_off(name)] = '\0'; p->id = name; + p->developer = developer; p->buffer = tal_arr(p, char, 64); list_head_init(&p->js_list); p->used = 0; @@ -1895,9 +1888,7 @@ static struct plugin *new_plugin(const tal_t *ctx, tal_arr_expand(&p->opts, o); } -#if DEVELOPER p->mark_mem = NULL; -#endif return p; } @@ -1919,16 +1910,17 @@ void plugin_main(char *argv[], { struct plugin *plugin; va_list ap; + bool developer; setup_locale(); - daemon_maybe_debug(argv); + developer = daemon_developer_mode(argv); /* Note this already prints to stderr, which is enough for now */ daemon_setup(argv[0], NULL, NULL); va_start(ap, num_notif_topics); - plugin = new_plugin(NULL, argv[0], + plugin = new_plugin(NULL, argv[0], developer, init, restartability, init_rpc, features, commands, num_commands, notif_subs, num_notif_subs, hook_subs, num_hook_subs, notif_topics, num_notif_topics, ap); @@ -2132,3 +2124,8 @@ notification_handled(struct command *cmd) tal_free(cmd); return &complete; } + +bool plugin_developer_mode(const struct plugin *plugin) +{ + return plugin->developer; +} diff --git a/plugins/libplugin.h b/plugins/libplugin.h index 3b6d1f3b6..3c31f36aa 100644 --- a/plugins/libplugin.h +++ b/plugins/libplugin.h @@ -20,6 +20,7 @@ #include struct json_out; +struct htable; struct plugin; struct rpc_conn; @@ -404,6 +405,9 @@ static inline void *plugin_option_cb_check(char *(*set)(struct plugin *plugin, return set; } +/* Is --developer enabled? */ +bool plugin_developer_mode(const struct plugin *plugin); + /* Macro to define arguments */ #define plugin_option_(name, type, description, set, arg, deprecated, dynamic) \ (name), \ @@ -489,12 +493,9 @@ struct route_hop *json_to_route(const tal_t *ctx, const char *buffer, /* Create a prefix (ending in /) for this cmd_id, if any. */ const char *json_id_prefix(const tal_t *ctx, const struct command *cmd); -#if DEVELOPER -struct htable; void plugin_set_memleak_handler(struct plugin *plugin, void (*mark_mem)(struct plugin *plugin, struct htable *memtable)); -#endif /* DEVELOPER */ /* Synchronously call a JSON-RPC method and return its contents and * the parser token. */