From 112b7336a39fee4748d8ab6285762ba3ab557017 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 24 Aug 2018 14:50:02 +0930 Subject: [PATCH] memleak: create and use a generic htable helper and generic intmap helper. memleak can't see into htables, as it overloads unused pointer bits. And it can't see into intmap, since they use malloc (it only looks for tal pointers). Signed-off-by: Rusty Russell --- common/memleak.c | 21 +++++++++++++++++++++ common/memleak.h | 10 ++++++++++ lightningd/chaintopology.c | 22 ---------------------- lightningd/chaintopology.h | 5 ----- lightningd/htlc_end.c | 28 ---------------------------- lightningd/htlc_end.h | 7 ------- lightningd/memdump.c | 7 ++++--- 7 files changed, 35 insertions(+), 65 deletions(-) diff --git a/common/memleak.c b/common/memleak.c index 74ba0b0db..88059d1b0 100644 --- a/common/memleak.c +++ b/common/memleak.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -167,6 +168,26 @@ void memleak_remove_referenced(struct htable *memtable, const void *root) pointer_referenced(memtable, memtable); } +/* memleak can't see inside hash tables, so do them manually */ +void memleak_remove_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_scan_region(memtable, p); +} + +/* FIXME: If uintmap used tal, this wouldn't be necessary! */ +void memleak_remove_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_scan_region(memtable, p); +} + static bool ptr_match(const void *candidate, void *ptr) { return candidate == ptr; diff --git a/common/memleak.h b/common/memleak.h index 70994ff87..e8787ee1c 100644 --- a/common/memleak.h +++ b/common/memleak.h @@ -36,6 +36,16 @@ struct htable *memleak_enter_allocations(const tal_t *ctx, /* Remove any pointers to memory under root */ void memleak_remove_referenced(struct htable *memtable, const void *root); +/* Remove any pointers inside this htable (which is opaque to memleak). */ +void memleak_remove_htable(struct htable *memtable, const struct htable *ht); + +/* Remove any pointers inside this uintmap (which is opaque to memleak). */ +#define memleak_remove_uintmap(memtable, umap) \ + memleak_remove_intmap_(memtable, uintmap_unwrap_(umap)) + +struct intmap; +void memleak_remove_intmap_(struct htable *memtable, const struct intmap *m); + /* Mark this pointer as being referenced, and search within for more. */ void memleak_scan_region(struct htable *memtable, const void *p); diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 07ac35725..657bca94f 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -623,28 +623,6 @@ u32 try_get_feerate(const struct chain_topology *topo, enum feerate feerate) return topo->feerate[feerate]; } -#if DEVELOPER -void chaintopology_mark_pointers_used(struct htable *memtable, - const struct chain_topology *topo) -{ - struct txwatch_hash_iter wit; - struct txwatch *w; - struct txowatch_hash_iter owit; - struct txowatch *ow; - - /* memleak can't see inside hash tables, so do them manually */ - for (w = txwatch_hash_first(&topo->txwatches, &wit); - w; - w = txwatch_hash_next(&topo->txwatches, &wit)) - memleak_scan_region(memtable, w); - - for (ow = txowatch_hash_first(&topo->txowatches, &owit); - ow; - ow = txowatch_hash_next(&topo->txowatches, &owit)) - memleak_scan_region(memtable, ow); -} -#endif /* DEVELOPER */ - /* On shutdown, channels get deleted last. That frees from our list, so * do it now instead. */ static void destroy_chain_topology(struct chain_topology *topo) diff --git a/lightningd/chaintopology.h b/lightningd/chaintopology.h index eb9573b7f..356d0b072 100644 --- a/lightningd/chaintopology.h +++ b/lightningd/chaintopology.h @@ -152,9 +152,4 @@ struct txlocator *locate_tx(const void *ctx, const struct chain_topology *topo, /* In channel_control.c */ void notify_feerate_change(struct lightningd *ld); - -#if DEVELOPER -void chaintopology_mark_pointers_used(struct htable *memtable, - const struct chain_topology *topo); -#endif #endif /* LIGHTNING_LIGHTNINGD_CHAINTOPOLOGY_H */ diff --git a/lightningd/htlc_end.c b/lightningd/htlc_end.c index d72242953..f4433dbf5 100644 --- a/lightningd/htlc_end.c +++ b/lightningd/htlc_end.c @@ -159,31 +159,3 @@ struct htlc_out *new_htlc_out(const tal_t *ctx, return htlc_out_check(hout, "new_htlc_out"); } - -#if DEVELOPER -void htlc_inmap_mark_pointers_used(struct htable *memtable, - const struct htlc_in_map *map) -{ - struct htlc_in *hin; - struct htlc_in_map_iter it; - - /* memleak can't see inside hash tables, so do them manually */ - for (hin = htlc_in_map_first(map, &it); - hin; - hin = htlc_in_map_next(map, &it)) - memleak_scan_region(memtable, hin); -} - -void htlc_outmap_mark_pointers_used(struct htable *memtable, - const struct htlc_out_map *map) -{ - struct htlc_out *hout; - struct htlc_out_map_iter it; - - /* memleak can't see inside hash tables, so do them manually */ - for (hout = htlc_out_map_first(map, &it); - hout; - hout = htlc_out_map_next(map, &it)) - memleak_scan_region(memtable, hout); -} -#endif /* DEVELOPER */ diff --git a/lightningd/htlc_end.h b/lightningd/htlc_end.h index a95ed4f2a..fdb43a9c1 100644 --- a/lightningd/htlc_end.h +++ b/lightningd/htlc_end.h @@ -138,11 +138,4 @@ struct htlc_out *htlc_out_check(const struct htlc_out *hout, const char *abortstr); struct htlc_in *htlc_in_check(const struct htlc_in *hin, const char *abortstr); -#if DEVELOPER -struct htable; -void htlc_inmap_mark_pointers_used(struct htable *memtable, - const struct htlc_in_map *map); -void htlc_outmap_mark_pointers_used(struct htable *memtable, - const struct htlc_out_map *map); -#endif /* DEVELOPER */ #endif /* LIGHTNING_LIGHTNINGD_HTLC_END_H */ diff --git a/lightningd/memdump.c b/lightningd/memdump.c index e26dc1905..5e9914c00 100644 --- a/lightningd/memdump.c +++ b/lightningd/memdump.c @@ -116,9 +116,10 @@ static void scan_mem(struct command *cmd, memtable = memleak_enter_allocations(cmd, cmd, cmd->jcon); /* First delete known false positives. */ - chaintopology_mark_pointers_used(memtable, ld->topology); - htlc_inmap_mark_pointers_used(memtable, &ld->htlcs_in); - htlc_outmap_mark_pointers_used(memtable, &ld->htlcs_out); + 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); /* Now delete ld and those which it has pointers to. */ memleak_remove_referenced(memtable, ld);