mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-02 18:35:00 +01:00
common/daemon: in DEVELOPER mode, check for tal_parent() loops.
If you steal something onto its own child, you create a loop. These are expensive to check for at runtime, but they can hide from memleak and are usually a bad idea. So we add a tal_steal() notify which does this work in DEVELOPER mdoe. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
3e2dea221b
commit
22b8a88b48
1 changed files with 29 additions and 0 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
#include <assert.h>
|
||||||
#include <backtrace-supported.h>
|
#include <backtrace-supported.h>
|
||||||
#include <backtrace.h>
|
#include <backtrace.h>
|
||||||
#include <ccan/err/err.h>
|
#include <ccan/err/err.h>
|
||||||
|
@ -78,6 +79,33 @@ int daemon_poll(struct pollfd *fds, nfds_t nfds, int timeout)
|
||||||
return poll(fds, nfds, timeout);
|
return poll(fds, nfds, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEVELOPER
|
||||||
|
static void steal_notify(tal_t *child, enum tal_notify_type n, tal_t *newparent)
|
||||||
|
{
|
||||||
|
tal_t *p = newparent;
|
||||||
|
|
||||||
|
assert(tal_parent(child) == newparent);
|
||||||
|
while ((p = tal_parent(p)) != NULL)
|
||||||
|
assert(p != child);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_steal_notifier(tal_t *parent UNUSED,
|
||||||
|
enum tal_notify_type type UNNEEDED,
|
||||||
|
void *child)
|
||||||
|
{
|
||||||
|
tal_add_notifier(child, TAL_NOTIFY_ADD_CHILD, add_steal_notifier);
|
||||||
|
tal_add_notifier(child, TAL_NOTIFY_STEAL, steal_notify);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_steal_notifiers(const tal_t *root)
|
||||||
|
{
|
||||||
|
tal_add_notifier(root, TAL_NOTIFY_ADD_CHILD, add_steal_notifier);
|
||||||
|
|
||||||
|
for (const tal_t *i = tal_first(root); i; i = tal_next(i))
|
||||||
|
add_steal_notifiers(i);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void daemon_setup(const char *argv0,
|
void daemon_setup(const char *argv0,
|
||||||
void (*backtrace_print)(const char *fmt, ...),
|
void (*backtrace_print)(const char *fmt, ...),
|
||||||
void (*backtrace_exit)(void))
|
void (*backtrace_exit)(void))
|
||||||
|
@ -91,6 +119,7 @@ void daemon_setup(const char *argv0,
|
||||||
/* Suppresses backtrace (breaks valgrind) */
|
/* Suppresses backtrace (breaks valgrind) */
|
||||||
if (!getenv("LIGHTNINGD_DEV_NO_BACKTRACE"))
|
if (!getenv("LIGHTNINGD_DEV_NO_BACKTRACE"))
|
||||||
backtrace_state = backtrace_create_state(argv0, 0, NULL, NULL);
|
backtrace_state = backtrace_create_state(argv0, 0, NULL, NULL);
|
||||||
|
add_steal_notifiers(NULL);
|
||||||
#else
|
#else
|
||||||
backtrace_state = backtrace_create_state(argv0, 0, NULL, NULL);
|
backtrace_state = backtrace_create_state(argv0, 0, NULL, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue