Skip to content

Commit b194c9c

Browse files
captain5050acmel
authored andcommitted
perf evsel: Fix memory leaks relating to unit
unit may have a strdup pointer or be to a literal, consequently memory assocciated with it isn't freed. Change it so the unit is always strdup and so the memory can be safely freed. Fix related issue in perf_event__process_event_update() for name and own_cpus. Leaks were spotted by leak sanitizer. Signed-off-by: Ian Rogers <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Stephane Eranian <[email protected]> Link: http://lore.kernel.org/lkml/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent d9fc706 commit b194c9c

File tree

4 files changed

+22
-18
lines changed

4 files changed

+22
-18
lines changed

tools/perf/tests/event_update.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ static int test__event_update(struct test_suite *test __maybe_unused, int subtes
8888
struct evsel *evsel;
8989
struct event_name tmp;
9090
struct evlist *evlist = evlist__new_default();
91-
char *unit = strdup("KRAVA");
9291

9392
TEST_ASSERT_VAL("failed to get evlist", evlist);
9493

@@ -99,7 +98,8 @@ static int test__event_update(struct test_suite *test __maybe_unused, int subtes
9998

10099
perf_evlist__id_add(&evlist->core, &evsel->core, 0, 0, 123);
101100

102-
evsel->unit = unit;
101+
free((char *)evsel->unit);
102+
evsel->unit = strdup("KRAVA");
103103

104104
TEST_ASSERT_VAL("failed to synthesize attr update unit",
105105
!perf_event__synthesize_event_update_unit(NULL, evsel, process_event_unit));
@@ -119,7 +119,6 @@ static int test__event_update(struct test_suite *test __maybe_unused, int subtes
119119
TEST_ASSERT_VAL("failed to synthesize attr update cpus",
120120
!perf_event__synthesize_event_update_cpus(&tmp.tool, evsel, process_event_cpus));
121121

122-
free(unit);
123122
evlist__delete(evlist);
124123
return 0;
125124
}

tools/perf/util/evsel.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ void evsel__init(struct evsel *evsel,
241241
{
242242
perf_evsel__init(&evsel->core, attr, idx);
243243
evsel->tracking = !idx;
244-
evsel->unit = "";
244+
evsel->unit = strdup("");
245245
evsel->scale = 1.0;
246246
evsel->max_events = ULONG_MAX;
247247
evsel->evlist = NULL;
@@ -276,13 +276,8 @@ struct evsel *evsel__new_idx(struct perf_event_attr *attr, int idx)
276276
}
277277

278278
if (evsel__is_clock(evsel)) {
279-
/*
280-
* The evsel->unit points to static alias->unit
281-
* so it's ok to use static string in here.
282-
*/
283-
static const char *unit = "msec";
284-
285-
evsel->unit = unit;
279+
free((char *)evsel->unit);
280+
evsel->unit = strdup("msec");
286281
evsel->scale = 1e-6;
287282
}
288283

@@ -420,7 +415,11 @@ struct evsel *evsel__clone(struct evsel *orig)
420415

421416
evsel->max_events = orig->max_events;
422417
evsel->tool_event = orig->tool_event;
423-
evsel->unit = orig->unit;
418+
free((char *)evsel->unit);
419+
evsel->unit = strdup(orig->unit);
420+
if (evsel->unit == NULL)
421+
goto out_err;
422+
424423
evsel->scale = orig->scale;
425424
evsel->snapshot = orig->snapshot;
426425
evsel->per_pkg = orig->per_pkg;
@@ -1441,6 +1440,7 @@ void evsel__exit(struct evsel *evsel)
14411440
zfree(&evsel->group_name);
14421441
zfree(&evsel->name);
14431442
zfree(&evsel->pmu_name);
1443+
zfree(&evsel->unit);
14441444
zfree(&evsel->metric_id);
14451445
evsel__zero_per_pkg(evsel);
14461446
hashmap__free(evsel->per_pkg_mask);

tools/perf/util/header.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4257,9 +4257,11 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
42574257

42584258
switch (ev->type) {
42594259
case PERF_EVENT_UPDATE__UNIT:
4260+
free((char *)evsel->unit);
42604261
evsel->unit = strdup(ev->data);
42614262
break;
42624263
case PERF_EVENT_UPDATE__NAME:
4264+
free(evsel->name);
42634265
evsel->name = strdup(ev->data);
42644266
break;
42654267
case PERF_EVENT_UPDATE__SCALE:
@@ -4268,11 +4270,11 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
42684270
break;
42694271
case PERF_EVENT_UPDATE__CPUS:
42704272
ev_cpus = (struct perf_record_event_update_cpus *)ev->data;
4271-
42724273
map = cpu_map__new_data(&ev_cpus->cpus);
4273-
if (map)
4274+
if (map) {
4275+
perf_cpu_map__put(evsel->core.own_cpus);
42744276
evsel->core.own_cpus = map;
4275-
else
4277+
} else
42764278
pr_err("failed to get event_update cpus\n");
42774279
default:
42784280
break;

tools/perf/util/parse-events.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,10 @@ static int add_event_tool(struct list_head *list, int *idx,
402402
if (!evsel)
403403
return -ENOMEM;
404404
evsel->tool_event = tool_event;
405-
if (tool_event == PERF_TOOL_DURATION_TIME)
406-
evsel->unit = "ns";
405+
if (tool_event == PERF_TOOL_DURATION_TIME) {
406+
free((char *)evsel->unit);
407+
evsel->unit = strdup("ns");
408+
}
407409
return 0;
408410
}
409411

@@ -1630,7 +1632,8 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
16301632
if (parse_state->fake_pmu)
16311633
return 0;
16321634

1633-
evsel->unit = info.unit;
1635+
free((char *)evsel->unit);
1636+
evsel->unit = strdup(info.unit);
16341637
evsel->scale = info.scale;
16351638
evsel->per_pkg = info.per_pkg;
16361639
evsel->snapshot = info.snapshot;

0 commit comments

Comments
 (0)