mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
perf trace-event: Free the global trace_event when a command ends
The tep handle behind trace_event__tp_format() is a process wide cache of the running kernel's tracepoint formats and nothing ever released it, as the comment above it had noted since the code was added. Add trace_event__exit() and call it from run_builtin() next to the existing perf_config__exit(). By then the builtin has returned, so the tep_event pointers it handed out, such as the ones cached in evsel->tp_format, are no longer reachable. Note that this does not silence every libtraceevent report under leak sanitizer. Parsing a print fmt drops a token inside the library itself, and as those allocations are not linked into the handle, freeing the handle cannot reclaim them. Assisted-by: Antigravity:gemini-3.1-pro Signed-off-by: Ian Rogers <irogers@google.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
d9eba1d5b5
commit
5a3d7afdfb
|
|
@ -32,6 +32,9 @@
|
|||
#include "util/build-id.h"
|
||||
#include "util/config.h"
|
||||
#include "util/debug.h"
|
||||
#ifdef HAVE_LIBTRACEEVENT
|
||||
#include "util/trace-event.h"
|
||||
#endif
|
||||
|
||||
const char perf_usage_string[] =
|
||||
"perf [--version] [--help] [OPTIONS] COMMAND [ARGS]";
|
||||
|
|
@ -379,6 +382,9 @@ static int run_builtin(const struct cmd_struct *p, int argc, const char **argv)
|
|||
|
||||
status = p->fn(argc, argv);
|
||||
perf_config__exit();
|
||||
#ifdef HAVE_LIBTRACEEVENT
|
||||
trace_event__exit();
|
||||
#endif
|
||||
exit_browser(status);
|
||||
|
||||
if (status)
|
||||
|
|
|
|||
|
|
@ -14,11 +14,9 @@
|
|||
#include "machine.h"
|
||||
|
||||
/*
|
||||
* global trace_event object used by trace_event__tp_format
|
||||
*
|
||||
* TODO There's no cleanup call for this. Add some sort of
|
||||
* __exit function support and call trace_event__cleanup
|
||||
* there.
|
||||
* Global trace_event object used by trace_event__tp_format. It caches the
|
||||
* tracepoint formats of the running kernel for the lifetime of the command
|
||||
* and is released by trace_event__exit.
|
||||
*/
|
||||
static struct trace_event tevent;
|
||||
static bool tevent_initialized;
|
||||
|
|
@ -75,6 +73,20 @@ void trace_event__cleanup(struct trace_event *t)
|
|||
t->plugin_list = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release the global trace_event. Called once the command is done, when the
|
||||
* tep_event pointers handed out by trace_event__tp_format are no longer in
|
||||
* use.
|
||||
*/
|
||||
void trace_event__exit(void)
|
||||
{
|
||||
if (!tevent_initialized)
|
||||
return;
|
||||
|
||||
trace_event__cleanup(&tevent);
|
||||
tevent_initialized = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns NULL and sets errno on failure.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ bool have_tracepoints(struct list_head *evlist);
|
|||
|
||||
int trace_event__init(struct trace_event *t);
|
||||
void trace_event__cleanup(struct trace_event *t);
|
||||
void trace_event__exit(void);
|
||||
int trace_event__register_resolver(struct machine *machine,
|
||||
tep_func_resolver_t *func);
|
||||
struct tep_event*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user