]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
perf stat: Fix segfault for event group in repeat mode
authorJiri Olsa <jolsa@redhat.com>
Mon, 15 Jul 2019 14:21:21 +0000 (16:21 +0200)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 23 Jul 2019 12:00:05 +0000 (09:00 -0300)
Numfor Mbiziwo-Tiapo reported segfault on stat of event group in repeat
mode:

  # perf stat -e '{cycles,instructions}' -r 10 ls

It's caused by memory corruption due to not cleaned evsel's id array and
index, which needs to be rebuilt in every stat iteration. Currently the
ids index grows, while the array (which is also not freed) has the same
size.

Fixing this by releasing id array and zeroing ids index in
perf_evsel__close function.

We also need to keep the evsel_list alive for stat record (which is
disabled in repeat mode).

Reported-by: Numfor Mbiziwo-Tiapo <nums@google.com>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Mark Drayton <mbd@fb.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Song Liu <songliubraving@fb.com>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/20190715142121.GC6032@krava
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-stat.c
tools/perf/util/evsel.c

index b55a534b4de0be8ec98a8624526d4ced72971ae2..352cf39d7c2feb569914bacde2e66b01b5d51e42 100644 (file)
@@ -607,7 +607,13 @@ try_again:
         * group leaders.
         */
        read_counters(&(struct timespec) { .tv_nsec = t1-t0 });
-       perf_evlist__close(evsel_list);
+
+       /*
+        * We need to keep evsel_list alive, because it's processed
+        * later the evsel_list will be closed after.
+        */
+       if (!STAT_RECORD)
+               perf_evlist__close(evsel_list);
 
        return WEXITSTATUS(status);
 }
@@ -1997,6 +2003,7 @@ int cmd_stat(int argc, const char **argv)
                        perf_session__write_header(perf_stat.session, evsel_list, fd, true);
                }
 
+               perf_evlist__close(evsel_list);
                perf_session__delete(perf_stat.session);
        }
 
index ebb46da4dfe5abc6056f9054db2bbeba63cf1c6a..52459dd5ad0cfc8fbfe7ee7966b09cfb39ec7ced 100644 (file)
@@ -1291,6 +1291,7 @@ static void perf_evsel__free_id(struct perf_evsel *evsel)
        xyarray__delete(evsel->sample_id);
        evsel->sample_id = NULL;
        zfree(&evsel->id);
+       evsel->ids = 0;
 }
 
 static void perf_evsel__free_config_terms(struct perf_evsel *evsel)
@@ -2077,6 +2078,7 @@ void perf_evsel__close(struct perf_evsel *evsel)
 
        perf_evsel__close_fd(evsel);
        perf_evsel__free_fd(evsel);
+       perf_evsel__free_id(evsel);
 }
 
 int perf_evsel__open_per_cpu(struct perf_evsel *evsel,