From 2652cc9704ac59c2d5d02ab07b96d779a9ba3a8d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 6 Sep 2019 14:13:05 +0930 Subject: [PATCH] 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 --- common/daemon.c | 3 -- common/memleak.c | 82 +++++++++++++----------------------------------- common/memleak.h | 3 -- 3 files changed, 22 insertions(+), 66 deletions(-) diff --git a/common/daemon.c b/common/daemon.c index fc93c1793..f93fa1884 100644 --- a/common/daemon.c +++ b/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); } diff --git a/common/memleak.c b/common/memleak.c index ff20bab70..09a4b2d62 100644 --- a/common/memleak.c +++ b/common/memleak.c @@ -8,54 +8,26 @@ #include #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(¬leaks, tal_count(notleaks) - 1); - tal_resize(¬leak_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(¬leaks, ptr); - tal_arr_expand(¬leak_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) { diff --git a/common/memleak.h b/common/memleak.h index c423eb50d..e93586878 100644 --- a/common/memleak.h +++ b/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,