mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
channeld: wire up dev_memleak.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -166,6 +166,12 @@ channel_feerates,,feerate,u32
|
|||||||
channel_feerates,,min_feerate,u32
|
channel_feerates,,min_feerate,u32
|
||||||
channel_feerates,,max_feerate,u32
|
channel_feerates,,max_feerate,u32
|
||||||
|
|
||||||
|
# master -> channeld: do you have a memleak?
|
||||||
|
channel_dev_memleak,1033
|
||||||
|
|
||||||
|
channel_dev_memleak_reply,1133
|
||||||
|
channel_dev_memleak_reply,,leak,bool
|
||||||
|
|
||||||
# Peer presented proof it was from the future.
|
# Peer presented proof it was from the future.
|
||||||
channel_fail_fallen_behind,1028
|
channel_fail_fallen_behind,1028
|
||||||
channel_fail_fallen_behind,,remote_per_commitment_point,struct pubkey
|
channel_fail_fallen_behind,,remote_per_commitment_point,struct pubkey
|
||||||
|
|||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include <common/dev_disconnect.h>
|
#include <common/dev_disconnect.h>
|
||||||
#include <common/htlc_tx.h>
|
#include <common/htlc_tx.h>
|
||||||
#include <common/key_derive.h>
|
#include <common/key_derive.h>
|
||||||
|
#include <common/memleak.h>
|
||||||
#include <common/msg_queue.h>
|
#include <common/msg_queue.h>
|
||||||
#include <common/peer_billboard.h>
|
#include <common/peer_billboard.h>
|
||||||
#include <common/peer_failed.h>
|
#include <common/peer_failed.h>
|
||||||
@@ -2470,7 +2471,24 @@ static void handle_dev_reenable_commit(struct peer *peer)
|
|||||||
wire_sync_write(MASTER_FD,
|
wire_sync_write(MASTER_FD,
|
||||||
take(towire_channel_dev_reenable_commit_reply(NULL)));
|
take(towire_channel_dev_reenable_commit_reply(NULL)));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
static void handle_dev_memleak(struct peer *peer, const u8 *msg)
|
||||||
|
{
|
||||||
|
struct htable *memtable;
|
||||||
|
bool found_leak;
|
||||||
|
|
||||||
|
memtable = memleak_enter_allocations(tmpctx, msg, msg);
|
||||||
|
|
||||||
|
/* Now delete peer and things it has pointers to. */
|
||||||
|
memleak_remove_referenced(memtable, peer);
|
||||||
|
memleak_remove_htable(memtable, &peer->channel->htlcs->raw);
|
||||||
|
|
||||||
|
found_leak = dump_memleak(memtable);
|
||||||
|
wire_sync_write(MASTER_FD,
|
||||||
|
take(towire_channel_dev_memleak_reply(NULL,
|
||||||
|
found_leak)));
|
||||||
|
}
|
||||||
|
#endif /* DEVELOPER */
|
||||||
|
|
||||||
static void req_in(struct peer *peer, const u8 *msg)
|
static void req_in(struct peer *peer, const u8 *msg)
|
||||||
{
|
{
|
||||||
@@ -2495,10 +2513,16 @@ static void req_in(struct peer *peer, const u8 *msg)
|
|||||||
case WIRE_CHANNEL_SEND_SHUTDOWN:
|
case WIRE_CHANNEL_SEND_SHUTDOWN:
|
||||||
handle_shutdown_cmd(peer, msg);
|
handle_shutdown_cmd(peer, msg);
|
||||||
return;
|
return;
|
||||||
case WIRE_CHANNEL_DEV_REENABLE_COMMIT:
|
|
||||||
#if DEVELOPER
|
#if DEVELOPER
|
||||||
|
case WIRE_CHANNEL_DEV_REENABLE_COMMIT:
|
||||||
handle_dev_reenable_commit(peer);
|
handle_dev_reenable_commit(peer);
|
||||||
return;
|
return;
|
||||||
|
case WIRE_CHANNEL_DEV_MEMLEAK:
|
||||||
|
handle_dev_memleak(peer, msg);
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
case WIRE_CHANNEL_DEV_REENABLE_COMMIT:
|
||||||
|
case WIRE_CHANNEL_DEV_MEMLEAK:
|
||||||
#endif /* DEVELOPER */
|
#endif /* DEVELOPER */
|
||||||
case WIRE_CHANNEL_INIT:
|
case WIRE_CHANNEL_INIT:
|
||||||
case WIRE_CHANNEL_OFFER_HTLC_REPLY:
|
case WIRE_CHANNEL_OFFER_HTLC_REPLY:
|
||||||
@@ -2513,6 +2537,7 @@ static void req_in(struct peer *peer, const u8 *msg)
|
|||||||
case WIRE_CHANNEL_SHUTDOWN_COMPLETE:
|
case WIRE_CHANNEL_SHUTDOWN_COMPLETE:
|
||||||
case WIRE_CHANNEL_DEV_REENABLE_COMMIT_REPLY:
|
case WIRE_CHANNEL_DEV_REENABLE_COMMIT_REPLY:
|
||||||
case WIRE_CHANNEL_FAIL_FALLEN_BEHIND:
|
case WIRE_CHANNEL_FAIL_FALLEN_BEHIND:
|
||||||
|
case WIRE_CHANNEL_DEV_MEMLEAK_REPLY:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
master_badmsg(-1, msg);
|
master_badmsg(-1, msg);
|
||||||
|
|||||||
@@ -232,9 +232,11 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds)
|
|||||||
case WIRE_CHANNEL_SEND_SHUTDOWN:
|
case WIRE_CHANNEL_SEND_SHUTDOWN:
|
||||||
case WIRE_CHANNEL_DEV_REENABLE_COMMIT:
|
case WIRE_CHANNEL_DEV_REENABLE_COMMIT:
|
||||||
case WIRE_CHANNEL_FEERATES:
|
case WIRE_CHANNEL_FEERATES:
|
||||||
|
case WIRE_CHANNEL_DEV_MEMLEAK:
|
||||||
/* Replies go to requests. */
|
/* Replies go to requests. */
|
||||||
case WIRE_CHANNEL_OFFER_HTLC_REPLY:
|
case WIRE_CHANNEL_OFFER_HTLC_REPLY:
|
||||||
case WIRE_CHANNEL_DEV_REENABLE_COMMIT_REPLY:
|
case WIRE_CHANNEL_DEV_REENABLE_COMMIT_REPLY:
|
||||||
|
case WIRE_CHANNEL_DEV_MEMLEAK_REPLY:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <lightningd/log.h>
|
#include <lightningd/log.h>
|
||||||
#include <lightningd/opening_control.h>
|
#include <lightningd/opening_control.h>
|
||||||
#include <lightningd/param.h>
|
#include <lightningd/param.h>
|
||||||
|
#include <lightningd/peer_control.h>
|
||||||
#include <lightningd/subd.h>
|
#include <lightningd/subd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <wire/wire_sync.h>
|
#include <wire/wire_sync.h>
|
||||||
@@ -255,7 +256,7 @@ static void hsm_dev_memleak_done(struct subd *hsmd,
|
|||||||
-1, 0, connect_dev_memleak_done, cmd);
|
-1, 0, connect_dev_memleak_done, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void opening_memleak_done(struct command *cmd, struct subd *leaker)
|
void peer_memleak_done(struct command *cmd, struct subd *leaker)
|
||||||
{
|
{
|
||||||
if (leaker)
|
if (leaker)
|
||||||
report_leak_info(cmd, leaker);
|
report_leak_info(cmd, leaker);
|
||||||
@@ -271,6 +272,16 @@ void opening_memleak_done(struct command *cmd, struct subd *leaker)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void opening_memleak_done(struct command *cmd, struct subd *leaker)
|
||||||
|
{
|
||||||
|
if (leaker)
|
||||||
|
report_leak_info(cmd, leaker);
|
||||||
|
else {
|
||||||
|
/* No leak there, try normal peers. */
|
||||||
|
peer_dev_memleak(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void json_memleak(struct command *cmd,
|
static void json_memleak(struct command *cmd,
|
||||||
const char *buffer UNNEEDED,
|
const char *buffer UNNEEDED,
|
||||||
const jsmntok_t *params UNNEEDED)
|
const jsmntok_t *params UNNEEDED)
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ struct command;
|
|||||||
struct subd;
|
struct subd;
|
||||||
|
|
||||||
void opening_memleak_done(struct command *cmd, struct subd *leaker);
|
void opening_memleak_done(struct command *cmd, struct subd *leaker);
|
||||||
|
void peer_memleak_done(struct command *cmd, struct subd *leaker);
|
||||||
#endif /* LIGHTNING_LIGHTNINGD_MEMDUMP_H */
|
#endif /* LIGHTNING_LIGHTNINGD_MEMDUMP_H */
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <lightningd/jsonrpc.h>
|
#include <lightningd/jsonrpc.h>
|
||||||
#include <lightningd/jsonrpc_errors.h>
|
#include <lightningd/jsonrpc_errors.h>
|
||||||
#include <lightningd/log.h>
|
#include <lightningd/log.h>
|
||||||
|
#include <lightningd/memdump.h>
|
||||||
#include <lightningd/onchain_control.h>
|
#include <lightningd/onchain_control.h>
|
||||||
#include <lightningd/opening_control.h>
|
#include <lightningd/opening_control.h>
|
||||||
#include <lightningd/options.h>
|
#include <lightningd/options.h>
|
||||||
@@ -1395,5 +1396,63 @@ static const struct json_command dev_forget_channel_command = {
|
|||||||
"Forget the channel with peer {id}. Checks if the channel is still active by checking its funding transaction. Check can be ignored by setting {force} to 'true'"
|
"Forget the channel with peer {id}. Checks if the channel is still active by checking its funding transaction. Check can be ignored by setting {force} to 'true'"
|
||||||
};
|
};
|
||||||
AUTODATA(json_command, &dev_forget_channel_command);
|
AUTODATA(json_command, &dev_forget_channel_command);
|
||||||
|
|
||||||
|
/* Mutual recursion */
|
||||||
|
static void peer_memleak_req_next(struct command *cmd, struct channel *prev);
|
||||||
|
static void channeld_memleak_req_done(struct subd *channeld,
|
||||||
|
const u8 *msg, const int *fds UNUSED,
|
||||||
|
struct command *cmd)
|
||||||
|
{
|
||||||
|
struct channel *c = channeld->channel;
|
||||||
|
bool found_leak;
|
||||||
|
|
||||||
|
if (!fromwire_channel_dev_memleak_reply(msg, &found_leak)) {
|
||||||
|
command_fail(cmd, LIGHTNINGD, "Bad channel_dev_memleak");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_leak) {
|
||||||
|
peer_memleak_done(cmd, channeld);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
peer_memleak_req_next(cmd, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void peer_memleak_req_next(struct command *cmd, struct channel *prev)
|
||||||
|
{
|
||||||
|
struct peer *p;
|
||||||
|
|
||||||
|
list_for_each(&cmd->ld->peers, p, list) {
|
||||||
|
struct channel *c;
|
||||||
|
|
||||||
|
list_for_each(&p->channels, c, list) {
|
||||||
|
if (c == prev) {
|
||||||
|
prev = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!c->owner)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (prev != NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* FIXME: handle onchaind here */
|
||||||
|
/* FIXME: handle closingd here */
|
||||||
|
if (streq(c->owner->name, "lightning_channeld")) {
|
||||||
|
subd_req(c, c->owner,
|
||||||
|
take(towire_channel_dev_memleak(NULL)),
|
||||||
|
-1, 0, channeld_memleak_req_done, cmd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
peer_memleak_done(cmd, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void peer_dev_memleak(struct command *cmd)
|
||||||
|
{
|
||||||
|
peer_memleak_req_next(cmd, NULL);
|
||||||
|
}
|
||||||
#endif /* DEVELOPER */
|
#endif /* DEVELOPER */
|
||||||
|
|
||||||
|
|||||||
@@ -91,4 +91,9 @@ void channel_watch_funding(struct lightningd *ld, struct channel *channel);
|
|||||||
|
|
||||||
/* Pull peers, channels and HTLCs from db, and wire them up. */
|
/* Pull peers, channels and HTLCs from db, and wire them up. */
|
||||||
void load_channels_from_wallet(struct lightningd *ld);
|
void load_channels_from_wallet(struct lightningd *ld);
|
||||||
|
|
||||||
|
#if DEVELOPER
|
||||||
|
void peer_dev_memleak(struct command *cmd);
|
||||||
|
#endif /* DEVELOPER */
|
||||||
|
|
||||||
#endif /* LIGHTNING_LIGHTNINGD_PEER_CONTROL_H */
|
#endif /* LIGHTNING_LIGHTNINGD_PEER_CONTROL_H */
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ void delay_then_reconnect(struct channel *channel UNNEEDED, u32 seconds_delay UN
|
|||||||
/* Generated stub for fatal */
|
/* Generated stub for fatal */
|
||||||
void fatal(const char *fmt UNNEEDED, ...)
|
void fatal(const char *fmt UNNEEDED, ...)
|
||||||
{ fprintf(stderr, "fatal called!\n"); abort(); }
|
{ fprintf(stderr, "fatal called!\n"); abort(); }
|
||||||
|
/* Generated stub for fromwire_channel_dev_memleak_reply */
|
||||||
|
bool fromwire_channel_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
|
||||||
|
{ fprintf(stderr, "fromwire_channel_dev_memleak_reply called!\n"); abort(); }
|
||||||
/* Generated stub for fromwire_connect_peer_connected */
|
/* Generated stub for fromwire_connect_peer_connected */
|
||||||
bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **globalfeatures UNNEEDED, u8 **localfeatures UNNEEDED)
|
bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **globalfeatures UNNEEDED, u8 **localfeatures UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_connect_peer_connected called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_connect_peer_connected called!\n"); abort(); }
|
||||||
@@ -303,6 +306,9 @@ void opening_peer_no_active_channels(struct peer *peer UNNEEDED)
|
|||||||
bool param(struct command *cmd UNNEEDED, const char *buffer UNNEEDED,
|
bool param(struct command *cmd UNNEEDED, const char *buffer UNNEEDED,
|
||||||
const jsmntok_t params[] UNNEEDED, ...)
|
const jsmntok_t params[] UNNEEDED, ...)
|
||||||
{ fprintf(stderr, "param called!\n"); abort(); }
|
{ fprintf(stderr, "param called!\n"); abort(); }
|
||||||
|
/* Generated stub for peer_memleak_done */
|
||||||
|
void peer_memleak_done(struct command *cmd UNNEEDED, struct subd *leaker UNNEEDED)
|
||||||
|
{ fprintf(stderr, "peer_memleak_done called!\n"); abort(); }
|
||||||
/* Generated stub for peer_start_channeld */
|
/* Generated stub for peer_start_channeld */
|
||||||
void peer_start_channeld(struct channel *channel UNNEEDED,
|
void peer_start_channeld(struct channel *channel UNNEEDED,
|
||||||
const struct crypto_state *cs UNNEEDED,
|
const struct crypto_state *cs UNNEEDED,
|
||||||
@@ -348,6 +354,9 @@ void subd_req_(const tal_t *ctx UNNEEDED,
|
|||||||
/* Generated stub for subd_send_msg */
|
/* Generated stub for subd_send_msg */
|
||||||
void subd_send_msg(struct subd *sd UNNEEDED, const u8 *msg_out UNNEEDED)
|
void subd_send_msg(struct subd *sd UNNEEDED, const u8 *msg_out UNNEEDED)
|
||||||
{ fprintf(stderr, "subd_send_msg called!\n"); abort(); }
|
{ fprintf(stderr, "subd_send_msg called!\n"); abort(); }
|
||||||
|
/* Generated stub for towire_channel_dev_memleak */
|
||||||
|
u8 *towire_channel_dev_memleak(const tal_t *ctx UNNEEDED)
|
||||||
|
{ fprintf(stderr, "towire_channel_dev_memleak called!\n"); abort(); }
|
||||||
/* Generated stub for towire_channel_dev_reenable_commit */
|
/* Generated stub for towire_channel_dev_reenable_commit */
|
||||||
u8 *towire_channel_dev_reenable_commit(const tal_t *ctx UNNEEDED)
|
u8 *towire_channel_dev_reenable_commit(const tal_t *ctx UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_channel_dev_reenable_commit called!\n"); abort(); }
|
{ fprintf(stderr, "towire_channel_dev_reenable_commit called!\n"); abort(); }
|
||||||
|
|||||||
@@ -70,6 +70,9 @@ void delay_then_reconnect(struct channel *channel UNNEEDED, u32 seconds_delay UN
|
|||||||
/* Generated stub for fatal */
|
/* Generated stub for fatal */
|
||||||
void fatal(const char *fmt UNNEEDED, ...)
|
void fatal(const char *fmt UNNEEDED, ...)
|
||||||
{ fprintf(stderr, "fatal called!\n"); abort(); }
|
{ fprintf(stderr, "fatal called!\n"); abort(); }
|
||||||
|
/* Generated stub for fromwire_channel_dev_memleak_reply */
|
||||||
|
bool fromwire_channel_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
|
||||||
|
{ fprintf(stderr, "fromwire_channel_dev_memleak_reply called!\n"); abort(); }
|
||||||
/* Generated stub for fromwire_channel_got_commitsig */
|
/* Generated stub for fromwire_channel_got_commitsig */
|
||||||
bool fromwire_channel_got_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, u32 *feerate UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED, secp256k1_ecdsa_signature **htlc_signature UNNEEDED, struct added_htlc **added UNNEEDED, struct secret **shared_secret UNNEEDED, struct fulfilled_htlc **fulfilled UNNEEDED, struct failed_htlc ***failed UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_tx **tx UNNEEDED)
|
bool fromwire_channel_got_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, u32 *feerate UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED, secp256k1_ecdsa_signature **htlc_signature UNNEEDED, struct added_htlc **added UNNEEDED, struct secret **shared_secret UNNEEDED, struct fulfilled_htlc **fulfilled UNNEEDED, struct failed_htlc ***failed UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_tx **tx UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_channel_got_commitsig called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_channel_got_commitsig called!\n"); abort(); }
|
||||||
@@ -353,6 +356,9 @@ void payment_store(struct lightningd *ld UNNEEDED, const struct sha256 *payment_
|
|||||||
void payment_succeeded(struct lightningd *ld UNNEEDED, struct htlc_out *hout UNNEEDED,
|
void payment_succeeded(struct lightningd *ld UNNEEDED, struct htlc_out *hout UNNEEDED,
|
||||||
const struct preimage *rval UNNEEDED)
|
const struct preimage *rval UNNEEDED)
|
||||||
{ fprintf(stderr, "payment_succeeded called!\n"); abort(); }
|
{ fprintf(stderr, "payment_succeeded called!\n"); abort(); }
|
||||||
|
/* Generated stub for peer_memleak_done */
|
||||||
|
void peer_memleak_done(struct command *cmd UNNEEDED, struct subd *leaker UNNEEDED)
|
||||||
|
{ fprintf(stderr, "peer_memleak_done called!\n"); abort(); }
|
||||||
/* Generated stub for peer_start_channeld */
|
/* Generated stub for peer_start_channeld */
|
||||||
void peer_start_channeld(struct channel *channel UNNEEDED,
|
void peer_start_channeld(struct channel *channel UNNEEDED,
|
||||||
const struct crypto_state *cs UNNEEDED,
|
const struct crypto_state *cs UNNEEDED,
|
||||||
@@ -401,6 +407,9 @@ void subd_req_(const tal_t *ctx UNNEEDED,
|
|||||||
/* Generated stub for subd_send_msg */
|
/* Generated stub for subd_send_msg */
|
||||||
void subd_send_msg(struct subd *sd UNNEEDED, const u8 *msg_out UNNEEDED)
|
void subd_send_msg(struct subd *sd UNNEEDED, const u8 *msg_out UNNEEDED)
|
||||||
{ fprintf(stderr, "subd_send_msg called!\n"); abort(); }
|
{ fprintf(stderr, "subd_send_msg called!\n"); abort(); }
|
||||||
|
/* Generated stub for towire_channel_dev_memleak */
|
||||||
|
u8 *towire_channel_dev_memleak(const tal_t *ctx UNNEEDED)
|
||||||
|
{ fprintf(stderr, "towire_channel_dev_memleak called!\n"); abort(); }
|
||||||
/* Generated stub for towire_channel_dev_reenable_commit */
|
/* Generated stub for towire_channel_dev_reenable_commit */
|
||||||
u8 *towire_channel_dev_reenable_commit(const tal_t *ctx UNNEEDED)
|
u8 *towire_channel_dev_reenable_commit(const tal_t *ctx UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_channel_dev_reenable_commit called!\n"); abort(); }
|
{ fprintf(stderr, "towire_channel_dev_reenable_commit called!\n"); abort(); }
|
||||||
|
|||||||
Reference in New Issue
Block a user