Messages in this thread | | | From | Namhyung Kim <> | Date | Tue, 2 Mar 2021 13:47:55 +0900 | Subject | Re: [PATCH] perf diff: Don't crash on freeing errno-session |
| |
Hello,
On Tue, Mar 2, 2021 at 11:35 AM Dmitry Safonov <dima@arista.com> wrote: > > __cmd_diff() sets result of perf_session__new() to d->session. > In case of failure, it's errno and perf-diff may crash with: > failed to open perf.data: Permission denied > Failed to open perf.data > Segmentation fault (core dumped) > > From the coredump: > 0 0x00005569a62b5955 in auxtrace__free (session=0xffffffffffffffff) > at util/auxtrace.c:2681 > 1 0x00005569a626b37d in perf_session__delete (session=0xffffffffffffffff) > at util/session.c:295 > 2 perf_session__delete (session=0xffffffffffffffff) at util/session.c:291 > 3 0x00005569a618008a in __cmd_diff () at builtin-diff.c:1239 > 4 cmd_diff (argc=<optimized out>, argv=<optimized out>) at builtin-diff.c:2011 > [..] > > Funny enough, it won't always crash. For me it crashes only if failed > file is second in cmd-line: the reason is that cmd_diff() check files for > branch-stacks [in check_file_brstack()] and if the first file doesn't > have brstacks, it doesn't proceed to try open other files from cmd-line. > > Check d->session before calling perf_session__delete(). > > Another solution would be assigning to temporary variable, checking it, > but I find it easier to follow with IS_ERR() check in the same function. > After some time it's still obvious why the check is needed, and with > temp variable it's possible to make the same mistake. > > Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> > Cc: Arnaldo Carvalho de Melo <acme@kernel.org> > Cc: Ingo Molnar <mingo@redhat.com> > Cc: Jiri Olsa <jolsa@redhat.com> > Cc: Mark Rutland <mark.rutland@arm.com> > Cc: Namhyung Kim <namhyung@kernel.org> > Cc: Peter Zijlstra <peterz@infradead.org> > Signed-off-by: Dmitry Safonov <dima@arista.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Thanks, Namhyung
> --- > tools/perf/builtin-diff.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c > index cefc71506409..b0c57e55052d 100644 > --- a/tools/perf/builtin-diff.c > +++ b/tools/perf/builtin-diff.c > @@ -1236,7 +1236,8 @@ static int __cmd_diff(void) > > out_delete: > data__for_each_file(i, d) { > - perf_session__delete(d->session); > + if (!IS_ERR(d->session)) > + perf_session__delete(d->session); > data__free(d); > } > > -- > 2.30.1 >
| |