memleak: simplify API.

Mainly renaming.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2022-09-16 12:44:39 +09:30
parent fd71dfc7f7
commit 3380f559f9
29 changed files with 186 additions and 161 deletions

View File

@@ -3652,10 +3652,10 @@ static void handle_dev_memleak(struct peer *peer, const u8 *msg)
struct htable *memtable; struct htable *memtable;
bool found_leak; bool found_leak;
memtable = memleak_find_allocations(tmpctx, msg, msg); memtable = memleak_start(tmpctx, msg, msg);
/* Now delete peer and things it has pointers to. */ /* Now delete peer and things it has pointers to. */
memleak_remove_region(memtable, peer, tal_bytelen(peer)); memleak_scan_obj(memtable, peer);
found_leak = dump_memleak(memtable, memleak_status_broken); found_leak = dump_memleak(memtable, memleak_status_broken);
wire_sync_write(MASTER_FD, wire_sync_write(MASTER_FD,

View File

@@ -22,7 +22,7 @@
static void memleak_help_htlcmap(struct htable *memtable, static void memleak_help_htlcmap(struct htable *memtable,
struct htlc_map *htlcs) struct htlc_map *htlcs)
{ {
memleak_remove_htable(memtable, &htlcs->raw); memleak_scan_htable(memtable, &htlcs->raw);
} }
#endif /* DEVELOPER */ #endif /* DEVELOPER */

View File

@@ -19,9 +19,9 @@ void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct n
/* Generated stub for memleak_add_helper_ */ /* Generated stub for memleak_add_helper_ */
void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED, void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED,
const tal_t *)){ } const tal_t *)){ }
/* Generated stub for memleak_remove_htable */ /* Generated stub for memleak_scan_htable */
void memleak_remove_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED) void memleak_scan_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED)
{ fprintf(stderr, "memleak_remove_htable called!\n"); abort(); } { fprintf(stderr, "memleak_scan_htable called!\n"); abort(); }
/* Generated stub for status_failed */ /* Generated stub for status_failed */
void status_failed(enum status_failreason code UNNEEDED, void status_failed(enum status_failreason code UNNEEDED,
const char *fmt UNNEEDED, ...) const char *fmt UNNEEDED, ...)

View File

@@ -554,14 +554,12 @@ static void closing_dev_memleak(const tal_t *ctx,
u8 *scriptpubkey[NUM_SIDES], u8 *scriptpubkey[NUM_SIDES],
const u8 *funding_wscript) const u8 *funding_wscript)
{ {
struct htable *memtable; struct htable *memtable = memleak_start(tmpctx, NULL, NULL);
memtable = memleak_find_allocations(tmpctx, NULL, NULL); memleak_ptr(memtable, ctx);
memleak_ptr(memtable, scriptpubkey[LOCAL]);
memleak_remove_pointer(memtable, ctx); memleak_ptr(memtable, scriptpubkey[REMOTE]);
memleak_remove_pointer(memtable, scriptpubkey[LOCAL]); memleak_ptr(memtable, funding_wscript);
memleak_remove_pointer(memtable, scriptpubkey[REMOTE]);
memleak_remove_pointer(memtable, funding_wscript);
dump_memleak(memtable, memleak_status_broken); dump_memleak(memtable, memleak_status_broken);
} }

View File

