gossipd: wire up memleak detection.

For simplicity we dump leaks to logs, and just return a bool to master.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2018-11-22 09:11:49 +10:30
parent 78771ca371
commit ab735dcbe6
11 changed files with 135 additions and 8 deletions

View File

@@ -5,12 +5,15 @@
#include <ccan/tal/str/str.h>
#include <common/daemon.h>
#include <common/memleak.h>
#include <common/timeout.h>
#include <gossipd/gen_gossip_wire.h>
#include <lightningd/chaintopology.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/jsonrpc_errors.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/param.h>
#include <lightningd/subd.h>
#include <stdio.h>
static void json_add_ptr(struct json_stream *response, const char *name,
@@ -111,7 +114,8 @@ static void json_add_backtrace(struct json_stream *response,
static void scan_mem(struct command *cmd,
struct json_stream *response,
struct lightningd *ld)
struct lightningd *ld,
const struct subd *leaking_subd)
{
struct htable *memtable;
const tal_t *i;
@@ -147,14 +151,64 @@ static void scan_mem(struct command *cmd,
json_array_end(response);
json_object_end(response);
}
if (leaking_subd) {
json_object_start(response, NULL);
json_add_string(response, "subdaemon", leaking_subd->name);
json_object_end(response);
}
json_array_end(response);
}
struct leak_info {
struct command *cmd;
struct subd *leaker;
};
static void report_leak_info2(struct leak_info *leak_info)
{
struct json_stream *response = json_stream_success(leak_info->cmd);
json_object_start(response, NULL);
scan_mem(leak_info->cmd, response, leak_info->cmd->ld, leak_info->leaker);
json_object_end(response);
command_success(leak_info->cmd, response);
}
static void report_leak_info(struct command *cmd, struct subd *leaker)
{
struct leak_info *leak_info = tal(cmd, struct leak_info);
leak_info->cmd = cmd;
leak_info->leaker = leaker;
/* Leak detection in a reply handler thinks we're leaking conn. */
notleak(new_reltimer(&leak_info->cmd->ld->timers, leak_info->cmd,
time_from_sec(0),
report_leak_info2, leak_info));
}
static void gossip_dev_memleak_done(struct subd *gossipd,
const u8 *reply,
const int *fds UNUSED,
struct command *cmd)
{
bool found_leak;
if (!fromwire_gossip_dev_memleak_reply(reply, &found_leak)) {
command_fail(cmd, LIGHTNINGD, "Bad gossip_dev_memleak");
return;
}
report_leak_info(cmd, found_leak ? gossipd : NULL);
}
static void json_memleak(struct command *cmd,
const char *buffer UNNEEDED,
const jsmntok_t *params UNNEEDED)
{
struct json_stream *response;
struct lightningd *ld = cmd->ld;
if (!param(cmd, buffer, params, NULL))
return;
@@ -165,12 +219,9 @@ static void json_memleak(struct command *cmd,
return;
}
response = json_stream_success(cmd);
json_object_start(response, NULL);
scan_mem(cmd, response, cmd->ld);
json_object_end(response);
command_success(cmd, response);
subd_req(ld->gossip, ld->gossip, take(towire_gossip_dev_memleak(NULL)),
-1, 0, gossip_dev_memleak_done, cmd);
command_still_pending(cmd);
}
static const struct json_command dev_memleak_command = {