| From 69949416bf66e9aa01e2233e79341d2a0050af11 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 7 Dec 2023 14:09:11 +0000 |
| Subject: perf db-export: Fix missing reference count get in |
| call_path_from_sample() |
| |
| From: Ben Gainey <ben.gainey@arm.com> |
| |
| [ Upstream commit 1e24ce402c97dc3c0ab050593f1d5f6fde524564 ] |
| |
| The addr_location map and maps fields in the inner loop were missing |
| calls to map__get()/maps__get(). The subsequent addr_location__exit() |
| call in each loop puts the map/maps fields causing use-after-free |
| aborts. |
| |
| This issue reproduces on at least arm64 and x86_64 with something |
| simple like `perf record -g ls` followed by `perf script -s script.py` |
| with the following script: |
| |
| perf_db_export_mode = True |
| perf_db_export_calls = False |
| perf_db_export_callchains = True |
| |
| def sample_table(*args): |
| print(f'sample_table({args})') |
| |
| def call_path_table(*args): |
| print(f'call_path_table({args}') |
| |
| Committer testing: |
| |
| This test, just introduced by Ian Rogers, now passes, not segfaulting |
| anymore: |
| |
| # perf test "perf script tests" |
| 95: perf script tests : Ok |
| # |
| |
| Fixes: 0dd5041c9a0eaf8c ("perf addr_location: Add init/exit/copy functions") |
| Signed-off-by: Ben Gainey <ben.gainey@arm.com> |
| Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
| Tested-by: Ian Rogers <irogers@google.com> |
| Cc: Adrian Hunter <adrian.hunter@intel.com> |
| Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> |
| Cc: Ingo Molnar <mingo@redhat.com> |
| Cc: Jiri Olsa <jolsa@kernel.org> |
| Cc: Mark Rutland <mark.rutland@arm.com> |
| Cc: Namhyung Kim <namhyung@kernel.org> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Link: https://lore.kernel.org/r/20231207140911.3240408-1-ben.gainey@arm.com |
| Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| tools/perf/util/db-export.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c |
| index b9fb71ab7a73..106429155c2e 100644 |
| --- a/tools/perf/util/db-export.c |
| +++ b/tools/perf/util/db-export.c |
| @@ -253,8 +253,8 @@ static struct call_path *call_path_from_sample(struct db_export *dbe, |
| */ |
| addr_location__init(&al); |
| al.sym = node->ms.sym; |
| - al.map = node->ms.map; |
| - al.maps = thread__maps(thread); |
| + al.map = map__get(node->ms.map); |
| + al.maps = maps__get(thread__maps(thread)); |
| al.addr = node->ip; |
| |
| if (al.map && !al.sym) |
| -- |
| 2.43.0 |
| |