diff options
author | Ian Rogers <irogers@google.com> | 2025-03-07 17:28:53 -0800 |
---|---|---|
committer | Namhyung Kim <namhyung@kernel.org> | 2025-03-10 14:26:45 -0700 |
commit | db5af2e4a02c9b3744453a84657ed1fc54a1ef82 (patch) | |
tree | f0f602ca90afd91a8e5bb85a613bf1776548c08b /tools/perf/builtin-mem.c | |
parent | 6dad43bb114983cab4aa74ae6e13318100447c80 (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.c | 12 |
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; } |