mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-18 06:34:20 +01:00
memleak: remove exclusions from memleak_start()
Add memleak_ignore_children() so callers can do exclusions themselves. Having two exclusions was always such a hack! Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -3652,7 +3652,8 @@ static void handle_dev_memleak(struct peer *peer, const u8 *msg)
|
||||
struct htable *memtable;
|
||||
bool found_leak;
|
||||
|
||||
memtable = memleak_start(tmpctx, msg, msg);
|
||||
memtable = memleak_start(tmpctx);
|
||||
memleak_ptr(memtable, msg);
|
||||
|
||||
/* Now delete peer and things it has pointers to. */
|
||||
memleak_scan_obj(memtable, peer);
|
||||
|
||||
@@ -554,7 +554,7 @@ static void closing_dev_memleak(const tal_t *ctx,
|
||||
u8 *scriptpubkey[NUM_SIDES],
|
||||
const u8 *funding_wscript)
|
||||
{
|
||||
struct htable *memtable = memleak_start(tmpctx, NULL, NULL);
|
||||
struct htable *memtable = memleak_start(tmpctx);
|
||||
|
||||
memleak_ptr(memtable, ctx);
|
||||
memleak_ptr(memtable, scriptpubkey[LOCAL]);
|
||||
|
||||
@@ -71,17 +71,13 @@ bool memleak_ptr(struct htable *memtable, const void *p)
|
||||
return htable_del(memtable, hash_ptr(p, NULL), p);
|
||||
}
|
||||
|
||||
static void children_into_htable(const void *exclude1, const void *exclude2,
|
||||
struct htable *memtable, const tal_t *p)
|
||||
static void children_into_htable(struct htable *memtable, const tal_t *p)
|
||||
{
|
||||
const tal_t *i;
|
||||
|
||||
for (i = tal_first(p); i; i = tal_next(i)) {
|
||||
const char *name = tal_name(i);
|
||||
|
||||
if (i == exclude1 || i == exclude2)
|
||||
continue;
|
||||
|
||||
if (name) {
|
||||
/* Don't add backtrace objects. */
|
||||
if (streq(name, "backtrace"))
|
||||
@@ -108,7 +104,7 @@ static void children_into_htable(const void *exclude1, const void *exclude2,
|
||||
continue;
|
||||
}
|
||||
htable_add(memtable, hash_ptr(i, NULL), i);
|
||||
children_into_htable(exclude1, exclude2, memtable, i);
|
||||
children_into_htable(memtable, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,6 +264,11 @@ void memleak_add_helper_(const tal_t *p,
|
||||
mh->cb = cb;
|
||||
}
|
||||
|
||||
void memleak_ignore_children(struct htable *memtable, const void *p)
|
||||
{
|
||||
for (const tal_t *i = tal_first(p); i; i = tal_next(i))
|
||||
remove_with_children(memtable, i);
|
||||
}
|
||||
|
||||
/* Handle allocations marked with helpers or notleak() */
|
||||
static void call_memleak_helpers(struct htable *memtable, const tal_t *p)
|
||||
@@ -297,16 +298,14 @@ static void call_memleak_helpers(struct htable *memtable, const tal_t *p)
|
||||
}
|
||||
}
|
||||
|
||||
struct htable *memleak_start(const tal_t *ctx,
|
||||
const void *exclude1,
|
||||
const void *exclude2)
|
||||
struct htable *memleak_start(const tal_t *ctx)
|
||||
{
|
||||
struct htable *memtable = tal(ctx, struct htable);
|
||||
htable_init(memtable, hash_ptr, NULL);
|
||||
|
||||
if (memleak_track) {
|
||||
/* First, add all pointers off NULL to table. */
|
||||
children_into_htable(exclude1, exclude2, memtable, NULL);
|
||||
children_into_htable(memtable, NULL);
|
||||
|
||||
/* Iterate and call helpers to eliminate hard-to-get references. */
|
||||
call_memleak_helpers(memtable, NULL);
|
||||
|
||||
@@ -67,14 +67,8 @@ void memleak_add_helper_(const tal_t *p, void (*cb)(struct htable *memtable,
|
||||
/**
|
||||
* memleak_start: allocate a htable with all tal objects
|
||||
* @ctx: the context to allocate the htable from
|
||||
* @exclude1: one tal pointer to exclude from adding (if non-NULL)
|
||||
* @exclude2: second tal pointer to exclude from adding (if non-NULL)
|
||||
*
|
||||
* Note that exclude1 and exclude2's tal children are also not added.
|
||||
*/
|
||||
struct htable *memleak_start(const tal_t *ctx,
|
||||
const void *exclude1,
|
||||
const void *exclude2);
|
||||
struct htable *memleak_start(const tal_t *ctx);
|
||||
|
||||
/**
|
||||
* memleak_ptr: this pointer is not a memleak.
|
||||
@@ -131,6 +125,16 @@ void memleak_scan_intmap_(struct htable *memtable, const struct intmap *m);
|
||||
memleak_scan_strmap_((memtable), tcon_unwrap(strmap))
|
||||
void memleak_scan_strmap_(struct htable *memtable, const struct strmap *m);
|
||||
|
||||
/**
|
||||
* memleak_ignore_children - ignore all this tal object's children.
|
||||
* @memtable: the memtable created by memleak_start
|
||||
* @p: the tal pointer.
|
||||
*
|
||||
* This is equivalent to calling memleak_ptr() on every child of @p
|
||||
* recursively. This is a big hammer, so be careful!
|
||||
*/
|
||||
void memleak_ignore_children(struct htable *memtable, const void *p);
|
||||
|
||||
/**
|
||||
* memleak_get: get (and remove) a leak from memtable, or NULL
|
||||
* @memtable: the memtable after all known allocations removed.
|
||||
|
||||
@@ -1860,7 +1860,8 @@ static void dev_connect_memleak(struct daemon *daemon, const u8 *msg)
|
||||
struct htable *memtable;
|
||||
bool found_leak;
|
||||
|
||||
memtable = memleak_start(tmpctx, msg, msg);
|
||||
memtable = memleak_start(tmpctx);
|
||||
memleak_ptr(memtable, msg);
|
||||
|
||||
/* Now delete daemon and those which it has pointers to. */
|
||||
memleak_scan_obj(memtable, daemon);
|
||||
|
||||
@@ -807,8 +807,8 @@ static void dev_gossip_memleak(struct daemon *daemon, const u8 *msg)
|
||||
struct htable *memtable;
|
||||
bool found_leak;
|
||||
|
||||
memtable = memleak_start(tmpctx, msg, msg);
|
||||
|
||||
memtable = memleak_start(tmpctx);
|
||||
memleak_ptr(memtable, msg);
|
||||
/* Now delete daemon and those which it has pointers to. */
|
||||
memleak_scan_obj(memtable, daemon);
|
||||
|
||||
|
||||
@@ -555,7 +555,8 @@ static struct io_plan *handle_memleak(struct io_conn *conn,
|
||||
bool found_leak;
|
||||
u8 *reply;
|
||||
|
||||
memtable = memleak_start(tmpctx, msg_in, msg_in);
|
||||
memtable = memleak_start(tmpctx);
|
||||
memleak_ptr(memtable, msg_in);
|
||||
|
||||
/* Now note clients and anything they point to. */
|
||||
memleak_scan_region(memtable, dbid_zero_clients, sizeof(dbid_zero_clients));
|
||||
|
||||
@@ -143,7 +143,11 @@ static void finish_report(const struct leak_detect *leaks)
|
||||
ld = cmd->ld;
|
||||
|
||||
/* Enter everything, except this cmd and its jcon */
|
||||
memtable = memleak_start(cmd, cmd, cmd->jcon);
|
||||
memtable = memleak_start(cmd);
|
||||
|
||||
/* This command is not a leak! */
|
||||
memleak_ptr(memtable, cmd);
|
||||
memleak_ignore_children(memtable, cmd);
|
||||
|
||||
/* First delete known false positives. */
|
||||
memleak_scan_htable(memtable, &ld->topology->txwatches.raw);
|
||||
|
||||
@@ -2101,7 +2101,9 @@ static bool handle_dev_memleak(struct tracked_output **outs, const u8 *msg)
|
||||
if (!fromwire_onchaind_dev_memleak(msg))
|
||||
return false;
|
||||
|
||||
memtable = memleak_start(tmpctx, msg, msg);
|
||||
memtable = memleak_start(tmpctx);
|
||||
memleak_ptr(memtable, msg);
|
||||
|
||||
/* Top-level context is parent of outs */
|
||||
memleak_remove_globals(memtable, tal_parent(outs));
|
||||
memleak_scan_obj(memtable, outs);
|
||||
|
||||
@@ -324,9 +324,7 @@ void memleak_scan_obj(struct htable *memtable UNNEEDED, const void *obj UNNEEDED
|
||||
void memleak_scan_region(struct htable *memtable UNNEEDED, const void *p UNNEEDED, size_t len UNNEEDED)
|
||||
{ fprintf(stderr, "memleak_scan_region called!\n"); abort(); }
|
||||
/* Generated stub for memleak_start */
|
||||
struct htable *memleak_start(const tal_t *ctx UNNEEDED,
|
||||
const void *exclude1 UNNEEDED,
|
||||
const void *exclude2 UNNEEDED)
|
||||
struct htable *memleak_start(const tal_t *ctx UNNEEDED)
|
||||
{ fprintf(stderr, "memleak_start called!\n"); abort(); }
|
||||
/* Generated stub for memleak_status_broken */
|
||||
void memleak_status_broken(const char *fmt UNNEEDED, ...)
|
||||
|
||||
@@ -131,9 +131,7 @@ void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg)
|
||||
void memleak_scan_obj(struct htable *memtable UNNEEDED, const void *obj UNNEEDED)
|
||||
{ fprintf(stderr, "memleak_scan_obj called!\n"); abort(); }
|
||||
/* Generated stub for memleak_start */
|
||||
struct htable *memleak_start(const tal_t *ctx UNNEEDED,
|
||||
const void *exclude1 UNNEEDED,
|
||||
const void *exclude2 UNNEEDED)
|
||||
struct htable *memleak_start(const tal_t *ctx UNNEEDED)
|
||||
{ fprintf(stderr, "memleak_start called!\n"); abort(); }
|
||||
/* Generated stub for new_coin_channel_close */
|
||||
struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx UNNEEDED,
|
||||
|
||||
@@ -890,7 +890,8 @@ static void handle_dev_memleak(struct state *state, const u8 *msg)
|
||||
|
||||
/* Populate a hash table with all our allocations (except msg, which
|
||||
* is in use right now). */
|
||||
memtable = memleak_start(tmpctx, msg, msg);
|
||||
memtable = memleak_start(tmpctx);
|
||||
memleak_ptr(memtable, msg);
|
||||
|
||||
/* Now delete state and things it has pointers to. */
|
||||
memleak_scan_obj(memtable, state);
|
||||
|
||||
@@ -1301,7 +1301,8 @@ static void handle_dev_memleak(struct state *state, const u8 *msg)
|
||||
|
||||
/* Populate a hash table with all our allocations (except msg, which
|
||||
* is in use right now). */
|
||||
memtable = memleak_start(tmpctx, msg, msg);
|
||||
memtable = memleak_start(tmpctx);
|
||||
memleak_ptr(memtable, msg);
|
||||
|
||||
/* Now delete state and things it has pointers to. */
|
||||
memleak_scan_obj(memtable, state);
|
||||
|
||||
@@ -1350,7 +1350,11 @@ static void memleak_check(struct plugin *plugin, struct command *cmd)
|
||||
{
|
||||
struct htable *memtable;
|
||||
|
||||
memtable = memleak_start(tmpctx, cmd, cmd);
|
||||
memtable = memleak_start(tmpctx);
|
||||
|
||||
/* cmd in use right now */
|
||||
memleak_ptr(memtable, cmd);
|
||||
memleak_ignore_children(memtable, cmd);
|
||||
|
||||
/* Now delete plugin and anything it has pointers to. */
|
||||
memleak_scan_obj(memtable, plugin);
|
||||
|
||||
Reference in New Issue
Block a user