mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 07:34:24 +01:00
common/memleak: take over dump_memleak(), allow print pointer.
This will let plugins use it. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
b34953dd5e
commit
a5fee67b91
@@ -3496,7 +3496,7 @@ static void handle_dev_memleak(struct peer *peer, const u8 *msg)
|
|||||||
/* Now delete peer and things it has pointers to. */
|
/* Now delete peer and things it has pointers to. */
|
||||||
memleak_remove_region(memtable, peer, tal_bytelen(peer));
|
memleak_remove_region(memtable, peer, tal_bytelen(peer));
|
||||||
|
|
||||||
found_leak = dump_memleak(memtable);
|
found_leak = dump_memleak(memtable, memleak_status_broken);
|
||||||
wire_sync_write(MASTER_FD,
|
wire_sync_write(MASTER_FD,
|
||||||
take(towire_channeld_dev_memleak_reply(NULL,
|
take(towire_channeld_dev_memleak_reply(NULL,
|
||||||
found_leak)));
|
found_leak)));
|
||||||
|
|||||||
@@ -485,7 +485,7 @@ static void closing_dev_memleak(const tal_t *ctx,
|
|||||||
memleak_remove_pointer(memtable, scriptpubkey[REMOTE]);
|
memleak_remove_pointer(memtable, scriptpubkey[REMOTE]);
|
||||||
memleak_remove_pointer(memtable, funding_wscript);
|
memleak_remove_pointer(memtable, funding_wscript);
|
||||||
|
|
||||||
dump_memleak(memtable);
|
dump_memleak(memtable, memleak_status_broken);
|
||||||
}
|
}
|
||||||
#endif /* DEVELOPER */
|
#endif /* DEVELOPER */
|
||||||
|
|
||||||
|
|||||||
@@ -290,6 +290,59 @@ void memleak_init(void)
|
|||||||
if (backtrace_state)
|
if (backtrace_state)
|
||||||
add_backtrace_notifiers(NULL);
|
add_backtrace_notifiers(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dump_syminfo(void *data, uintptr_t pc UNUSED,
|
||||||
|
const char *filename, int lineno,
|
||||||
|
const char *function)
|
||||||
|
{
|
||||||
|
void PRINTF_FMT(1,2) (*print)(const char *fmt, ...) = data;
|
||||||
|
/* This can happen in backtraces. */
|
||||||
|
if (!filename || !function)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
print(" %s:%u (%s)", filename, lineno, function);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_leak_backtrace(const uintptr_t *bt,
|
||||||
|
void PRINTF_FMT(1,2)
|
||||||
|
(*print)(const char *fmt, ...))
|
||||||
|
{
|
||||||
|
if (!bt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* First one serves as counter. */
|
||||||
|
print(" backtrace:");
|
||||||
|
for (size_t i = 1; i < bt[0]; i++) {
|
||||||
|
backtrace_pcinfo(backtrace_state,
|
||||||
|
bt[i], dump_syminfo,
|
||||||
|
NULL, print);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dump_memleak(struct htable *memtable,
|
||||||
|
void PRINTF_FMT(1,2) (*print)(const char *fmt, ...))
|
||||||
|
{
|
||||||
|
const tal_t *i;
|
||||||
|
const uintptr_t *backtrace;
|
||||||
|
bool found_leak = false;
|
||||||
|
|
||||||
|
while ((i = memleak_get(memtable, &backtrace)) != NULL) {
|
||||||
|
print("MEMLEAK: %p", i);
|
||||||
|
if (tal_name(i))
|
||||||
|
print(" label=%s", tal_name(i));
|
||||||
|
|
||||||
|
dump_leak_backtrace(backtrace, print);
|
||||||
|
print(" parents:");
|
||||||
|
for (tal_t *p = tal_parent(i); p; p = tal_parent(p)) {
|
||||||
|
print(" %s", tal_name(p));
|
||||||
|
p = tal_parent(p);
|
||||||
|
}
|
||||||
|
found_leak = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return found_leak;
|
||||||
|
}
|
||||||
#else /* !DEVELOPER */
|
#else /* !DEVELOPER */
|
||||||
void *notleak_(const void *ptr, bool plus_children UNNEEDED)
|
void *notleak_(const void *ptr, bool plus_children UNNEEDED)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -121,4 +121,10 @@ const void *memleak_get(struct htable *memtable, const uintptr_t **backtrace);
|
|||||||
|
|
||||||
extern struct backtrace_state *backtrace_state;
|
extern struct backtrace_state *backtrace_state;
|
||||||
|
|
||||||
|
#if DEVELOPER
|
||||||
|
/* Only defined if DEVELOPER */
|
||||||
|
bool dump_memleak(struct htable *memtable,
|
||||||
|
void PRINTF_FMT(1,2) (*print)(const char *fmt, ...));
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* LIGHTNING_COMMON_MEMLEAK_H */
|
#endif /* LIGHTNING_COMMON_MEMLEAK_H */
|
||||||
|
|||||||
@@ -226,3 +226,14 @@ void master_badmsg(u32 type_expected, const u8 *msg)
|
|||||||
"Error parsing %u: %s",
|
"Error parsing %u: %s",
|
||||||
type_expected, tal_hex(tmpctx, msg));
|
type_expected, tal_hex(tmpctx, msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEVELOPER
|
||||||
|
/* Print BROKEN status: callback for dump_memleak. */
|
||||||
|
void memleak_status_broken(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
status_vfmt(LOG_BROKEN, NULL, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -74,4 +74,10 @@ void status_send_fatal(const u8 *msg TAKES) NORETURN;
|
|||||||
|
|
||||||
/* Only for sync status! */
|
/* Only for sync status! */
|
||||||
void status_send_fd(int fd);
|
void status_send_fd(int fd);
|
||||||
|
|
||||||
|
#if DEVELOPER
|
||||||
|
/* Print BROKEN status: callback for dump_memleak. */
|
||||||
|
void memleak_status_broken(const char *fmt, ...);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* LIGHTNING_COMMON_STATUS_H */
|
#endif /* LIGHTNING_COMMON_STATUS_H */
|
||||||
|
|||||||
@@ -50,58 +50,3 @@ void subdaemon_setup(int argc, char *argv[])
|
|||||||
|
|
||||||
daemon_setup(argv[0], status_backtrace_print, status_backtrace_exit);
|
daemon_setup(argv[0], status_backtrace_print, status_backtrace_exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEVELOPER
|
|
||||||
// Indented to avoid header-order check
|
|
||||||
#include <backtrace.h>
|
|
||||||
#include <common/memleak.h>
|
|
||||||
|
|
||||||
static int dump_syminfo(void *data UNUSED, uintptr_t pc UNUSED,
|
|
||||||
const char *filename, int lineno,
|
|
||||||
const char *function)
|
|
||||||
{
|
|
||||||
/* This can happen in backtraces. */
|
|
||||||
if (!filename || !function)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
status_debug(" %s:%u (%s)", filename, lineno, function);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dump_leak_backtrace(const uintptr_t *bt)
|
|
||||||
{
|
|
||||||
if (!bt)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* First one serves as counter. */
|
|
||||||
status_debug(" backtrace:");
|
|
||||||
for (size_t i = 1; i < bt[0]; i++) {
|
|
||||||
backtrace_pcinfo(backtrace_state,
|
|
||||||
bt[i], dump_syminfo,
|
|
||||||
NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool dump_memleak(struct htable *memtable)
|
|
||||||
{
|
|
||||||
const tal_t *i;
|
|
||||||
const uintptr_t *backtrace;
|
|
||||||
bool found_leak = false;
|
|
||||||
|
|
||||||
while ((i = memleak_get(memtable, &backtrace)) != NULL) {
|
|
||||||
status_broken("MEMLEAK: %p", i);
|
|
||||||
if (tal_name(i))
|
|
||||||
status_broken(" label=%s", tal_name(i));
|
|
||||||
|
|
||||||
dump_leak_backtrace(backtrace);
|
|
||||||
status_broken(" parents:");
|
|
||||||
for (tal_t *p = tal_parent(i); p; p = tal_parent(p)) {
|
|
||||||
status_broken(" %s", tal_name(p));
|
|
||||||
p = tal_parent(p);
|
|
||||||
}
|
|
||||||
found_leak = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return found_leak;
|
|
||||||
}
|
|
||||||
#endif /* DEVELOPER */
|
|
||||||
|
|||||||
@@ -7,7 +7,4 @@ struct htable;
|
|||||||
/* daemon_setup, but for subdaemons */
|
/* daemon_setup, but for subdaemons */
|
||||||
void subdaemon_setup(int argc, char *argv[]);
|
void subdaemon_setup(int argc, char *argv[]);
|
||||||
|
|
||||||
/* Only defined if DEVELOPER */
|
|
||||||
bool dump_memleak(struct htable *memtable);
|
|
||||||
|
|
||||||
#endif /* LIGHTNING_COMMON_SUBDAEMON_H */
|
#endif /* LIGHTNING_COMMON_SUBDAEMON_H */
|
||||||
|
|||||||
@@ -1734,7 +1734,7 @@ static struct io_plan *dev_connect_memleak(struct io_conn *conn,
|
|||||||
/* Now delete daemon and those which it has pointers to. */
|
/* Now delete daemon and those which it has pointers to. */
|
||||||
memleak_remove_region(memtable, daemon, sizeof(daemon));
|
memleak_remove_region(memtable, daemon, sizeof(daemon));
|
||||||
|
|
||||||
found_leak = dump_memleak(memtable);
|
found_leak = dump_memleak(memtable, memleak_status_broken);
|
||||||
daemon_conn_send(daemon->master,
|
daemon_conn_send(daemon->master,
|
||||||
take(towire_connectd_dev_memleak_reply(NULL,
|
take(towire_connectd_dev_memleak_reply(NULL,
|
||||||
found_leak)));
|
found_leak)));
|
||||||
|
|||||||
@@ -1260,7 +1260,7 @@ static struct io_plan *dev_gossip_memleak(struct io_conn *conn,
|
|||||||
/* Now delete daemon and those which it has pointers to. */
|
/* Now delete daemon and those which it has pointers to. */
|
||||||
memleak_remove_region(memtable, daemon, sizeof(*daemon));
|
memleak_remove_region(memtable, daemon, sizeof(*daemon));
|
||||||
|
|
||||||
found_leak = dump_memleak(memtable);
|
found_leak = dump_memleak(memtable, memleak_status_broken);
|
||||||
daemon_conn_send(daemon->master,
|
daemon_conn_send(daemon->master,
|
||||||
take(towire_gossipd_dev_memleak_reply(NULL,
|
take(towire_gossipd_dev_memleak_reply(NULL,
|
||||||
found_leak)));
|
found_leak)));
|
||||||
|
|||||||
@@ -580,7 +580,7 @@ static struct io_plan *handle_memleak(struct io_conn *conn,
|
|||||||
memleak_remove_pointer(memtable, dev_force_privkey);
|
memleak_remove_pointer(memtable, dev_force_privkey);
|
||||||
memleak_remove_pointer(memtable, dev_force_bip32_seed);
|
memleak_remove_pointer(memtable, dev_force_bip32_seed);
|
||||||
|
|
||||||
found_leak = dump_memleak(memtable);
|
found_leak = dump_memleak(memtable, memleak_status_broken);
|
||||||
reply = towire_hsmd_dev_memleak_reply(NULL, found_leak);
|
reply = towire_hsmd_dev_memleak_reply(NULL, found_leak);
|
||||||
return req_reply(conn, c, take(reply));
|
return req_reply(conn, c, take(reply));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2162,7 +2162,7 @@ static bool handle_dev_memleak(struct tracked_output **outs, const u8 *msg)
|
|||||||
memleak_remove_globals(memtable, tal_parent(outs));
|
memleak_remove_globals(memtable, tal_parent(outs));
|
||||||
memleak_remove_region(memtable, outs, tal_bytelen(outs));
|
memleak_remove_region(memtable, outs, tal_bytelen(outs));
|
||||||
|
|
||||||
found_leak = dump_memleak(memtable);
|
found_leak = dump_memleak(memtable, memleak_status_broken);
|
||||||
wire_sync_write(REQ_FD,
|
wire_sync_write(REQ_FD,
|
||||||
take(towire_onchaind_dev_memleak_reply(NULL,
|
take(towire_onchaind_dev_memleak_reply(NULL,
|
||||||
found_leak)));
|
found_leak)));
|
||||||
|
|||||||
@@ -25,9 +25,6 @@ bool derive_keyset(const struct pubkey *per_commitment_point UNNEEDED,
|
|||||||
bool option_static_remotekey UNNEEDED,
|
bool option_static_remotekey UNNEEDED,
|
||||||
struct keyset *keyset UNNEEDED)
|
struct keyset *keyset UNNEEDED)
|
||||||
{ fprintf(stderr, "derive_keyset called!\n"); abort(); }
|
{ fprintf(stderr, "derive_keyset called!\n"); abort(); }
|
||||||
/* Generated stub for dump_memleak */
|
|
||||||
bool dump_memleak(struct htable *memtable UNNEEDED)
|
|
||||||
{ fprintf(stderr, "dump_memleak called!\n"); abort(); }
|
|
||||||
/* Generated stub for fromwire */
|
/* Generated stub for fromwire */
|
||||||
const u8 *fromwire(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, void *copy UNNEEDED, size_t n UNNEEDED)
|
const u8 *fromwire(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, void *copy UNNEEDED, size_t n UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire called!\n"); abort(); }
|
||||||
@@ -115,15 +112,6 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx UNNEEDED,
|
|||||||
/* Generated stub for master_badmsg */
|
/* Generated stub for master_badmsg */
|
||||||
void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg)
|
void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg)
|
||||||
{ fprintf(stderr, "master_badmsg called!\n"); abort(); }
|
{ fprintf(stderr, "master_badmsg called!\n"); abort(); }
|
||||||
/* Generated stub for memleak_find_allocations */
|
|
||||||
struct htable *memleak_find_allocations(const tal_t *ctx UNNEEDED,
|
|
||||||
const void *exclude1 UNNEEDED,
|
|
||||||
const void *exclude2 UNNEEDED)
|
|
||||||
{ fprintf(stderr, "memleak_find_allocations called!\n"); abort(); }
|
|
||||||
/* Generated stub for memleak_remove_region */
|
|
||||||
void memleak_remove_region(struct htable *memtable UNNEEDED,
|
|
||||||
const void *p UNNEEDED, size_t bytelen UNNEEDED)
|
|
||||||
{ fprintf(stderr, "memleak_remove_region called!\n"); abort(); }
|
|
||||||
/* Generated stub for new_coin_chain_fees */
|
/* Generated stub for new_coin_chain_fees */
|
||||||
struct chain_coin_mvt *new_coin_chain_fees(const tal_t *ctx UNNEEDED,
|
struct chain_coin_mvt *new_coin_chain_fees(const tal_t *ctx UNNEEDED,
|
||||||
const char *account_name UNNEEDED,
|
const char *account_name UNNEEDED,
|
||||||
@@ -294,6 +282,25 @@ void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNE
|
|||||||
{ fprintf(stderr, "towire_u8_array called!\n"); abort(); }
|
{ fprintf(stderr, "towire_u8_array called!\n"); abort(); }
|
||||||
/* AUTOGENERATED MOCKS END */
|
/* AUTOGENERATED MOCKS END */
|
||||||
|
|
||||||
|
#if DEVELOPER
|
||||||
|
/* Generated stub for memleak_find_allocations */
|
||||||
|
struct htable *memleak_find_allocations(const tal_t *ctx UNNEEDED,
|
||||||
|
const void *exclude1 UNNEEDED,
|
||||||
|
const void *exclude2 UNNEEDED)
|
||||||
|
{ fprintf(stderr, "memleak_find_allocations called!\n"); abort(); }
|
||||||
|
/* Generated stub for memleak_remove_region */
|
||||||
|
void memleak_remove_region(struct htable *memtable UNNEEDED,
|
||||||
|
const void *p UNNEEDED, size_t bytelen UNNEEDED)
|
||||||
|
{ fprintf(stderr, "memleak_remove_region called!\n"); abort(); }
|
||||||
|
/* Generated stub for memleak_status_broken */
|
||||||
|
void memleak_status_broken(const char *fmt UNNEEDED, ...)
|
||||||
|
{ fprintf(stderr, "memleak_status_broken called!\n"); abort(); }
|
||||||
|
/* Generated stub for dump_memleak */
|
||||||
|
bool dump_memleak(struct htable *memtable UNNEEDED,
|
||||||
|
void (*print)(const char *fmt UNNEEDED, ...))
|
||||||
|
{ fprintf(stderr, "dump_memleak called!\n"); abort(); }
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Stubs which do get called. */
|
/* Stubs which do get called. */
|
||||||
u8 *towire_hsmd_sign_local_htlc_tx(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, bool option_anchor_outputs UNNEEDED)
|
u8 *towire_hsmd_sign_local_htlc_tx(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, bool option_anchor_outputs UNNEEDED)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ bool derive_keyset(const struct pubkey *per_commitment_point UNNEEDED,
|
|||||||
bool option_static_remotekey UNNEEDED,
|
bool option_static_remotekey UNNEEDED,
|
||||||
struct keyset *keyset UNNEEDED)
|
struct keyset *keyset UNNEEDED)
|
||||||
{ fprintf(stderr, "derive_keyset called!\n"); abort(); }
|
{ fprintf(stderr, "derive_keyset called!\n"); abort(); }
|
||||||
/* Generated stub for dump_memleak */
|
|
||||||
bool dump_memleak(struct htable *memtable UNNEEDED)
|
|
||||||
{ fprintf(stderr, "dump_memleak called!\n"); abort(); }
|
|
||||||
/* Generated stub for fromwire */
|
/* Generated stub for fromwire */
|
||||||
const u8 *fromwire(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, void *copy UNNEEDED, size_t n UNNEEDED)
|
const u8 *fromwire(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, void *copy UNNEEDED, size_t n UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire called!\n"); abort(); }
|
||||||
@@ -320,6 +317,16 @@ bool wire_sync_write(int fd UNNEEDED, const void *msg TAKES UNNEEDED)
|
|||||||
{ fprintf(stderr, "wire_sync_write called!\n"); abort(); }
|
{ fprintf(stderr, "wire_sync_write called!\n"); abort(); }
|
||||||
/* AUTOGENERATED MOCKS END */
|
/* AUTOGENERATED MOCKS END */
|
||||||
|
|
||||||
|
#if DEVELOPER
|
||||||
|
/* Generated stub for memleak_status_broken */
|
||||||
|
void memleak_status_broken(const char *fmt UNNEEDED, ...)
|
||||||
|
{ fprintf(stderr, "memleak_status_broken called!\n"); abort(); }
|
||||||
|
/* Generated stub for dump_memleak */
|
||||||
|
bool dump_memleak(struct htable *memtable UNNEEDED,
|
||||||
|
void (*print)(const char *fmt UNNEEDED, ...))
|
||||||
|
{ fprintf(stderr, "dump_memleak called!\n"); abort(); }
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
common_setup(argv[0]);
|
common_setup(argv[0]);
|
||||||
|
|||||||
@@ -44,16 +44,6 @@ struct htable *memleak_find_allocations(const tal_t *ctx UNNEEDED,
|
|||||||
const void *exclude1 UNNEEDED,
|
const void *exclude1 UNNEEDED,
|
||||||
const void *exclude2 UNNEEDED)
|
const void *exclude2 UNNEEDED)
|
||||||
{ fprintf(stderr, "memleak_find_allocations called!\n"); abort(); }
|
{ fprintf(stderr, "memleak_find_allocations called!\n"); abort(); }
|
||||||
/* Generated stub for memleak_get */
|
|
||||||
const void *memleak_get(struct htable *memtable UNNEEDED, const uintptr_t **backtrace UNNEEDED)
|
|
||||||
{ fprintf(stderr, "memleak_get called!\n"); abort(); }
|
|
||||||
/* Generated stub for memleak_init */
|
|
||||||
void memleak_init(void)
|
|
||||||
{ fprintf(stderr, "memleak_init called!\n"); abort(); }
|
|
||||||
/* Generated stub for memleak_remove_region */
|
|
||||||
void memleak_remove_region(struct htable *memtable UNNEEDED,
|
|
||||||
const void *p UNNEEDED, size_t bytelen UNNEEDED)
|
|
||||||
{ fprintf(stderr, "memleak_remove_region called!\n"); abort(); }
|
|
||||||
/* Generated stub for new_coin_penalty_sat */
|
/* Generated stub for new_coin_penalty_sat */
|
||||||
struct chain_coin_mvt *new_coin_penalty_sat(const tal_t *ctx UNNEEDED,
|
struct chain_coin_mvt *new_coin_penalty_sat(const tal_t *ctx UNNEEDED,
|
||||||
const char *account_name UNNEEDED,
|
const char *account_name UNNEEDED,
|
||||||
@@ -105,6 +95,20 @@ const char *version(void)
|
|||||||
/* Generated stub for dev_disconnect_init */
|
/* Generated stub for dev_disconnect_init */
|
||||||
void dev_disconnect_init(int fd UNNEEDED)
|
void dev_disconnect_init(int fd UNNEEDED)
|
||||||
{ fprintf(stderr, "dev_disconnect_init called!\n"); abort(); }
|
{ fprintf(stderr, "dev_disconnect_init called!\n"); abort(); }
|
||||||
|
/* Generated stub for dump_memleak */
|
||||||
|
bool dump_memleak(struct htable *memtable UNNEEDED,
|
||||||
|
void (*print)(const char *fmt UNNEEDED, ...))
|
||||||
|
{ fprintf(stderr, "dump_memleak called!\n"); abort(); }
|
||||||
|
/* Generated stub for memleak_init */
|
||||||
|
void memleak_init(void)
|
||||||
|
{ fprintf(stderr, "memleak_init called!\n"); abort(); }
|
||||||
|
/* Generated stub for memleak_remove_region */
|
||||||
|
void memleak_remove_region(struct htable *memtable UNNEEDED,
|
||||||
|
const void *p UNNEEDED, size_t bytelen UNNEEDED)
|
||||||
|
{ fprintf(stderr, "memleak_remove_region called!\n"); abort(); }
|
||||||
|
/* Generated stub for memleak_status_broken */
|
||||||
|
void memleak_status_broken(const char *fmt UNNEEDED, ...)
|
||||||
|
{ fprintf(stderr, "memleak_status_broken called!\n"); abort(); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Noops */
|
/* Noops */
|
||||||
|
|||||||
@@ -898,7 +898,7 @@ static void dualopend_dev_memleak(struct state *state)
|
|||||||
memleak_remove_region(memtable, state, tal_bytelen(state));
|
memleak_remove_region(memtable, state, tal_bytelen(state));
|
||||||
|
|
||||||
/* If there's anything left, dump it to logs, and return true. */
|
/* If there's anything left, dump it to logs, and return true. */
|
||||||
dump_memleak(memtable);
|
dump_memleak(memtable, memleak_status_broken);
|
||||||
}
|
}
|
||||||
#endif /* DEVELOPER */
|
#endif /* DEVELOPER */
|
||||||
|
|
||||||
|
|||||||
@@ -1234,7 +1234,7 @@ static void handle_dev_memleak(struct state *state, const u8 *msg)
|
|||||||
memleak_remove_region(memtable, state, sizeof(*state));
|
memleak_remove_region(memtable, state, sizeof(*state));
|
||||||
|
|
||||||
/* If there's anything left, dump it to logs, and return true. */
|
/* If there's anything left, dump it to logs, and return true. */
|
||||||
found_leak = dump_memleak(memtable);
|
found_leak = dump_memleak(memtable, memleak_status_broken);
|
||||||
wire_sync_write(REQ_FD,
|
wire_sync_write(REQ_FD,
|
||||||
take(towire_openingd_dev_memleak_reply(NULL,
|
take(towire_openingd_dev_memleak_reply(NULL,
|
||||||
found_leak)));
|
found_leak)));
|
||||||
|
|||||||
Reference in New Issue
Block a user