Browse Source

common/memleak: simplify notleak() handling.

Use the same "child of tal object" trick to mark things "notleak".

That simplifies things and means we don't have to track them being
reallocated.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
pull/2803/head
Rusty Russell 5 years ago
committed by Christian Decker
parent
commit
2652cc9704
  1. 3
      common/daemon.c
  2. 82
      common/memleak.c
  3. 3
      common/memleak.h

3
common/daemon.c

@ -157,9 +157,6 @@ void daemon_setup(const char *argv0,
void daemon_shutdown(void)
{
#if DEVELOPER
memleak_cleanup();
#endif
tal_free(tmpctx);
wally_cleanup(0);
}

82
common/memleak.c

@ -8,54 +8,26 @@
#include <common/utils.h>
#if DEVELOPER
static const void **notleaks;
static bool *notleak_children;
static bool memleak_track;
struct memleak_notleak {
bool plus_children;
};
struct memleak_helper {
void (*cb)(struct htable *memtable, const tal_t *);
};
static size_t find_notleak(const tal_t *ptr)
{
size_t i, nleaks = tal_count(notleaks);
for (i = 0; i < nleaks; i++)
if (notleaks[i] == ptr)
return i;
abort();
}
static void notleak_change(tal_t *ctx,
enum tal_notify_type type,
void *info)
{
size_t i;
if (type == TAL_NOTIFY_FREE) {
i = find_notleak(ctx);
memmove(notleaks + i, notleaks + i + 1,
sizeof(*notleaks) * (tal_count(notleaks) - i - 1));
memmove(notleak_children + i, notleak_children + i + 1,
sizeof(*notleak_children)
* (tal_count(notleak_children) - i - 1));
tal_resize(&notleaks, tal_count(notleaks) - 1);
tal_resize(&notleak_children, tal_count(notleak_children) - 1);
} else if (type == TAL_NOTIFY_MOVE) {
i = find_notleak(info);
notleaks[i] = ctx;
}
}
void *notleak_(const void *ptr, bool plus_children)
{
struct memleak_notleak *notleak;
/* If we're not tracking, don't do anything. */
if (!notleaks)
if (!memleak_track)
return cast_const(void *, ptr);
tal_arr_expand(&notleaks, ptr);
tal_arr_expand(&notleak_children, plus_children);
tal_add_notifier(ptr, TAL_NOTIFY_FREE|TAL_NOTIFY_MOVE, notleak_change);
notleak = tal(ptr, struct memleak_notleak);
notleak->plus_children = plus_children;
return cast_const(void *, ptr);
}
@ -86,8 +58,9 @@ static void children_into_htable(const void *exclude1, const void *exclude2,
if (streq(name, "backtrace"))
continue;
/* Don't add our own memleak_helpers */
if (strends(name, "struct memleak_helper"))
/* Don't add our own memleak_helpers or notleak() */
if (strends(name, "struct memleak_helper")
|| strends(name, "struct memleak_notleak"))
continue;
/* Don't add tal_link objects */
@ -145,19 +118,8 @@ static void remove_with_children(struct htable *memtable, const tal_t *p)
void memleak_remove_referenced(struct htable *memtable, const void *root)
{
size_t i;
/* Now delete the ones which are referenced. */
memleak_scan_region(memtable, root, tal_bytelen(root));
memleak_scan_region(memtable, notleaks, tal_bytelen(notleaks));
/* Those who asked tal children to be removed, do so. */
for (i = 0; i < tal_count(notleaks); i++)
if (notleak_children[i])
remove_with_children(memtable, notleaks[i]);
/* notleak_children array is not a leak */
pointer_referenced(memtable, notleak_children);
/* Remove memtable itself */
pointer_referenced(memtable, memtable);
@ -258,6 +220,7 @@ void memleak_add_helper_(const tal_t *p,
}
/* Handle allocations marked with helpers or notleak() */
static void call_memleak_helpers(struct htable *memtable, const tal_t *p)
{
const tal_t *i;
@ -268,6 +231,13 @@ static void call_memleak_helpers(struct htable *memtable, const tal_t *p)
if (name && strends(name, "struct memleak_helper")) {
const struct memleak_helper *mh = i;
mh->cb(memtable, p);
} else if (name && strends(name, "struct memleak_notleak")) {
const struct memleak_notleak *notleak = i;
if (notleak->plus_children)
remove_with_children(memtable, p);
else
pointer_referenced(memtable, p);
memleak_scan_region(memtable, p, tal_bytelen(p));
} else {
call_memleak_helpers(memtable, i);
}
@ -293,18 +263,10 @@ struct htable *memleak_enter_allocations(const tal_t *ctx,
void memleak_init(void)
{
assert(!notleaks);
notleaks = tal_arr(NULL, const void *, 0);
notleak_children = tal_arr(notleaks, bool, 0);
memleak_track = true;
if (backtrace_state)
add_backtrace_notifiers(NULL);
}
void memleak_cleanup(void)
{
notleaks = tal_free(notleaks);
}
#else /* !DEVELOPER */
void *notleak_(const void *ptr, bool plus_children UNNEEDED)
{

3
common/memleak.h

@ -41,9 +41,6 @@ void memleak_add_helper_(const tal_t *p, void (*cb)(struct htable *memtable,
/* Initialize memleak detection */
void memleak_init(void);
/* Free memleak detection. */
void memleak_cleanup(void);
/* Allocate a htable with all the memory we've allocated. */
struct htable *memleak_enter_allocations(const tal_t *ctx,
const void *exclude1,

Loading…
Cancel
Save