mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-19 05:44:12 +01:00
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 <rusty@rustcorp.com.au>
This commit is contained in:
parent
67a391f8d0
commit
a9f26b7d07
@ -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()
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -126,6 +126,9 @@ struct daemon {
|
||||
/* Who am I? */
|
||||
struct node_id id;
|
||||
|
||||
/* --developer? */
|
||||
bool developer;
|
||||
|
||||
/* pubkey equivalent. */
|
||||
struct pubkey mykey;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -82,10 +82,8 @@
|
||||
#include <wally_bip32.h>
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
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. */
|
||||
|
Loading…
Reference in New Issue
Block a user