mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
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>
This commit is contained in:
parent
aca2e4f722
commit
2652cc9704
@ -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);
|
||||
}
|
||||
|
@ -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(¬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)
|
||||
{
|
||||
|
@ -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…
Reference in New Issue
Block a user