@@ -25,6 +25,7 @@
#include <ccan/crypto/siphash24/siphash24.h> #include <ccan/crypto/siphash24/siphash24.h>
#include <ccan/htable/htable.h> #include <ccan/htable/htable.h>
#include <ccan/intmap/intmap.h> #include <ccan/intmap/intmap.h>
#include <ccan/list/list.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <common/memleak.h> #include <common/memleak.h>
#include <common/utils.h> #include <common/utils.h>
@@ -65,7 +66,7 @@ static size_t hash_ptr(const void *elem, void *unused UNNEEDED)
return siphash24(&seed, &elem, sizeof(elem)); return siphash24(&seed, &elem, sizeof(elem));
} }
static bool pointer_referenced(struct htable *memtable, const void *p) bool memleak_ptr(struct htable *memtable, const void *p)
{ {
return htable_del(memtable, hash_ptr(p, NULL), p); return htable_del(memtable, hash_ptr(p, NULL), p);
} }
@@ -122,45 +123,54 @@ static void scan_for_pointers(struct htable *memtable,
void *ptr; void *ptr;
memcpy(&ptr, (char *)p + i * sizeof(void *), sizeof(ptr)); memcpy(&ptr, (char *)p + i * sizeof(void *), sizeof(ptr));
if (pointer_referenced(memtable, ptr)) if (memleak_ptr(memtable, ptr))
scan_for_pointers(memtable, ptr, tal_bytelen(ptr)); scan_for_pointers(memtable, ptr, tal_bytelen(ptr));
} }
} }
void memleak_remove_region(struct htable *memtable, void memleak_scan_region(struct htable *memtable, const void *ptr, size_t len)
const void *ptr, size_t bytelen)
{ {
pointer_referenced(memtable, ptr); scan_for_pointers(memtable, ptr, len);
scan_for_pointers(memtable, ptr, bytelen); }
void memleak_scan_obj(struct htable *memtable, const void *ptr)
{
memleak_ptr(memtable, ptr);
scan_for_pointers(memtable, ptr, tal_bytelen(ptr));
}
void memleak_scan_list_head(struct htable *memtable, const struct list_head *l)
{
scan_for_pointers(memtable, l, sizeof(*l));
} }
static void remove_with_children(struct htable *memtable, const tal_t *p) static void remove_with_children(struct htable *memtable, const tal_t *p)
{ {
const tal_t *i; const tal_t *i;
pointer_referenced(memtable, p); memleak_ptr(memtable, p);
for (i = tal_first(p); i; i = tal_next(i)) for (i = tal_first(p); i; i = tal_next(i))
remove_with_children(memtable, i); remove_with_children(memtable, i);
} }
/* memleak can't see inside hash tables, so do them manually */ /* memleak can't see inside hash tables, so do them manually */
void memleak_remove_htable(struct htable *memtable, const struct htable *ht) void memleak_scan_htable(struct htable *memtable, const struct htable *ht)
{ {
struct htable_iter i; struct htable_iter i;
const void *p; const void *p;
for (p = htable_first(ht, &i); p; p = htable_next(ht, &i)) for (p = htable_first(ht, &i); p; p = htable_next(ht, &i))
memleak_remove_region(memtable, p, tal_bytelen(p)); memleak_scan_obj(memtable, p);
} }
/* FIXME: If uintmap used tal, this wouldn't be necessary! */ /* FIXME: If uintmap used tal, this wouldn't be necessary! */
void memleak_remove_intmap_(struct htable *memtable, const struct intmap *m) void memleak_scan_intmap_(struct htable *memtable, const struct intmap *m)
{ {
void *p; void *p;
intmap_index_t i; intmap_index_t i;
for (p = intmap_first_(m, &i); p; p = intmap_after_(m, &i)) for (p = intmap_first_(m, &i); p; p = intmap_after_(m, &i))
memleak_remove_region(memtable, p, tal_bytelen(p)); memleak_scan_obj(memtable, p);
} }
static bool handle_strmap(const char *member, void *p, void *memtable_) static bool handle_strmap(const char *member, void *p, void *memtable_)
@@ -168,15 +178,15 @@ static bool handle_strmap(const char *member, void *p, void *memtable_)
struct htable *memtable = memtable_; struct htable *memtable = memtable_;
/* membername may *not* be a tal ptr, but it can be! */ /* membername may *not* be a tal ptr, but it can be! */
pointer_referenced(memtable, member); memleak_ptr(memtable, member);
memleak_remove_region(memtable, p, tal_bytelen(p)); memleak_scan_obj(memtable, p);
/* Keep going */ /* Keep going */
return true; return true;
} }
/* FIXME: If strmap used tal, this wouldn't be necessary! */ /* FIXME: If strmap used tal, this wouldn't be necessary! */
void memleak_remove_strmap_(struct htable *memtable, const struct strmap *m) void memleak_scan_strmap_(struct htable *memtable, const struct strmap *m)
{ {
strmap_iterate_(m, handle_strmap, memtable); strmap_iterate_(m, handle_strmap, memtable);
} }
@@ -192,7 +202,7 @@ const void *memleak_get(struct htable *memtable, const uintptr_t **backtrace)
const tal_t *i, *p; const tal_t *i, *p;
/* Remove memtable itself */ /* Remove memtable itself */
pointer_referenced(memtable, memtable); memleak_ptr(memtable, memtable);
i = htable_first(memtable, &it); i = htable_first(memtable, &it);
if (!i) if (!i)
@@ -273,14 +283,12 @@ static void call_memleak_helpers(struct htable *memtable, const tal_t *p)
mh->cb(memtable, p); mh->cb(memtable, p);
} else if (strends(name, " **NOTLEAK**") } else if (strends(name, " **NOTLEAK**")
|| strends(name, "_notleak")) { || strends(name, "_notleak")) {
pointer_referenced(memtable, i); memleak_ptr(memtable, i);
memleak_remove_region(memtable, i, memleak_scan_obj(memtable, i);
tal_bytelen(i));
} else if (strends(name, } else if (strends(name,
" **NOTLEAK_IGNORE_CHILDREN**")) { " **NOTLEAK_IGNORE_CHILDREN**")) {
remove_with_children(memtable, i); remove_with_children(memtable, i);
memleak_remove_region(memtable, i, memleak_scan_obj(memtable, i);
tal_bytelen(i));
} }
} }
@@ -289,9 +297,9 @@ static void call_memleak_helpers(struct htable *memtable, const tal_t *p)
} }
} }
struct htable *memleak_find_allocations(const tal_t *ctx, struct htable *memleak_start(const tal_t *ctx,
const void *exclude1, const void *exclude1,
const void *exclude2) const void *exclude2)
{ {
struct htable *memtable = tal(ctx, struct htable); struct htable *memtable = tal(ctx, struct htable);
htable_init(memtable, hash_ptr, NULL); htable_init(memtable, hash_ptr, NULL);

View File

@@ -6,6 +6,7 @@
#include <inttypes.h> #include <inttypes.h>
struct htable; struct htable;
struct list_head;
/** /**
* memleak_init: Initialize memleak detection; you call this at the start! * memleak_init: Initialize memleak detection; you call this at the start!
@@ -64,54 +65,71 @@ void memleak_add_helper_(const tal_t *p, void (*cb)(struct htable *memtable,
const tal_t *)); const tal_t *));
/** /**
* memleak_find_allocations: allocate a htable with all tal objects; * memleak_start: allocate a htable with all tal objects
* @ctx: the context to allocate the htable from * @ctx: the context to allocate the htable from
* @exclude1: one tal pointer to exclude from adding (if non-NULL) * @exclude1: one tal pointer to exclude from adding (if non-NULL)
* @exclude2: second 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. * Note that exclude1 and exclude2's tal children are also not added.
*/ */
struct htable *memleak_find_allocations(const tal_t *ctx, struct htable *memleak_start(const tal_t *ctx,
const void *exclude1, const void *exclude1,
const void *exclude2); const void *exclude2);
/** /**
* memleak_remove_region - remove this region and anything it references * memleak_ptr: this pointer is not a memleak.
* @memtable: the memtable create by memleak_find_allocations. * @memtable: the memtable create by memleak_start.
* @p: the pointer to remove. * @p: the pointer.
* @bytelen: the bytes within it to scan for more pointers.
* *
* This removes @p from the memtable, then looks for any tal pointers * This tells memleak that @p (a tal allocation) is not a leak. Returns
* inside between @p and @p + @bytelen and calls * true if it was in the memleak table (it will no longer be).
* memleak_remove_region() on those if not already removed.
*/ */
void memleak_remove_region(struct htable *memtable, bool memleak_ptr(struct htable *memtable, const void *p);
const void *p, size_t bytelen);
/** /**
* memleak_remove_pointer - remove this pointer * memleak_scan_obj - this tal object and anything it references are not leaks.
* @memtable: the memtable create by memleak_find_allocations. * @memtable: the memtable create by memleak_start.
* @p: the pointer to remove. * @obj: the tal pointer
* *
* This removes @p from the memtable. * This removes @obj from the memtable, then looks for any tal pointers
* inside @obj and calls memleak_scan_obj() on those if not already removed.
*/ */
#define memleak_remove_pointer(memtable, p) \ void memleak_scan_obj(struct htable *memtable, const void *obj);
memleak_remove_region((memtable), (p), 0)
/* Helper to remove objects inside this htable (which is opaque to memleak). */ /**
void memleak_remove_htable(struct htable *memtable, const struct htable *ht); * memleak_scan_list_head - this list is not a leak.
* @memtable: the memtable create by memleak_start.
* @l: the list_head pointer
*
* This removes @l from the memtable, and any elements in the list. Usually
* used for file-scope linked lists.
*/
void memleak_scan_list_head(struct htable *memtable, const struct list_head *l);
/* Helper to remove objects inside this uintmap (which is opaque to memleak). */ /**
#define memleak_remove_uintmap(memtable, umap) \ * memleak_scan_region - scan a non-tal allocation for references.
memleak_remove_intmap_(memtable, uintmap_unwrap_(umap)) * @memtable: the memtable create by memleak_start.
* @p: the tal pointer
* @len: the length in bytes.
*
* Sometimes we have a stack or file-scope object which contains pointers.
*/
void memleak_scan_region(struct htable *memtable, const void *p, size_t len);
/* Objects inside this htable (which is opaque to memleak) are not leaks. */
void memleak_scan_htable(struct htable *memtable, const struct htable *ht);
/* Objects inside this uintmap (which is opaque to memleak) are not leaks. */
#define memleak_scan_uintmap(memtable, umap) \
memleak_scan_intmap_(memtable, uintmap_unwrap_(umap))
struct intmap; struct intmap;
void memleak_remove_intmap_(struct htable *memtable, const struct intmap *m); void memleak_scan_intmap_(struct htable *memtable, const struct intmap *m);
/* Remove any pointers inside this strmap (which is opaque to memleak). */ /* Objects inside this strmap (which is opaque to memleak) are not leaks. */
#define memleak_remove_strmap(memtable, strmap) \ #define memleak_scan_strmap(memtable, strmap) \
memleak_remove_strmap_((memtable), tcon_unwrap(strmap)) memleak_scan_strmap_((memtable), tcon_unwrap(strmap))
void memleak_remove_strmap_(struct htable *memtable, const struct strmap *m); void memleak_scan_strmap_(struct htable *memtable, const struct strmap *m);
/** /**
* memleak_get: get (and remove) a leak from memtable, or NULL * memleak_get: get (and remove) a leak from memtable, or NULL

View File

@@ -1860,11 +1860,11 @@ static void dev_connect_memleak(struct daemon *daemon, const u8 *msg)
struct htable *memtable; struct htable *memtable;
bool found_leak; bool found_leak;
memtable = memleak_find_allocations(tmpctx, msg, msg); memtable = memleak_start(tmpctx, msg, msg);
/* Now delete daemon and those which it has pointers to. */ /* Now delete daemon and those which it has pointers to. */
memleak_remove_region(memtable, daemon, sizeof(daemon)); memleak_scan_obj(memtable, daemon);
memleak_remove_htable(memtable, &daemon->peers.raw); memleak_scan_htable(memtable, &daemon->peers.raw);
found_leak = dump_memleak(memtable, memleak_status_broken); found_leak = dump_memleak(memtable, memleak_status_broken);
daemon_conn_send(daemon->master, daemon_conn_send(daemon->master,
@@ -2003,7 +2003,7 @@ static struct io_plan *recv_gossip(struct io_conn *conn,
#if DEVELOPER #if DEVELOPER
static void memleak_daemon_cb(struct htable *memtable, struct daemon *daemon) static void memleak_daemon_cb(struct htable *memtable, struct daemon *daemon)
{ {
memleak_remove_htable(memtable, &daemon->peers.raw); memleak_scan_htable(memtable, &daemon->peers.raw);
} }
#endif /* DEVELOPER */ #endif /* DEVELOPER */

View File

@@ -807,10 +807,10 @@ static void dev_gossip_memleak(struct daemon *daemon, const u8 *msg)
struct htable *memtable; struct htable *memtable;
bool found_leak; bool found_leak;
memtable = memleak_find_allocations(tmpctx, msg, msg); memtable = memleak_start(tmpctx, msg, msg);
/* Now delete daemon and those which it has pointers to. */ /* Now delete daemon and those which it has pointers to. */
memleak_remove_region(memtable, daemon, sizeof(*daemon)); memleak_scan_obj(memtable, daemon);
found_leak = dump_memleak(memtable, memleak_status_broken); found_leak = dump_memleak(memtable, memleak_status_broken);
daemon_conn_send(daemon->master, daemon_conn_send(daemon->master,

View File

@@ -222,16 +222,16 @@ static void memleak_help_routing_tables(struct htable *memtable,
struct node *n; struct node *n;
struct node_map_iter nit; struct node_map_iter nit;
memleak_remove_htable(memtable, &rstate->nodes->raw); memleak_scan_htable(memtable, &rstate->nodes->raw);
memleak_remove_htable(memtable, &rstate->pending_node_map->raw); memleak_scan_htable(memtable, &rstate->pending_node_map->raw);
memleak_remove_htable(memtable, &rstate->pending_cannouncements.raw); memleak_scan_htable(memtable, &rstate->pending_cannouncements.raw);
memleak_remove_uintmap(memtable, &rstate->unupdated_chanmap); memleak_scan_uintmap(memtable, &rstate->unupdated_chanmap);
for (n = node_map_first(rstate->nodes, &nit); for (n = node_map_first(rstate->nodes, &nit);
n; n;
n = node_map_next(rstate->nodes, &nit)) { n = node_map_next(rstate->nodes, &nit)) {
if (node_uses_chan_map(n)) if (node_uses_chan_map(n))
memleak_remove_htable(memtable, &n->chans.map.raw); memleak_scan_htable(memtable, &n->chans.map.raw);
} }
} }
#endif /* DEVELOPER */ #endif /* DEVELOPER */

View File

@@ -95,12 +95,12 @@ struct gossip_store *gossip_store_new(struct routing_state *rstate UNNEEDED,
/* Generated stub for memleak_add_helper_ */ /* Generated stub for memleak_add_helper_ */
void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED, void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED,
const tal_t *)){ } const tal_t *)){ }
/* Generated stub for memleak_remove_htable */ /* Generated stub for memleak_scan_htable */
void memleak_remove_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED) void memleak_scan_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED)
{ fprintf(stderr, "memleak_remove_htable called!\n"); abort(); } { fprintf(stderr, "memleak_scan_htable called!\n"); abort(); }
/* Generated stub for memleak_remove_intmap_ */ /* Generated stub for memleak_scan_intmap_ */
void memleak_remove_intmap_(struct htable *memtable UNNEEDED, const struct intmap *m UNNEEDED) void memleak_scan_intmap_(struct htable *memtable UNNEEDED, const struct intmap *m UNNEEDED)
{ fprintf(stderr, "memleak_remove_intmap_ called!\n"); abort(); } { fprintf(stderr, "memleak_scan_intmap_ called!\n"); abort(); }
/* Generated stub for nannounce_different */ /* Generated stub for nannounce_different */
bool nannounce_different(struct gossip_store *gs UNNEEDED, bool nannounce_different(struct gossip_store *gs UNNEEDED,
const struct node *node UNNEEDED, const struct node *node UNNEEDED,

View File

@@ -62,12 +62,12 @@ void gossip_store_mark_channel_deleted(struct gossip_store *gs UNNEEDED,
/* Generated stub for memleak_add_helper_ */ /* Generated stub for memleak_add_helper_ */
void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED, void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED,
const tal_t *)){ } const tal_t *)){ }
/* Generated stub for memleak_remove_htable */ /* Generated stub for memleak_scan_htable */
void memleak_remove_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED) void memleak_scan_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED)
{ fprintf(stderr, "memleak_remove_htable called!\n"); abort(); } { fprintf(stderr, "memleak_scan_htable called!\n"); abort(); }
/* Generated stub for memleak_remove_intmap_ */ /* Generated stub for memleak_scan_intmap_ */
void memleak_remove_intmap_(struct htable *memtable UNNEEDED, const struct intmap *m UNNEEDED) void memleak_scan_intmap_(struct htable *memtable UNNEEDED, const struct intmap *m UNNEEDED)
{ fprintf(stderr, "memleak_remove_intmap_ called!\n"); abort(); } { fprintf(stderr, "memleak_scan_intmap_ called!\n"); abort(); }
/* Generated stub for nannounce_different */ /* Generated stub for nannounce_different */
bool nannounce_different(struct gossip_store *gs UNNEEDED, bool nannounce_different(struct gossip_store *gs UNNEEDED,
const struct node *node UNNEEDED, const struct node *node UNNEEDED,

View File

@@ -555,17 +555,15 @@ static struct io_plan *handle_memleak(struct io_conn *conn,
bool found_leak; bool found_leak;
u8 *reply; u8 *reply;
memtable = memleak_find_allocations(tmpctx, msg_in, msg_in); memtable = memleak_start(tmpctx, msg_in, msg_in);
/* Now delete clients and anything they point to. */ /* Now note clients and anything they point to. */
memleak_remove_region(memtable, memleak_scan_region(memtable, dbid_zero_clients, sizeof(dbid_zero_clients));
dbid_zero_clients, sizeof(dbid_zero_clients)); memleak_scan_uintmap(memtable, &clients);
memleak_remove_uintmap(memtable, &clients); memleak_scan_obj(memtable, status_conn);
memleak_remove_region(memtable,
status_conn, tal_bytelen(status_conn));
memleak_remove_pointer(memtable, dev_force_privkey); memleak_ptr(memtable, dev_force_privkey);
memleak_remove_pointer(memtable, dev_force_bip32_seed); memleak_ptr(memtable, dev_force_bip32_seed);
found_leak = dump_memleak(memtable, memleak_status_broken); found_leak = dump_memleak(memtable, memleak_status_broken);
reply = towire_hsmd_dev_memleak_reply(NULL, found_leak); reply = towire_hsmd_dev_memleak_reply(NULL, found_leak);

View File

@@ -1187,7 +1187,7 @@ static void destroy_jsonrpc(struct jsonrpc *jsonrpc)
static void memleak_help_jsonrpc(struct htable *memtable, static void memleak_help_jsonrpc(struct htable *memtable,
struct jsonrpc *jsonrpc) struct jsonrpc *jsonrpc)
{ {
memleak_remove_strmap(memtable, &jsonrpc->usagemap); memleak_scan_strmap(memtable, &jsonrpc->usagemap);
} }
#endif /* DEVELOPER */ #endif /* DEVELOPER */

View File

@@ -335,7 +335,7 @@ static void destroy_alt_subdaemons(struct lightningd *ld)
static void memleak_help_alt_subdaemons(struct htable *memtable, static void memleak_help_alt_subdaemons(struct htable *memtable,
struct lightningd *ld) struct lightningd *ld)
{ {
memleak_remove_strmap(memtable, &ld->alt_subdaemons); memleak_scan_strmap(memtable, &ld->alt_subdaemons);
} }
#endif /* DEVELOPER */ #endif /* DEVELOPER */

View File

@@ -143,17 +143,17 @@ static void finish_report(const struct leak_detect *leaks)
ld = cmd->ld; ld = cmd->ld;
/* Enter everything, except this cmd and its jcon */ /* Enter everything, except this cmd and its jcon */
memtable = memleak_find_allocations(cmd, cmd, cmd->jcon); memtable = memleak_start(cmd, cmd, cmd->jcon);
/* First delete known false positives. */ /* First delete known false positives. */
memleak_remove_htable(memtable, &ld->topology->txwatches.raw); memleak_scan_htable(memtable, &ld->topology->txwatches.raw);
memleak_remove_htable(memtable, &ld->topology->txowatches.raw); memleak_scan_htable(memtable, &ld->topology->txowatches.raw);
memleak_remove_htable(memtable, &ld->htlcs_in.raw); memleak_scan_htable(memtable, &ld->htlcs_in.raw);
memleak_remove_htable(memtable, &ld->htlcs_out.raw); memleak_scan_htable(memtable, &ld->htlcs_out.raw);
memleak_remove_htable(memtable, &ld->htlc_sets.raw); memleak_scan_htable(memtable, &ld->htlc_sets.raw);
/* Now delete ld and those which it has pointers to. */ /* Now delete ld and those which it has pointers to. */
memleak_remove_region(memtable, ld, sizeof(*ld)); memleak_scan_obj(memtable, ld);
response = json_stream_success(cmd); response = json_stream_success(cmd);
json_array_start(response, "leaks"); json_array_start(response, "leaks");

View File

@@ -48,7 +48,7 @@ struct plugin_rpccall {
static void memleak_help_pending_requests(struct htable *memtable, static void memleak_help_pending_requests(struct htable *memtable,
struct plugins *plugins) struct plugins *plugins)
{ {
memleak_remove_strmap(memtable, &plugins->pending_requests); memleak_scan_strmap(memtable, &plugins->pending_requests);
} }
#endif /* DEVELOPER */ #endif /* DEVELOPER */

View File

@@ -2085,15 +2085,12 @@ static void handle_preimage(struct tracked_output **outs,
#if DEVELOPER #if DEVELOPER
static void memleak_remove_globals(struct htable *memtable, const tal_t *topctx) static void memleak_remove_globals(struct htable *memtable, const tal_t *topctx)
{ {
if (keyset) memleak_scan_obj(memtable, keyset);
memleak_remove_region(memtable, keyset, sizeof(*keyset)); memleak_ptr(memtable, remote_per_commitment_point);
memleak_remove_pointer(memtable, remote_per_commitment_point); memleak_ptr(memtable, remote_per_commitment_secret);
memleak_remove_pointer(memtable, remote_per_commitment_secret); memleak_ptr(memtable, topctx);
memleak_remove_pointer(memtable, topctx); memleak_scan_obj(memtable, missing_htlc_msgs);
memleak_remove_region(memtable, memleak_scan_obj(memtable, queued_msgs);
missing_htlc_msgs, tal_bytelen(missing_htlc_msgs));
memleak_remove_region(memtable,
queued_msgs, tal_bytelen(queued_msgs));
} }
static bool handle_dev_memleak(struct tracked_output **outs, const u8 *msg) static bool handle_dev_memleak(struct tracked_output **outs, const u8 *msg)
@@ -2104,10 +2101,10 @@ static bool handle_dev_memleak(struct tracked_output **outs, const u8 *msg)
if (!fromwire_onchaind_dev_memleak(msg)) if (!fromwire_onchaind_dev_memleak(msg))
return false; return false;
memtable = memleak_find_allocations(tmpctx, msg, msg); memtable = memleak_start(tmpctx, msg, msg);
/* Top-level context is parent of outs */ /* Top-level context is parent of outs */
memleak_remove_globals(memtable, tal_parent(outs)); memleak_remove_globals(memtable, tal_parent(outs));
memleak_remove_region(memtable, outs, tal_bytelen(outs)); memleak_scan_obj(memtable, outs);
found_leak = dump_memleak(memtable, memleak_status_broken); found_leak = dump_memleak(memtable, memleak_status_broken);
wire_sync_write(REQ_FD, wire_sync_write(REQ_FD,

View File

@@ -310,23 +310,28 @@ void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNE
/* AUTOGENERATED MOCKS END */ /* AUTOGENERATED MOCKS END */
#if DEVELOPER #if DEVELOPER
/* Generated stub for memleak_find_allocations */ /* Generated stub for memleak_ptr */
struct htable *memleak_find_allocations(const tal_t *ctx UNNEEDED, bool memleak_ptr(struct htable *memtable UNNEEDED, const void *p UNNEEDED)
const void *exclude1 UNNEEDED, { fprintf(stderr, "memleak_ptr called!\n"); abort(); }
const void *exclude2 UNNEEDED)
{ fprintf(stderr, "memleak_find_allocations called!\n"); abort(); }
/* Generated stub for memleak_remove_region */
void memleak_remove_region(struct htable *memtable UNNEEDED,
const void *p UNNEEDED, size_t bytelen UNNEEDED)
{ fprintf(stderr, "memleak_remove_region called!\n"); abort(); }
/* Generated stub for memleak_status_broken */
void memleak_status_broken(const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "memleak_status_broken called!\n"); abort(); }
/* Generated stub for dump_memleak */ /* Generated stub for dump_memleak */
bool dump_memleak(struct htable *memtable UNNEEDED, bool dump_memleak(struct htable *memtable UNNEEDED,
void (*print)(const char *fmt UNNEEDED, ...)) void (*print)(const char *fmt UNNEEDED, ...))
{ fprintf(stderr, "dump_memleak called!\n"); abort(); } { fprintf(stderr, "dump_memleak called!\n"); abort(); }
#endif /* Generated stub for memleak_scan_obj */
void memleak_scan_obj(struct htable *memtable UNNEEDED, const void *obj UNNEEDED)
{ fprintf(stderr, "memleak_scan_obj called!\n"); abort(); }
/* Generated stub for memleak_scan_region */
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)
{ fprintf(stderr, "memleak_start called!\n"); abort(); }
/* Generated stub for memleak_status_broken */
void memleak_status_broken(const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "memleak_status_broken called!\n"); abort(); }
#endif /* DEVELOPER */
/* Stubs which do get called. */ /* Stubs which do get called. */
u8 *towire_hsmd_sign_local_htlc_tx(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, bool option_anchor_outputs UNNEEDED) u8 *towire_hsmd_sign_local_htlc_tx(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, bool option_anchor_outputs UNNEEDED)

View File

@@ -127,15 +127,14 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx UNNEEDED,
/* Generated stub for master_badmsg */ /* Generated stub for master_badmsg */
void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg) void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg)
{ fprintf(stderr, "master_badmsg called!\n"); abort(); } { fprintf(stderr, "master_badmsg called!\n"); abort(); }
/* Generated stub for memleak_find_allocations */ /* Generated stub for memleak_scan_obj */
struct htable *memleak_find_allocations(const tal_t *ctx UNNEEDED, void memleak_scan_obj(struct htable *memtable UNNEEDED, const void *obj UNNEEDED)
const void *exclude1 UNNEEDED, { fprintf(stderr, "memleak_scan_obj called!\n"); abort(); }
const void *exclude2 UNNEEDED) /* Generated stub for memleak_start */
{ fprintf(stderr, "memleak_find_allocations called!\n"); abort(); } struct htable *memleak_start(const tal_t *ctx UNNEEDED,
/* Generated stub for memleak_remove_region */ const void *exclude1 UNNEEDED,
void memleak_remove_region(struct htable *memtable UNNEEDED, const void *exclude2 UNNEEDED)
const void *p UNNEEDED, size_t bytelen UNNEEDED) { fprintf(stderr, "memleak_start called!\n"); abort(); }
{ fprintf(stderr, "memleak_remove_region called!\n"); abort(); }
/* Generated stub for new_coin_channel_close */ /* Generated stub for new_coin_channel_close */
struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx UNNEEDED, struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED, const struct bitcoin_txid *txid UNNEEDED,
@@ -345,6 +344,9 @@ bool wire_sync_write(int fd UNNEEDED, const void *msg TAKES UNNEEDED)
/* AUTOGENERATED MOCKS END */ /* AUTOGENERATED MOCKS END */
#if DEVELOPER #if DEVELOPER
/* Generated stub for memleak_ptr */
bool memleak_ptr(struct htable *memtable UNNEEDED, const void *p UNNEEDED)
{ fprintf(stderr, "memleak_ptr called!\n"); abort(); }
/* Generated stub for memleak_status_broken */ /* Generated stub for memleak_status_broken */
void memleak_status_broken(const char *fmt UNNEEDED, ...) void memleak_status_broken(const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "memleak_status_broken called!\n"); abort(); } { fprintf(stderr, "memleak_status_broken called!\n"); abort(); }

View File

@@ -890,10 +890,10 @@ static void handle_dev_memleak(struct state *state, const u8 *msg)
/* Populate a hash table with all our allocations (except msg, which /* Populate a hash table with all our allocations (except msg, which
* is in use right now). */ * is in use right now). */
memtable = memleak_find_allocations(tmpctx, msg, msg); memtable = memleak_start(tmpctx, msg, msg);
/* Now delete state and things it has pointers to. */ /* Now delete state and things it has pointers to. */
memleak_remove_region(memtable, state, tal_bytelen(state)); memleak_scan_obj(memtable, state);
/* If there's anything left, dump it to logs, and return true. */ /* If there's anything left, dump it to logs, and return true. */
found_leak = dump_memleak(memtable, memleak_status_broken); found_leak = dump_memleak(memtable, memleak_status_broken);

