diff --git a/channeld/channeld.c b/channeld/channeld.c index f701d24aa..6fd127839 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -3652,10 +3652,10 @@ static void handle_dev_memleak(struct peer *peer, const u8 *msg) struct htable *memtable; 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. */ - memleak_remove_region(memtable, peer, tal_bytelen(peer)); + memleak_scan_obj(memtable, peer); found_leak = dump_memleak(memtable, memleak_status_broken); wire_sync_write(MASTER_FD, diff --git a/channeld/full_channel.c b/channeld/full_channel.c index 05448eb25..c991315cd 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -22,7 +22,7 @@ static void memleak_help_htlcmap(struct htable *memtable, struct htlc_map *htlcs) { - memleak_remove_htable(memtable, &htlcs->raw); + memleak_scan_htable(memtable, &htlcs->raw); } #endif /* DEVELOPER */ diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index 4992d9f9c..edc762505 100644 --- a/channeld/test/run-full_channel.c +++ b/channeld/test/run-full_channel.c @@ -19,9 +19,9 @@ void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct n /* Generated stub for memleak_add_helper_ */ void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED, const tal_t *)){ } -/* Generated stub for memleak_remove_htable */ -void memleak_remove_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED) -{ fprintf(stderr, "memleak_remove_htable called!\n"); abort(); } +/* Generated stub for memleak_scan_htable */ +void memleak_scan_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED) +{ fprintf(stderr, "memleak_scan_htable called!\n"); abort(); } /* Generated stub for status_failed */ void status_failed(enum status_failreason code UNNEEDED, const char *fmt UNNEEDED, ...) diff --git a/closingd/closingd.c b/closingd/closingd.c index 73b22ab34..d3f0623a3 100644 --- a/closingd/closingd.c +++ b/closingd/closingd.c @@ -554,14 +554,12 @@ static void closing_dev_memleak(const tal_t *ctx, u8 *scriptpubkey[NUM_SIDES], const u8 *funding_wscript) { - struct htable *memtable; + struct htable *memtable = memleak_start(tmpctx, NULL, NULL); - memtable = memleak_find_allocations(tmpctx, NULL, NULL); - - memleak_remove_pointer(memtable, ctx); - memleak_remove_pointer(memtable, scriptpubkey[LOCAL]); - memleak_remove_pointer(memtable, scriptpubkey[REMOTE]); - memleak_remove_pointer(memtable, funding_wscript); + memleak_ptr(memtable, ctx); + memleak_ptr(memtable, scriptpubkey[LOCAL]); + memleak_ptr(memtable, scriptpubkey[REMOTE]); + memleak_ptr(memtable, funding_wscript); dump_memleak(memtable, memleak_status_broken); } diff --git a/common/memleak.c b/common/memleak.c index 8f0332480..2ad2411e3 100644 --- a/common/memleak.c +++ b/common/memleak.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -65,7 +66,7 @@ static size_t hash_ptr(const void *elem, void *unused UNNEEDED) 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); } @@ -122,45 +123,54 @@ static void scan_for_pointers(struct htable *memtable, void *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)); } } -void memleak_remove_region(struct htable *memtable, - const void *ptr, size_t bytelen) +void memleak_scan_region(struct htable *memtable, const void *ptr, size_t len) { - pointer_referenced(memtable, ptr); - scan_for_pointers(memtable, ptr, bytelen); + scan_for_pointers(memtable, ptr, len); +} + +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) { const tal_t *i; - pointer_referenced(memtable, p); + memleak_ptr(memtable, p); for (i = tal_first(p); i; i = tal_next(i)) remove_with_children(memtable, i); } /* 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; const void *p; 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! */ -void memleak_remove_intmap_(struct htable *memtable, const struct intmap *m) +void memleak_scan_intmap_(struct htable *memtable, const struct intmap *m) { void *p; intmap_index_t 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_) @@ -168,15 +178,15 @@ static bool handle_strmap(const char *member, void *p, void *memtable_) struct htable *memtable = memtable_; /* membername may *not* be a tal ptr, but it can be! */ - pointer_referenced(memtable, member); - memleak_remove_region(memtable, p, tal_bytelen(p)); + memleak_ptr(memtable, member); + memleak_scan_obj(memtable, p); /* Keep going */ return true; } /* 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); } @@ -192,7 +202,7 @@ const void *memleak_get(struct htable *memtable, const uintptr_t **backtrace) const tal_t *i, *p; /* Remove memtable itself */ - pointer_referenced(memtable, memtable); + memleak_ptr(memtable, memtable); i = htable_first(memtable, &it); if (!i) @@ -273,14 +283,12 @@ static void call_memleak_helpers(struct htable *memtable, const tal_t *p) mh->cb(memtable, p); } else if (strends(name, " **NOTLEAK**") || strends(name, "_notleak")) { - pointer_referenced(memtable, i); - memleak_remove_region(memtable, i, - tal_bytelen(i)); + memleak_ptr(memtable, i); + memleak_scan_obj(memtable, i); } else if (strends(name, " **NOTLEAK_IGNORE_CHILDREN**")) { remove_with_children(memtable, i); - memleak_remove_region(memtable, i, - tal_bytelen(i)); + memleak_scan_obj(memtable, 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, - const void *exclude1, - const void *exclude2) +struct htable *memleak_start(const tal_t *ctx, + const void *exclude1, + const void *exclude2) { struct htable *memtable = tal(ctx, struct htable); htable_init(memtable, hash_ptr, NULL); diff --git a/common/memleak.h b/common/memleak.h index aa72ba581..c06014ea0 100644 --- a/common/memleak.h +++ b/common/memleak.h @@ -6,6 +6,7 @@ #include struct htable; +struct list_head; /** * 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 *)); /** - * 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 * @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_find_allocations(const tal_t *ctx, - const void *exclude1, - const void *exclude2); +struct htable *memleak_start(const tal_t *ctx, + const void *exclude1, + const void *exclude2); /** - * memleak_remove_region - remove this region and anything it references - * @memtable: the memtable create by memleak_find_allocations. - * @p: the pointer to remove. - * @bytelen: the bytes within it to scan for more pointers. + * memleak_ptr: this pointer is not a memleak. + * @memtable: the memtable create by memleak_start. + * @p: the pointer. * - * This removes @p from the memtable, then looks for any tal pointers - * inside between @p and @p + @bytelen and calls - * memleak_remove_region() on those if not already removed. + * This tells memleak that @p (a tal allocation) is not a leak. Returns + * true if it was in the memleak table (it will no longer be). */ -void memleak_remove_region(struct htable *memtable, - const void *p, size_t bytelen); +bool memleak_ptr(struct htable *memtable, const void *p); /** - * memleak_remove_pointer - remove this pointer - * @memtable: the memtable create by memleak_find_allocations. - * @p: the pointer to remove. + * memleak_scan_obj - this tal object and anything it references are not leaks. + * @memtable: the memtable create by memleak_start. + * @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) \ - memleak_remove_region((memtable), (p), 0) +void memleak_scan_obj(struct htable *memtable, const void *obj); -/* 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_remove_intmap_(memtable, uintmap_unwrap_(umap)) +/** + * memleak_scan_region - scan a non-tal allocation for references. + * @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; -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). */ -#define memleak_remove_strmap(memtable, strmap) \ - memleak_remove_strmap_((memtable), tcon_unwrap(strmap)) -void memleak_remove_strmap_(struct htable *memtable, const struct strmap *m); +/* Objects inside this strmap (which is opaque to memleak) are not leaks. */ +#define memleak_scan_strmap(memtable, strmap) \ + memleak_scan_strmap_((memtable), tcon_unwrap(strmap)) +void memleak_scan_strmap_(struct htable *memtable, const struct strmap *m); /** * memleak_get: get (and remove) a leak from memtable, or NULL diff --git a/connectd/connectd.c b/connectd/connectd.c index a5fa736aa..49bd268a1 100644 --- a/connectd/connectd.c +++ b/connectd/connectd.c @@ -1860,11 +1860,11 @@ static void dev_connect_memleak(struct daemon *daemon, const u8 *msg) struct htable *memtable; 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. */ - memleak_remove_region(memtable, daemon, sizeof(daemon)); - memleak_remove_htable(memtable, &daemon->peers.raw); + memleak_scan_obj(memtable, daemon); + memleak_scan_htable(memtable, &daemon->peers.raw); found_leak = dump_memleak(memtable, memleak_status_broken); daemon_conn_send(daemon->master, @@ -2003,7 +2003,7 @@ static struct io_plan *recv_gossip(struct io_conn *conn, #if DEVELOPER 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 */ diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 224db2220..9cbbfc21d 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -807,10 +807,10 @@ static void dev_gossip_memleak(struct daemon *daemon, const u8 *msg) struct htable *memtable; 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. */ - memleak_remove_region(memtable, daemon, sizeof(*daemon)); + memleak_scan_obj(memtable, daemon); found_leak = dump_memleak(memtable, memleak_status_broken); daemon_conn_send(daemon->master, diff --git a/gossipd/routing.c b/gossipd/routing.c index 253fffd06..d9dcdf72b 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -222,16 +222,16 @@ static void memleak_help_routing_tables(struct htable *memtable, struct node *n; struct node_map_iter nit; - memleak_remove_htable(memtable, &rstate->nodes->raw); - memleak_remove_htable(memtable, &rstate->pending_node_map->raw); - memleak_remove_htable(memtable, &rstate->pending_cannouncements.raw); - memleak_remove_uintmap(memtable, &rstate->unupdated_chanmap); + memleak_scan_htable(memtable, &rstate->nodes->raw); + memleak_scan_htable(memtable, &rstate->pending_node_map->raw); + memleak_scan_htable(memtable, &rstate->pending_cannouncements.raw); + memleak_scan_uintmap(memtable, &rstate->unupdated_chanmap); for (n = node_map_first(rstate->nodes, &nit); n; n = node_map_next(rstate->nodes, &nit)) { if (node_uses_chan_map(n)) - memleak_remove_htable(memtable, &n->chans.map.raw); + memleak_scan_htable(memtable, &n->chans.map.raw); } } #endif /* DEVELOPER */ diff --git a/gossipd/test/run-check_channel_announcement.c b/gossipd/test/run-check_channel_announcement.c index d095f22b4..fc8f88884 100644 --- a/gossipd/test/run-check_channel_announcement.c +++ b/gossipd/test/run-check_channel_announcement.c @@ -95,12 +95,12 @@ struct gossip_store *gossip_store_new(struct routing_state *rstate UNNEEDED, /* Generated stub for memleak_add_helper_ */ void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED, const tal_t *)){ } -/* Generated stub for memleak_remove_htable */ -void memleak_remove_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED) -{ fprintf(stderr, "memleak_remove_htable called!\n"); abort(); } -/* Generated stub for memleak_remove_intmap_ */ -void memleak_remove_intmap_(struct htable *memtable UNNEEDED, const struct intmap *m UNNEEDED) -{ fprintf(stderr, "memleak_remove_intmap_ called!\n"); abort(); } +/* Generated stub for memleak_scan_htable */ +void memleak_scan_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED) +{ fprintf(stderr, "memleak_scan_htable called!\n"); abort(); } +/* Generated stub for memleak_scan_intmap_ */ +void memleak_scan_intmap_(struct htable *memtable UNNEEDED, const struct intmap *m UNNEEDED) +{ fprintf(stderr, "memleak_scan_intmap_ called!\n"); abort(); } /* Generated stub for nannounce_different */ bool nannounce_different(struct gossip_store *gs UNNEEDED, const struct node *node UNNEEDED, diff --git a/gossipd/test/run-txout_failure.c b/gossipd/test/run-txout_failure.c index 239cd6c9e..2307c1d7d 100644 --- a/gossipd/test/run-txout_failure.c +++ b/gossipd/test/run-txout_failure.c @@ -62,12 +62,12 @@ void gossip_store_mark_channel_deleted(struct gossip_store *gs UNNEEDED, /* Generated stub for memleak_add_helper_ */ void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED, const tal_t *)){ } -/* Generated stub for memleak_remove_htable */ -void memleak_remove_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED) -{ fprintf(stderr, "memleak_remove_htable called!\n"); abort(); } -/* Generated stub for memleak_remove_intmap_ */ -void memleak_remove_intmap_(struct htable *memtable UNNEEDED, const struct intmap *m UNNEEDED) -{ fprintf(stderr, "memleak_remove_intmap_ called!\n"); abort(); } +/* Generated stub for memleak_scan_htable */ +void memleak_scan_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED) +{ fprintf(stderr, "memleak_scan_htable called!\n"); abort(); } +/* Generated stub for memleak_scan_intmap_ */ +void memleak_scan_intmap_(struct htable *memtable UNNEEDED, const struct intmap *m UNNEEDED) +{ fprintf(stderr, "memleak_scan_intmap_ called!\n"); abort(); } /* Generated stub for nannounce_different */ bool nannounce_different(struct gossip_store *gs UNNEEDED, const struct node *node UNNEEDED, diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index 85875bf30..aae54bedd 100644 --- a/hsmd/hsmd.c +++ b/hsmd/hsmd.c @@ -555,17 +555,15 @@ static struct io_plan *handle_memleak(struct io_conn *conn, bool found_leak; 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. */ - memleak_remove_region(memtable, - dbid_zero_clients, sizeof(dbid_zero_clients)); - memleak_remove_uintmap(memtable, &clients); - memleak_remove_region(memtable, - status_conn, tal_bytelen(status_conn)); + /* Now note clients and anything they point to. */ + memleak_scan_region(memtable, dbid_zero_clients, sizeof(dbid_zero_clients)); + memleak_scan_uintmap(memtable, &clients); + memleak_scan_obj(memtable, status_conn); - memleak_remove_pointer(memtable, dev_force_privkey); - memleak_remove_pointer(memtable, dev_force_bip32_seed); + memleak_ptr(memtable, dev_force_privkey); + memleak_ptr(memtable, dev_force_bip32_seed); found_leak = dump_memleak(memtable, memleak_status_broken); reply = towire_hsmd_dev_memleak_reply(NULL, found_leak); diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index fbe74bb1b..58a1d6011 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -1187,7 +1187,7 @@ static void destroy_jsonrpc(struct jsonrpc *jsonrpc) static void memleak_help_jsonrpc(struct htable *memtable, struct jsonrpc *jsonrpc) { - memleak_remove_strmap(memtable, &jsonrpc->usagemap); + memleak_scan_strmap(memtable, &jsonrpc->usagemap); } #endif /* DEVELOPER */ diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 29d5da761..7aaf91687 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -335,7 +335,7 @@ static void destroy_alt_subdaemons(struct lightningd *ld) static void memleak_help_alt_subdaemons(struct htable *memtable, struct lightningd *ld) { - memleak_remove_strmap(memtable, &ld->alt_subdaemons); + memleak_scan_strmap(memtable, &ld->alt_subdaemons); } #endif /* DEVELOPER */ diff --git a/lightningd/memdump.c b/lightningd/memdump.c index 8adb83b51..f279aca8e 100644 --- a/lightningd/memdump.c +++ b/lightningd/memdump.c @@ -143,17 +143,17 @@ static void finish_report(const struct leak_detect *leaks) ld = cmd->ld; /* 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. */ - memleak_remove_htable(memtable, &ld->topology->txwatches.raw); - memleak_remove_htable(memtable, &ld->topology->txowatches.raw); - memleak_remove_htable(memtable, &ld->htlcs_in.raw); - memleak_remove_htable(memtable, &ld->htlcs_out.raw); - memleak_remove_htable(memtable, &ld->htlc_sets.raw); + memleak_scan_htable(memtable, &ld->topology->txwatches.raw); + memleak_scan_htable(memtable, &ld->topology->txowatches.raw); + memleak_scan_htable(memtable, &ld->htlcs_in.raw); + memleak_scan_htable(memtable, &ld->htlcs_out.raw); + memleak_scan_htable(memtable, &ld->htlc_sets.raw); /* 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); json_array_start(response, "leaks"); diff --git a/lightningd/plugin.c b/lightningd/plugin.c index 2e006d5b4..b569d28f3 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -48,7 +48,7 @@ struct plugin_rpccall { static void memleak_help_pending_requests(struct htable *memtable, struct plugins *plugins) { - memleak_remove_strmap(memtable, &plugins->pending_requests); + memleak_scan_strmap(memtable, &plugins->pending_requests); } #endif /* DEVELOPER */ diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index 4a15b841b..3f75dac9f 100644 --- a/onchaind/onchaind.c +++ b/onchaind/onchaind.c @@ -2085,15 +2085,12 @@ static void handle_preimage(struct tracked_output **outs, #if DEVELOPER static void memleak_remove_globals(struct htable *memtable, const tal_t *topctx) { - if (keyset) - memleak_remove_region(memtable, keyset, sizeof(*keyset)); - memleak_remove_pointer(memtable, remote_per_commitment_point); - memleak_remove_pointer(memtable, remote_per_commitment_secret); - memleak_remove_pointer(memtable, topctx); - memleak_remove_region(memtable, - missing_htlc_msgs, tal_bytelen(missing_htlc_msgs)); - memleak_remove_region(memtable, - queued_msgs, tal_bytelen(queued_msgs)); + memleak_scan_obj(memtable, keyset); + memleak_ptr(memtable, remote_per_commitment_point); + memleak_ptr(memtable, remote_per_commitment_secret); + memleak_ptr(memtable, topctx); + memleak_scan_obj(memtable, missing_htlc_msgs); + memleak_scan_obj(memtable, queued_msgs); } 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)) return false; - memtable = memleak_find_allocations(tmpctx, msg, msg); + memtable = memleak_start(tmpctx, msg, msg); /* Top-level context is parent of 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); wire_sync_write(REQ_FD, diff --git a/onchaind/test/run-grind_feerate-bug.c b/onchaind/test/run-grind_feerate-bug.c index b7a1a215c..8423e972e 100644 --- a/onchaind/test/run-grind_feerate-bug.c +++ b/onchaind/test/run-grind_feerate-bug.c @@ -310,23 +310,28 @@ void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNE /* AUTOGENERATED MOCKS END */ #if DEVELOPER -/* Generated stub for memleak_find_allocations */ -struct htable *memleak_find_allocations(const tal_t *ctx UNNEEDED, - const void *exclude1 UNNEEDED, - 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 memleak_ptr */ +bool memleak_ptr(struct htable *memtable UNNEEDED, const void *p UNNEEDED) +{ fprintf(stderr, "memleak_ptr called!\n"); abort(); } /* Generated stub for dump_memleak */ bool dump_memleak(struct htable *memtable UNNEEDED, void (*print)(const char *fmt UNNEEDED, ...)) { 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. */ 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) diff --git a/onchaind/test/run-grind_feerate.c b/onchaind/test/run-grind_feerate.c index e88f79bd5..7e59d8fb2 100644 --- a/onchaind/test/run-grind_feerate.c +++ b/onchaind/test/run-grind_feerate.c @@ -127,15 +127,14 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx UNNEEDED, /* Generated stub for master_badmsg */ void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg) { fprintf(stderr, "master_badmsg called!\n"); abort(); } -/* Generated stub for memleak_find_allocations */ -struct htable *memleak_find_allocations(const tal_t *ctx UNNEEDED, - const void *exclude1 UNNEEDED, - 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_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_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 new_coin_channel_close */ struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx 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 */ #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 */ void memleak_status_broken(const char *fmt UNNEEDED, ...) { fprintf(stderr, "memleak_status_broken called!\n"); abort(); } diff --git a/openingd/dualopend.c b/openingd/dualopend.c index e215cca18..79a2b29f0 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -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 * 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. */ - 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. */ found_leak = dump_memleak(memtable, memleak_status_broken); diff --git a/openingd/openingd.c b/openingd/openingd.c index a7bd167f5..27a84737d 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -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 * 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. */ - memleak_remove_region(memtable, state, sizeof(*state)); + memleak_scan_obj(memtable, state); /* If there's anything left, dump it to logs, and return true. */ found_leak = dump_memleak(memtable, memleak_status_broken); diff --git a/plugins/bcli.c b/plugins/bcli.c index 7946dde76..b5c6a9b80 100644 --- a/plugins/bcli.c +++ b/plugins/bcli.c @@ -927,7 +927,7 @@ static void wait_and_check_bitcoind(struct plugin *p) #if DEVELOPER static void memleak_mark_bitcoind(struct plugin *p, struct htable *memtable) { - memleak_remove_region(memtable, bitcoind, sizeof(*bitcoind)); + memleak_scan_obj(memtable, bitcoind); } #endif diff --git a/plugins/commando.c b/plugins/commando.c index 820d31ac2..ae770e376 100644 --- a/plugins/commando.c +++ b/plugins/commando.c @@ -920,12 +920,12 @@ static struct command_result *json_commando_rune(struct command *cmd, #if DEVELOPER static void memleak_mark_globals(struct plugin *p, struct htable *memtable) { - memleak_remove_region(memtable, outgoing_commands, tal_bytelen(outgoing_commands)); - memleak_remove_region(memtable, incoming_commands, tal_bytelen(incoming_commands)); - memleak_remove_region(memtable, master_rune, sizeof(*master_rune)); - memleak_remove_htable(memtable, &usage_table.raw); + memleak_scan_obj(memtable, outgoing_commands); + memleak_scan_obj(memtable, incoming_commands); + memleak_scan_obj(memtable, master_rune); + memleak_scan_htable(memtable, &usage_table.raw); if (rune_counter) - memleak_remove_region(memtable, rune_counter, sizeof(*rune_counter)); + memleak_scan_obj(memtable, rune_counter); } #endif diff --git a/plugins/funder.c b/plugins/funder.c index e4c1e0a1e..6575f2202 100644 --- a/plugins/funder.c +++ b/plugins/funder.c @@ -1084,8 +1084,8 @@ static void tell_lightningd_lease_rates(struct plugin *p, #if DEVELOPER static void memleak_mark(struct plugin *p, struct htable *memtable) { - memleak_remove_region(memtable, &pending_opens, sizeof(pending_opens)); - memleak_remove_region(memtable, current_policy, sizeof(*current_policy)); + memleak_scan_list_head(memtable, &pending_opens); + memleak_scan_obj(memtable, current_policy); } #endif diff --git a/plugins/libplugin.c b/plugins/libplugin.c index e39a507c1..0d4afafc2 100644 --- a/plugins/libplugin.c +++ b/plugins/libplugin.c @@ -1350,16 +1350,16 @@ static void memleak_check(struct plugin *plugin, struct command *cmd) { 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. */ - memleak_remove_region(memtable, plugin, sizeof(*plugin)); + memleak_scan_obj(memtable, plugin); /* 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. */ - memleak_remove_strmap(memtable, &cmd->plugin->usagemap); + memleak_scan_strmap(memtable, &cmd->plugin->usagemap); if (plugin->mark_mem) plugin->mark_mem(plugin, memtable); diff --git a/plugins/pay.c b/plugins/pay.c index d08610368..c67e48bd7 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -571,7 +571,7 @@ static struct command_result *json_listpays(struct command *cmd, #if DEVELOPER 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 diff --git a/plugins/topology.c b/plugins/topology.c index 56f815470..d20e65a8b 100644 --- a/plugins/topology.c +++ b/plugins/topology.c @@ -615,8 +615,7 @@ done: #if DEVELOPER static void memleak_mark(struct plugin *p, struct htable *memtable) { - memleak_remove_region(memtable, global_gossmap, - tal_bytelen(global_gossmap)); + memleak_scan_obj(memtable, global_gossmap); } #endif diff --git a/plugins/txprepare.c b/plugins/txprepare.c index 669daef98..d4a355634 100644 --- a/plugins/txprepare.c +++ b/plugins/txprepare.c @@ -570,7 +570,7 @@ static const struct plugin_command commands[] = { #if DEVELOPER 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 diff --git a/tests/plugins/test_libplugin.c b/tests/plugins/test_libplugin.c index a93f975ad..00f0c3196 100644 --- a/tests/plugins/test_libplugin.c +++ b/tests/plugins/test_libplugin.c @@ -107,7 +107,7 @@ static struct command_result *json_testrpc(struct command *cmd, static void memleak_mark(struct plugin *p, struct htable *memtable) { /* name_option is not a leak! */ - memleak_remove_region(memtable, &name_option, sizeof(name_option)); + memleak_ptr(memtable, name_option); } #endif /* DEVELOPER */