mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-21 14:24:09 +01:00
dualopend: restore memleak calls.
And implement a timeout (20 seconds) just in case it's not listening. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
84e0e743eb
commit
d7ffb712e5
7 changed files with 85 additions and 14 deletions
|
@ -3026,6 +3026,8 @@ static unsigned int dual_opend_msg(struct subd *dualopend,
|
|||
case WIRE_DUALOPEND_SEND_TX_SIGS:
|
||||
case WIRE_DUALOPEND_SEND_SHUTDOWN:
|
||||
case WIRE_DUALOPEND_DEPTH_REACHED:
|
||||
case WIRE_DUALOPEND_DEV_MEMLEAK:
|
||||
case WIRE_DUALOPEND_DEV_MEMLEAK_REPLY:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -129,9 +129,19 @@ static void finish_report(const struct leak_detect *leaks)
|
|||
struct htable *memtable;
|
||||
const tal_t *i;
|
||||
const uintptr_t *backtrace;
|
||||
struct command *cmd = leaks->cmd;
|
||||
struct lightningd *ld = cmd->ld;
|
||||
struct json_stream *response = json_stream_success(cmd);
|
||||
struct command *cmd;
|
||||
struct lightningd *ld;
|
||||
struct json_stream *response;
|
||||
|
||||
/* If it timed out, we free ourselved and exit! */
|
||||
if (!leaks->cmd) {
|
||||
tal_free(leaks);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convenience variables */
|
||||
cmd = leaks->cmd;
|
||||
ld = cmd->ld;
|
||||
|
||||
/* Enter everything, except this cmd and its jcon */
|
||||
memtable = memleak_find_allocations(cmd, cmd, cmd->jcon);
|
||||
|
@ -146,6 +156,7 @@ static void finish_report(const struct leak_detect *leaks)
|
|||
/* Now delete ld and those which it has pointers to. */
|
||||
memleak_remove_region(memtable, ld, sizeof(*ld));
|
||||
|
||||
response = json_stream_success(cmd);
|
||||
json_array_start(response, "leaks");
|
||||
while ((i = memleak_get(memtable, &backtrace)) != NULL) {
|
||||
const tal_t *p;
|
||||
|
@ -176,6 +187,12 @@ static void finish_report(const struct leak_detect *leaks)
|
|||
was_pending(command_success(cmd, response));
|
||||
}
|
||||
|
||||
static void leak_detect_timeout(struct leak_detect *leak_detect)
|
||||
{
|
||||
finish_report(leak_detect);
|
||||
leak_detect->cmd = NULL;
|
||||
}
|
||||
|
||||
static void leak_detect_req_done(const struct subd_req *req,
|
||||
struct leak_detect *leak_detect)
|
||||
{
|
||||
|
@ -274,6 +291,10 @@ static struct command_result *json_memleak(struct command *cmd,
|
|||
|
||||
/* Ask all per-peer daemons */
|
||||
peer_dev_memleak(ld, leaks);
|
||||
|
||||
/* Set timer: dualopend doesn't always listen! */
|
||||
notleak(new_reltimer(ld->timers, leaks, time_from_sec(20),
|
||||
leak_detect_timeout, leaks));
|
||||
return command_still_pending(cmd);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include <lightningd/subd.h>
|
||||
#include <limits.h>
|
||||
#include <onchaind/onchaind_wiregen.h>
|
||||
#include <openingd/dualopend_wiregen.h>
|
||||
#include <openingd/openingd_wiregen.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
@ -2363,6 +2364,19 @@ static void openingd_memleak_req_done(struct subd *open_daemon,
|
|||
report_subd_memleak(leaks, open_daemon);
|
||||
}
|
||||
|
||||
static void dualopend_memleak_req_done(struct subd *dualopend,
|
||||
const u8 *msg, const int *fds UNUSED,
|
||||
struct leak_detect *leaks)
|
||||
{
|
||||
bool found_leak;
|
||||
|
||||
if (!fromwire_dualopend_dev_memleak_reply(msg, &found_leak))
|
||||
fatal("Bad dualopend_dev_memleak");
|
||||
|
||||
if (found_leak)
|
||||
report_subd_memleak(leaks, dualopend);
|
||||
}
|
||||
|
||||
void peer_dev_memleak(struct lightningd *ld, struct leak_detect *leaks)
|
||||
{
|
||||
struct peer *p;
|
||||
|
@ -2390,9 +2404,12 @@ void peer_dev_memleak(struct lightningd *ld, struct leak_detect *leaks)
|
|||
take(towire_onchaind_dev_memleak(NULL)),
|
||||
-1, 0, onchaind_memleak_req_done, leaks),
|
||||
leaks);
|
||||
} else if (streq(c->owner->name, "dualopend")) {
|
||||
start_leak_request(subd_req(c, c->owner,
|
||||
take(towire_dualopend_dev_memleak(NULL)),
|
||||
-1, 0, dualopend_memleak_req_done, leaks),
|
||||
leaks);
|
||||
}
|
||||
/* FIXME: dualopend doesn't support memleak
|
||||
* when we ask */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -207,6 +207,9 @@ bool fromwire_channeld_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNE
|
|||
/* Generated stub for fromwire_connectd_peer_connected */
|
||||
bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct wireaddr **remote_addr UNNEEDED, bool *incoming UNNEEDED, u8 **features UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_connectd_peer_connected called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_dualopend_dev_memleak_reply */
|
||||
bool fromwire_dualopend_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_dualopend_dev_memleak_reply called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_hsmd_sign_bolt12_reply */
|
||||
bool fromwire_hsmd_sign_bolt12_reply(const void *p UNNEEDED, struct bip340sig *sig UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_hsmd_sign_bolt12_reply called!\n"); abort(); }
|
||||
|
@ -634,6 +637,9 @@ u8 *towire_channeld_specific_feerates(const tal_t *ctx UNNEEDED, u32 feerate_bas
|
|||
/* Generated stub for towire_connectd_peer_final_msg */
|
||||
u8 *towire_connectd_peer_final_msg(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, const u8 *msg UNNEEDED)
|
||||
{ fprintf(stderr, "towire_connectd_peer_final_msg called!\n"); abort(); }
|
||||
/* Generated stub for towire_dualopend_dev_memleak */
|
||||
u8 *towire_dualopend_dev_memleak(const tal_t *ctx UNNEEDED)
|
||||
{ fprintf(stderr, "towire_dualopend_dev_memleak called!\n"); abort(); }
|
||||
/* Generated stub for towire_errorfmt */
|
||||
u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
|
||||
const struct channel_id *channel UNNEEDED,
|
||||
|
|
|
@ -881,18 +881,23 @@ static bool is_segwit_output(struct wally_tx_output *output,
|
|||
* at closing time, rather than when it askes.
|
||||
*/
|
||||
#if DEVELOPER
|
||||
static void dualopend_dev_memleak(struct state *state)
|
||||
static void handle_dev_memleak(struct state *state, const u8 *msg)
|
||||
{
|
||||
struct htable *memtable;
|
||||
bool found_leak;
|
||||
|
||||
/* Populate a hash table with all our allocations. */
|
||||
memtable = memleak_find_allocations(tmpctx, NULL, NULL);
|
||||
/* Populate a hash table with all our allocations (except msg, which
|
||||
* is in use right now). */
|
||||
memtable = memleak_find_allocations(tmpctx, msg, msg);
|
||||
|
||||
/* Now delete state and things it has pointers to. */
|
||||
memleak_remove_region(memtable, state, tal_bytelen(state));
|
||||
|
||||
/* If there's anything left, dump it to logs, and return true. */
|
||||
dump_memleak(memtable, memleak_status_broken);
|
||||
found_leak = dump_memleak(memtable, memleak_status_broken);
|
||||
wire_sync_write(REQ_FD,
|
||||
take(towire_dualopend_dev_memleak_reply(NULL,
|
||||
found_leak)));
|
||||
}
|
||||
#endif /* DEVELOPER */
|
||||
|
||||
|
@ -1053,7 +1058,14 @@ fetch_psbt_changes(struct state *state,
|
|||
psbt);
|
||||
|
||||
wire_sync_write(REQ_FD, take(msg));
|
||||
|
||||
msg = wire_sync_read(tmpctx, REQ_FD);
|
||||
#if DEVELOPER
|
||||
while (fromwire_dualopend_dev_memleak(msg)) {
|
||||
handle_dev_memleak(state, msg);
|
||||
msg = wire_sync_read(tmpctx, REQ_FD);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fromwire_dualopend_fail(msg, msg, &err)) {
|
||||
open_err_warn(state, "%s", err);
|
||||
|
@ -3601,6 +3613,11 @@ static u8 *handle_master_in(struct state *state)
|
|||
enum dualopend_wire t = fromwire_peektype(msg);
|
||||
|
||||
switch (t) {
|
||||
case WIRE_DUALOPEND_DEV_MEMLEAK:
|
||||
#if DEVELOPER
|
||||
handle_dev_memleak(state, msg);
|
||||
#endif
|
||||
return NULL;
|
||||
case WIRE_DUALOPEND_OPENER_INIT:
|
||||
opener_start(state, msg);
|
||||
return NULL;
|
||||
|
@ -3627,6 +3644,7 @@ static u8 *handle_master_in(struct state *state)
|
|||
case WIRE_DUALOPEND_GOT_RBF_OFFER_REPLY:
|
||||
case WIRE_DUALOPEND_RBF_VALID:
|
||||
case WIRE_DUALOPEND_VALIDATE_LEASE_REPLY:
|
||||
case WIRE_DUALOPEND_DEV_MEMLEAK_REPLY:
|
||||
|
||||
/* Messages we send */
|
||||
case WIRE_DUALOPEND_GOT_OFFER:
|
||||
|
@ -3949,11 +3967,6 @@ int main(int argc, char *argv[])
|
|||
dualopend_wire_name(fromwire_peektype(msg)));
|
||||
tal_free(msg);
|
||||
|
||||
#if DEVELOPER
|
||||
/* Now look for memory leaks. */
|
||||
dualopend_dev_memleak(state);
|
||||
#endif /* DEVELOPER */
|
||||
|
||||
/* This frees the entire tal tree. */
|
||||
tal_free(state);
|
||||
daemon_shutdown();
|
||||
|
|
|
@ -220,6 +220,12 @@ msgtype,dualopend_fail_fallen_behind,1028
|
|||
# Shutdown is complete, ready for closing negotiation. + peer_fd & gossip_fd.
|
||||
msgtype,dualopend_shutdown_complete,7025
|
||||
|
||||
# master -> dualopend: do you have a memleak?
|
||||
msgtype,dualopend_dev_memleak,7033
|
||||
|
||||
msgtype,dualopend_dev_memleak_reply,7133
|
||||
msgdata,dualopend_dev_memleak_reply,leak,bool,
|
||||
|
||||
# dualopend -> master: this was a dry run, here's some info about this open
|
||||
msgtype,dualopend_dry_run,7026
|
||||
msgdata,dualopend_dry_run,channel_id,channel_id,
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 14.
|
|
@ -151,6 +151,9 @@ bool fromwire_channeld_sending_commitsig(const tal_t *ctx UNNEEDED, const void *
|
|||
/* Generated stub for fromwire_connectd_peer_connected */
|
||||
bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct wireaddr **remote_addr UNNEEDED, bool *incoming UNNEEDED, u8 **features UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_connectd_peer_connected called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_dualopend_dev_memleak_reply */
|
||||
bool fromwire_dualopend_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_dualopend_dev_memleak_reply called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_hsmd_get_output_scriptpubkey_reply */
|
||||
bool fromwire_hsmd_get_output_scriptpubkey_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **script UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_hsmd_get_output_scriptpubkey_reply called!\n"); abort(); }
|
||||
|
@ -723,6 +726,9 @@ u8 *towire_connectd_peer_disconnected(const tal_t *ctx UNNEEDED, const struct no
|
|||
/* Generated stub for towire_connectd_peer_final_msg */
|
||||
u8 *towire_connectd_peer_final_msg(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, const u8 *msg UNNEEDED)
|
||||
{ fprintf(stderr, "towire_connectd_peer_final_msg called!\n"); abort(); }
|
||||
/* Generated stub for towire_dualopend_dev_memleak */
|
||||
u8 *towire_dualopend_dev_memleak(const tal_t *ctx UNNEEDED)
|
||||
{ fprintf(stderr, "towire_dualopend_dev_memleak called!\n"); abort(); }
|
||||
/* Generated stub for towire_errorfmt */
|
||||
u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
|
||||
const struct channel_id *channel UNNEEDED,
|
||||
|
|
Loading…
Add table
Reference in a new issue