diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 6c5baa285b13..d60bc929c257 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -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) diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c index 826f75464171..819542a73f55 100644 --- a/tools/perf/util/trace-event.c +++ b/tools/perf/util/trace-event.c @@ -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. */ diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 720121c74f1d..1c342fce36bb 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -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*