View File

@@ -1301,10 +1301,10 @@ static void handle_dev_memleak(struct state *state, const u8 *msg)
/* Populate a hash table with all our allocations (except msg, which /* Populate a hash table with all our allocations (except msg, which
* is in use right now). */ * is in use right now). */
memtable = memleak_find_allocations(tmpctx, msg, msg); memtable = memleak_start(tmpctx, msg, msg);
/* Now delete state and things it has pointers to. */ /* Now delete state and things it has pointers to. */
memleak_remove_region(memtable, state, sizeof(*state)); memleak_scan_obj(memtable, state);
/* If there's anything left, dump it to logs, and return true. */ /* If there's anything left, dump it to logs, and return true. */
found_leak = dump_memleak(memtable, memleak_status_broken); found_leak = dump_memleak(memtable, memleak_status_broken);

View File

@@ -927,7 +927,7 @@ static void wait_and_check_bitcoind(struct plugin *p)
#if DEVELOPER #if DEVELOPER
static void memleak_mark_bitcoind(struct plugin *p, struct htable *memtable) static void memleak_mark_bitcoind(struct plugin *p, struct htable *memtable)
{ {
memleak_remove_region(memtable, bitcoind, sizeof(*bitcoind)); memleak_scan_obj(memtable, bitcoind);
} }
#endif #endif

