summaryrefslogtreecommitdiff
path: root/tools/perf/builtin-mem.c
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2025-03-07 17:28:53 -0800
committerNamhyung Kim <namhyung@kernel.org>2025-03-10 14:26:45 -0700
commitdb5af2e4a02c9b3744453a84657ed1fc54a1ef82 (patch)
treef0f602ca90afd91a8e5bb85a613bf1776548c08b /tools/perf/builtin-mem.c
parent6dad43bb114983cab4aa74ae6e13318100447c80 (diff)
perf mem: Don't leak mem event names
When preparing the mem events for the argv copies are intentionally made. These copies are leaked and cause runs of perf using address sanitizer to fail. Rather than leak the memory allocate a chunk of memory for the mem event names upfront and build the strings in this - the storage is sized larger than the previous buffer size. The caller is then responsible for clearing up this memory. As part of this change, remove the mem_loads_name and mem_stores_name global buffers then change the perf_pmu__mem_events_name to write to an out argument buffer. Signed-off-by: Ian Rogers <irogers@google.com> Tested-by: Thomas Falcon <thomas.falcon@intel.com> Reviewed-by: Leo Yan <leo.yan@arm.com> Link: https://lore.kernel.org/r/20250308012853.1384762-1-irogers@google.com Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Diffstat (limited to 'tools/perf/builtin-mem.c')
-rw-r--r--tools/perf/builtin-mem.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index 99d5e1491a288..5ec83cd85650d 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -74,6 +74,7 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem,
int rec_argc, i = 0, j;
int start, end;
const char **rec_argv;
+ char *event_name_storage = NULL;
int ret;
struct perf_mem_event *e;
struct perf_pmu *pmu;
@@ -140,7 +141,7 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem,
rec_argv[i++] = "--data-page-size";
start = i;
- ret = perf_mem_events__record_args(rec_argv, &i);
+ ret = perf_mem_events__record_args(rec_argv, &i, &event_name_storage);
if (ret)
goto out;
end = i;
@@ -170,6 +171,7 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem,
ret = cmd_record(i, rec_argv);
out:
+ free(event_name_storage);
free(rec_argv);
return ret;
}
@@ -521,6 +523,7 @@ int cmd_mem(int argc, const char **argv)
NULL,
NULL
};
+ int ret;
argc = parse_options_subcommand(argc, argv, mem_options, mem_subcommands,
mem_usage, PARSE_OPT_STOP_AT_NON_OPTION);
@@ -536,14 +539,15 @@ int cmd_mem(int argc, const char **argv)
}
if (strlen(argv[0]) > 2 && strstarts("record", argv[0]))
- return __cmd_record(argc, argv, &mem, record_options);
+ ret = __cmd_record(argc, argv, &mem, record_options);
else if (strlen(argv[0]) > 2 && strstarts("report", argv[0]))
- return __cmd_report(argc, argv, &mem, report_options);
+ ret = __cmd_report(argc, argv, &mem, report_options);
else
usage_with_options(mem_usage, mem_options);
/* free usage string allocated by parse_options_subcommand */
free((void *)mem_usage[0]);
+ free(sort_order_help);
- return 0;
+ return ret;
}