mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 21:35:11 +01:00
openingd: wire up dev_memleak.
This is a bit different from the other cases: we need to iterate through the peers and ask all the ones in openingd. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
6da379631f
commit
a42c8bfb38
@ -70,6 +70,7 @@ LIGHTNINGD_SRC := \
|
||||
lightningd/lightningd.c \
|
||||
lightningd/log.c \
|
||||
lightningd/log_status.c \
|
||||
lightningd/memdump.c \
|
||||
lightningd/onchain_control.c \
|
||||
lightningd/opening_control.c \
|
||||
lightningd/options.c \
|
||||
@ -83,11 +84,7 @@ LIGHTNINGD_SRC := \
|
||||
lightningd/subd.c \
|
||||
lightningd/watch.c
|
||||
|
||||
# Source files without corresponding headers
|
||||
LIGHTNINGD_SRC_NOHDR := \
|
||||
lightningd/memdump.c
|
||||
|
||||
LIGHTNINGD_OBJS := $(LIGHTNINGD_SRC:.c=.o) $(LIGHTNINGD_SRC_NOHDR:.c=.o)
|
||||
LIGHTNINGD_OBJS := $(LIGHTNINGD_SRC:.c=.o)
|
||||
|
||||
# Make sure these depend on everything.
|
||||
ALL_OBJS += $(LIGHTNINGD_OBJS)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Only possible if we're in developer mode. */
|
||||
#include "config.h"
|
||||
#include "memdump.h"
|
||||
#if DEVELOPER
|
||||
#include <backtrace.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
@ -15,6 +15,7 @@
|
||||
#include <lightningd/jsonrpc_errors.h>
|
||||
#include <lightningd/lightningd.h>
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/opening_control.h>
|
||||
#include <lightningd/param.h>
|
||||
#include <lightningd/subd.h>
|
||||
#include <stdio.h>
|
||||
@ -254,13 +255,26 @@ static void hsm_dev_memleak_done(struct subd *hsmd,
|
||||
-1, 0, connect_dev_memleak_done, cmd);
|
||||
}
|
||||
|
||||
void opening_memleak_done(struct command *cmd, struct subd *leaker)
|
||||
{
|
||||
if (leaker)
|
||||
report_leak_info(cmd, leaker);
|
||||
else {
|
||||
/* No leak there, try hsmd (we talk to hsm sync) */
|
||||
u8 *msg = towire_hsm_dev_memleak(NULL);
|
||||
if (!wire_sync_write(cmd->ld->hsm_fd, take(msg)))
|
||||
fatal("Could not write to HSM: %s", strerror(errno));
|
||||
|
||||
hsm_dev_memleak_done(cmd->ld->hsm,
|
||||
wire_sync_read(tmpctx, cmd->ld->hsm_fd),
|
||||
cmd);
|
||||
}
|
||||
}
|
||||
|
||||
static void json_memleak(struct command *cmd,
|
||||
const char *buffer UNNEEDED,
|
||||
const jsmntok_t *params UNNEEDED)
|
||||
{
|
||||
struct lightningd *ld = cmd->ld;
|
||||
u8 *msg;
|
||||
|
||||
if (!param(cmd, buffer, params, NULL))
|
||||
return;
|
||||
|
||||
@ -274,12 +288,8 @@ static void json_memleak(struct command *cmd,
|
||||
* immediately. */
|
||||
command_still_pending(cmd);
|
||||
|
||||
/* We talk to hsm sync. */
|
||||
msg = towire_hsm_dev_memleak(NULL);
|
||||
if (!wire_sync_write(ld->hsm_fd, take(msg)))
|
||||
fatal("Could not write to HSM: %s", strerror(errno));
|
||||
|
||||
hsm_dev_memleak_done(ld->hsm, wire_sync_read(tmpctx, ld->hsm_fd), cmd);
|
||||
/* This calls opening_memleak_done() async when all done. */
|
||||
opening_dev_memleak(cmd);
|
||||
}
|
||||
|
||||
static const struct json_command dev_memleak_command = {
|
||||
|
11
lightningd/memdump.h
Normal file
11
lightningd/memdump.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef LIGHTNING_LIGHTNINGD_MEMDUMP_H
|
||||
#define LIGHTNING_LIGHTNINGD_MEMDUMP_H
|
||||
#include "config.h"
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct command;
|
||||
struct subd;
|
||||
|
||||
void opening_memleak_done(struct command *cmd, struct subd *leaker);
|
||||
#endif /* LIGHTNING_LIGHTNINGD_MEMDUMP_H */
|
@ -675,6 +675,9 @@ static unsigned int openingd_msg(struct subd *openingd,
|
||||
case WIRE_OPENING_INIT:
|
||||
case WIRE_OPENING_FUNDER:
|
||||
case WIRE_OPENING_CAN_ACCEPT_CHANNEL:
|
||||
case WIRE_OPENING_DEV_MEMLEAK:
|
||||
/* Replies never get here */
|
||||
case WIRE_OPENING_DEV_MEMLEAK_REPLY:
|
||||
break;
|
||||
}
|
||||
log_broken(openingd->log, "Unexpected msg %s: %s",
|
||||
@ -855,3 +858,58 @@ static const struct json_command fund_channel_command = {
|
||||
"Fund channel with {id} using {satoshi} (or 'all') satoshis, at optional {feerate}"
|
||||
};
|
||||
AUTODATA(json_command, &fund_channel_command);
|
||||
|
||||
#if DEVELOPER
|
||||
/* Indented to avoid include ordering check */
|
||||
#include <lightningd/memdump.h>
|
||||
|
||||
/* Mutual recursion */
|
||||
static void opening_memleak_req_next(struct command *cmd, struct peer *prev);
|
||||
static void opening_memleak_req_done(struct subd *openingd,
|
||||
const u8 *msg, const int *fds UNUSED,
|
||||
struct command *cmd)
|
||||
{
|
||||
bool found_leak;
|
||||
struct uncommitted_channel *uc = openingd->channel;
|
||||
|
||||
if (!fromwire_opening_dev_memleak_reply(msg, &found_leak)) {
|
||||
command_fail(cmd, LIGHTNINGD, "Bad opening_dev_memleak");
|
||||
return;
|
||||
}
|
||||
|
||||
if (found_leak) {
|
||||
opening_memleak_done(cmd, openingd);
|
||||
return;
|
||||
}
|
||||
opening_memleak_req_next(cmd, uc->peer);
|
||||
}
|
||||
|
||||
static void opening_memleak_req_next(struct command *cmd, struct peer *prev)
|
||||
{
|
||||
struct peer *p;
|
||||
|
||||
list_for_each(&cmd->ld->peers, p, list) {
|
||||
if (!p->uncommitted_channel)
|
||||
continue;
|
||||
if (p == prev) {
|
||||
prev = NULL;
|
||||
continue;
|
||||
}
|
||||
if (prev != NULL)
|
||||
continue;
|
||||
|
||||
/* FIXME: If openingd dies, we'll get stuck here! */
|
||||
subd_req(p,
|
||||
p->uncommitted_channel->openingd,
|
||||
take(towire_opening_dev_memleak(NULL)),
|
||||
-1, 0, opening_memleak_req_done, cmd);
|
||||
return;
|
||||
}
|
||||
opening_memleak_done(cmd, NULL);
|
||||
}
|
||||
|
||||
void opening_dev_memleak(struct command *cmd)
|
||||
{
|
||||
opening_memleak_req_next(cmd, NULL);
|
||||
}
|
||||
#endif /* DEVELOPER */
|
||||
|
@ -22,4 +22,10 @@ void opening_peer_no_active_channels(struct peer *peer);
|
||||
void kill_uncommitted_channel(struct uncommitted_channel *uc,
|
||||
const char *why);
|
||||
|
||||
#if DEVELOPER
|
||||
struct command;
|
||||
/* Calls report_leak_info() async. */
|
||||
void opening_dev_memleak(struct command *cmd);
|
||||
#endif
|
||||
|
||||
#endif /* LIGHTNING_LIGHTNINGD_OPENING_CONTROL_H */
|
||||
|
@ -85,3 +85,9 @@ opening_fundee,,feerate_per_kw,u32
|
||||
opening_fundee,,msglen,u16
|
||||
opening_fundee,,funding_signed_msg,msglen*u8
|
||||
opening_fundee,,our_channel_reserve_satoshis,u64
|
||||
|
||||
# master -> openingd: do you have a memleak?
|
||||
opening_dev_memleak,6033
|
||||
|
||||
opening_dev_memleak_reply,6133
|
||||
opening_dev_memleak_reply,,leak,bool
|
||||
|
|
@ -13,6 +13,7 @@
|
||||
#include <common/gen_peer_status_wire.h>
|
||||
#include <common/initial_channel.h>
|
||||
#include <common/key_derive.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/peer_billboard.h>
|
||||
#include <common/peer_failed.h>
|
||||
#include <common/pseudorand.h>
|
||||
@ -1043,6 +1044,24 @@ static void fail_if_all_error(const u8 *inner)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#if DEVELOPER
|
||||
static void handle_dev_memleak(struct state *state, const u8 *msg)
|
||||
{
|
||||
struct htable *memtable;
|
||||
bool found_leak;
|
||||
|
||||
memtable = memleak_enter_allocations(tmpctx, msg, msg);
|
||||
|
||||
/* Now delete state and things it has pointers to. */
|
||||
memleak_remove_referenced(memtable, state);
|
||||
|
||||
found_leak = dump_memleak(memtable);
|
||||
wire_sync_write(REQ_FD,
|
||||
take(towire_opening_dev_memleak_reply(NULL,
|
||||
found_leak)));
|
||||
}
|
||||
#endif /* DEVELOPER */
|
||||
|
||||
static u8 *handle_master_in(struct state *state)
|
||||
{
|
||||
u8 *msg = wire_sync_read(tmpctx, REQ_FD);
|
||||
@ -1076,6 +1095,12 @@ static u8 *handle_master_in(struct state *state)
|
||||
state->can_accept_channel = true;
|
||||
return NULL;
|
||||
|
||||
case WIRE_OPENING_DEV_MEMLEAK:
|
||||
#if DEVELOPER
|
||||
handle_dev_memleak(state, msg);
|
||||
return NULL;
|
||||
#endif
|
||||
case WIRE_OPENING_DEV_MEMLEAK_REPLY:
|
||||
case WIRE_OPENING_INIT:
|
||||
case WIRE_OPENING_FUNDER_REPLY:
|
||||
case WIRE_OPENING_FUNDEE:
|
||||
|
Loading…
Reference in New Issue
Block a user