View File

@@ -920,12 +920,12 @@ static struct command_result *json_commando_rune(struct command *cmd,
#if DEVELOPER #if DEVELOPER
static void memleak_mark_globals(struct plugin *p, struct htable *memtable) static void memleak_mark_globals(struct plugin *p, struct htable *memtable)
{ {
memleak_remove_region(memtable, outgoing_commands, tal_bytelen(outgoing_commands)); memleak_scan_obj(memtable, outgoing_commands);
memleak_remove_region(memtable, incoming_commands, tal_bytelen(incoming_commands)); memleak_scan_obj(memtable, incoming_commands);
memleak_remove_region(memtable, master_rune, sizeof(*master_rune)); memleak_scan_obj(memtable, master_rune);
memleak_remove_htable(memtable, &usage_table.raw); memleak_scan_htable(memtable, &usage_table.raw);
if (rune_counter) if (rune_counter)
memleak_remove_region(memtable, rune_counter, sizeof(*rune_counter)); memleak_scan_obj(memtable, rune_counter);
} }
#endif #endif

View File

@@ -1084,8 +1084,8 @@ static void tell_lightningd_lease_rates(struct plugin *p,
#if DEVELOPER #if DEVELOPER
static void memleak_mark(struct plugin *p, struct htable *memtable) static void memleak_mark(struct plugin *p, struct htable *memtable)
{ {
memleak_remove_region(memtable, &pending_opens, sizeof(pending_opens)); memleak_scan_list_head(memtable, &pending_opens);
memleak_remove_region(memtable, current_policy, sizeof(*current_policy)); memleak_scan_obj(memtable, current_policy);
} }
#endif #endif

View File

@@ -1350,16 +1350,16 @@ static void memleak_check(struct plugin *plugin, struct command *cmd)
{ {
struct htable *memtable; struct htable *memtable;
memtable = memleak_find_allocations(tmpctx, cmd, cmd); memtable = memleak_start(tmpctx, cmd, cmd);
/* Now delete plugin and anything it has pointers to. */ /* Now delete plugin and anything it has pointers to. */
memleak_remove_region(memtable, plugin, sizeof(*plugin)); memleak_scan_obj(memtable, plugin);
/* Memleak needs some help to see into strmaps */ /* Memleak needs some help to see into strmaps */
memleak_remove_strmap(memtable, &plugin->out_reqs); memleak_scan_strmap(memtable, &plugin->out_reqs);
/* We know usage strings are referred to. */ /* We know usage strings are referred to. */
memleak_remove_strmap(memtable, &cmd->plugin->usagemap); memleak_scan_strmap(memtable, &cmd->plugin->usagemap);
if (plugin->mark_mem) if (plugin->mark_mem)
plugin->mark_mem(plugin, memtable); plugin->mark_mem(plugin, memtable);

View File

@@ -571,7 +571,7 @@ static struct command_result *json_listpays(struct command *cmd,
#if DEVELOPER #if DEVELOPER
static void memleak_mark_payments(struct plugin *p, struct htable *memtable) static void memleak_mark_payments(struct plugin *p, struct htable *memtable)
{ {
memleak_remove_region(memtable, &payments, sizeof(payments)); memleak_scan_list_head(memtable, &payments);
} }
#endif #endif

View File

@@ -615,8 +615,7 @@ done:
#if DEVELOPER #if DEVELOPER
static void memleak_mark(struct plugin *p, struct htable *memtable) static void memleak_mark(struct plugin *p, struct htable *memtable)
{ {
memleak_remove_region(memtable, global_gossmap, memleak_scan_obj(memtable, global_gossmap);
tal_bytelen(global_gossmap));
} }
#endif #endif

View File

@@ -570,7 +570,7 @@ static const struct plugin_command commands[] = {
#if DEVELOPER #if DEVELOPER
static void mark_unreleased_txs(struct plugin *plugin, struct htable *memtable) static void mark_unreleased_txs(struct plugin *plugin, struct htable *memtable)
{ {
memleak_remove_region(memtable, &unreleased_txs, sizeof(unreleased_txs)); memleak_scan_list_head(memtable, &unreleased_txs);
} }
#endif #endif

View File

@@ -107,7 +107,7 @@ static struct command_result *json_testrpc(struct command *cmd,
static void memleak_mark(struct plugin *p, struct htable *memtable) static void memleak_mark(struct plugin *p, struct htable *memtable)
{ {
/* name_option is not a leak! */ /* name_option is not a leak! */
memleak_remove_region(memtable, &name_option, sizeof(name_option)); memleak_ptr(memtable, name_option);
} }
#endif /* DEVELOPER */ #endif /* DEVELOPER */