Browse Source

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 <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 6 years ago
committed by Christian Decker
parent
commit
112b7336a3
  1. 21
      common/memleak.c
  2. 10
      common/memleak.h
  3. 22
      lightningd/chaintopology.c
  4. 5
      lightningd/chaintopology.h
  5. 28
      lightningd/htlc_end.c
  6. 7
      lightningd/htlc_end.h
  7. 7
      lightningd/memdump.c

21
common/memleak.c

@ -2,6 +2,7 @@
#include <backtrace.h>
#include <ccan/crypto/siphash24/siphash24.h>
#include <ccan/htable/htable.h>
#include <ccan/intmap/intmap.h>
#include <common/daemon.h>
#include <common/memleak.h>
@ -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;

10
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);

22
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)

5
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 */

28
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 */

7
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 */

7
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);

Loading…
Cancel
Save