Skip to content

Commit

Permalink
perf hist: Fix reference counting of branch_info
Browse files Browse the repository at this point in the history
iter_finish_branch_entry() doesn't put the branch_info from/to map
elements creating memory leaks. This can be seen with:

```
$ perf record -e cycles -b perf test -w noploop
$ perf report -D
...
Direct leak of 984344 byte(s) in 123043 object(s) allocated from:
    #0 0x7fb2654f3bd7 in malloc libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x564d3400d10b in map__get util/map.h:186
    #2 0x564d3400d10b in ip__resolve_ams util/machine.c:1981
    #3 0x564d34014d81 in sample__resolve_bstack util/machine.c:2151
    #4 0x564d34094790 in iter_prepare_branch_entry util/hist.c:898
    #5 0x564d34098fa4 in hist_entry_iter__add util/hist.c:1238
    torvalds#6 0x564d33d1f0c7 in process_sample_event tools/perf/builtin-report.c:334
    torvalds#7 0x564d34031eb7 in perf_session__deliver_event util/session.c:1655
    torvalds#8 0x564d3403ba52 in do_flush util/ordered-events.c:245
    torvalds#9 0x564d3403ba52 in __ordered_events__flush util/ordered-events.c:324
    torvalds#10 0x564d3402d32e in perf_session__process_user_event util/session.c:1708
    torvalds#11 0x564d34032480 in perf_session__process_event util/session.c:1877
    torvalds#12 0x564d340336ad in reader__read_event util/session.c:2399
    torvalds#13 0x564d34033fdc in reader__process_events util/session.c:2448
    torvalds#14 0x564d34033fdc in __perf_session__process_events util/session.c:2495
    torvalds#15 0x564d34033fdc in perf_session__process_events util/session.c:2661
    torvalds#16 0x564d33d27113 in __cmd_report tools/perf/builtin-report.c:1065
    torvalds#17 0x564d33d27113 in cmd_report tools/perf/builtin-report.c:1805
    torvalds#18 0x564d33e0ccb7 in run_builtin tools/perf/perf.c:350
    torvalds#19 0x564d33e0d45e in handle_internal_command tools/perf/perf.c:403
    torvalds#20 0x564d33cdd827 in run_argv tools/perf/perf.c:447
    torvalds#21 0x564d33cdd827 in main tools/perf/perf.c:561
...
```

Clearing up the map_symbols properly creates maps reference count
issues so resolve those. Resolving this issue doesn't improve peak
heap consumption for the test above.

Committer testing:

  $ sudo dnf install libasan
  $ make -k CORESIGHT=1 EXTRA_CFLAGS="-fsanitize=address" CC=clang O=/tmp/build/$(basename $PWD)/ -C tools/perf install-bin

Reviewed-by: Kan Liang <[email protected]>
Signed-off-by: Ian Rogers <[email protected]>
Tested-by: Arnaldo Carvalho de Melo <[email protected]>
Cc: Adrian Hunter <[email protected]>
Cc: Alexander Shishkin <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Sun Haiyong <[email protected]>
Cc: Yanteng Si <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
  • Loading branch information
captain5050 authored and acmel committed Aug 8, 2024
1 parent 37ce8a5 commit b2f70c9
Showing 1 changed file with 14 additions and 4 deletions.
18 changes: 14 additions & 4 deletions tools/perf/util/hist.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,9 @@ static int hist_entry__init(struct hist_entry *he,
memcpy(he->branch_info, template->branch_info,
sizeof(*he->branch_info));

he->branch_info->from.ms.maps = maps__get(he->branch_info->from.ms.maps);
he->branch_info->from.ms.map = map__get(he->branch_info->from.ms.map);
he->branch_info->to.ms.maps = maps__get(he->branch_info->to.ms.maps);
he->branch_info->to.ms.map = map__get(he->branch_info->to.ms.map);
}

Expand Down Expand Up @@ -970,10 +972,21 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a
return err;
}

static void branch_info__exit(struct branch_info *bi)
{
map_symbol__exit(&bi->from.ms);
map_symbol__exit(&bi->to.ms);
zfree_srcline(&bi->srcline_from);
zfree_srcline(&bi->srcline_to);
}

static int
iter_finish_branch_entry(struct hist_entry_iter *iter,
struct addr_location *al __maybe_unused)
{
for (int i = 0; i < iter->total; i++)
branch_info__exit(&iter->bi[i]);

zfree(&iter->bi);
iter->he = NULL;

Expand Down Expand Up @@ -1319,10 +1332,7 @@ void hist_entry__delete(struct hist_entry *he)
map_symbol__exit(&he->ms);

if (he->branch_info) {
map_symbol__exit(&he->branch_info->from.ms);
map_symbol__exit(&he->branch_info->to.ms);
zfree_srcline(&he->branch_info->srcline_from);
zfree_srcline(&he->branch_info->srcline_to);
branch_info__exit(he->branch_info);
zfree(&he->branch_info);
}

Expand Down

0 comments on commit b2f70c9

Please sign in to comment.