Skip to content

Commit

Permalink
lightningd: fix memleak where we didn't free plugin_hook_request when…
Browse files Browse the repository at this point in the history
… it was finished.

Covered up by notleak() :(

Changelog-Fixed: lightingd: slow memory leak when using plugin hooks fixed (introduced in v23.11)
Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Apr 2, 2024
1 parent 9a4be1a commit 5b76c2f
Showing 1 changed file with 16 additions and 13 deletions.
29 changes: 16 additions & 13 deletions lightningd/plugin_hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,19 @@ bool plugin_hook_continue(void *unused, const char *buffer, const jsmntok_t *tok
return resrestok && json_tok_streq(buffer, resrestok, "continue");
}

static void cleanup_ph_req(struct plugin_hook_request *ph_req)
{
/* We need to remove the destructors from the remaining
* call-chain, otherwise they'd still be called when the
* plugin dies or we shut down. */
for (size_t i=0; i<tal_count(ph_req->hooks); i++) {
tal_del_destructor2(ph_req->hooks[i],
destroy_hook_in_ph_req, ph_req);
}

tal_free(ph_req);
}

/**
* Callback to be passed to the jsonrpc_request.
*
Expand Down Expand Up @@ -159,26 +172,15 @@ static void plugin_hook_callback(const char *buffer, const jsmntok_t *toks,
if (!ph_req->hook->deserialize_cb(ph_req->cb_arg,
buffer, resulttok)) {
tal_free(ph_req->cb_arg);
goto cleanup;
cleanup_ph_req(ph_req);
return;
}
} else {
log_debug(ph_req->ld->log, "Plugin died from %s hook call",
ph_req->hook->name);
}

plugin_hook_call_next(ph_req);
return;

cleanup:
/* We need to remove the destructors from the remaining
* call-chain, otherwise they'd still be called when the
* plugin dies or we shut down. */
for (size_t i=0; i<tal_count(ph_req->hooks); i++) {
tal_del_destructor2(ph_req->hooks[i],
destroy_hook_in_ph_req, ph_req);
}

tal_free(ph_req);
}

static void plugin_hook_call_next(struct plugin_hook_request *ph_req)
Expand All @@ -192,6 +194,7 @@ static void plugin_hook_call_next(struct plugin_hook_request *ph_req)
ph_req->hook_index++;
if (ph_req->hook_index >= tal_count(ph_req->hooks)) {
ph_req->hook->final_cb(ph_req->cb_arg);
cleanup_ph_req(ph_req);
return;
}
} while (ph_req->hooks[ph_req->hook_index] == NULL);
Expand Down

0 comments on commit 5b76c2f

Please sign in to comment.