All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] perf diff: Don't crash on freeing errno-session
@ 2021-03-02  2:35 Dmitry Safonov
  2021-03-02  4:47 ` Namhyung Kim
  0 siblings, 1 reply; 3+ messages in thread
From: Dmitry Safonov @ 2021-03-02  2:35 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dmitry Safonov, Dmitry Safonov, Alexander Shishkin,
	Arnaldo Carvalho de Melo, Ingo Molnar, Jiri Olsa, Mark Rutland,
	Namhyung Kim, Peter Zijlstra

__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>
---
 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


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] perf diff: Don't crash on freeing errno-session
  2021-03-02  2:35 [PATCH] perf diff: Don't crash on freeing errno-session Dmitry Safonov
@ 2021-03-02  4:47 ` Namhyung Kim
  2021-03-02 12:31   ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 3+ messages in thread
From: Namhyung Kim @ 2021-03-02  4:47 UTC (permalink / raw)
  To: Dmitry Safonov
  Cc: linux-kernel, Dmitry Safonov, Alexander Shishkin,
	Arnaldo Carvalho de Melo, Ingo Molnar, Jiri Olsa, Mark Rutland,
	Peter Zijlstra

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
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] perf diff: Don't crash on freeing errno-session
  2021-03-02  4:47 ` Namhyung Kim
@ 2021-03-02 12:31   ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 3+ messages in thread
From: Arnaldo Carvalho de Melo @ 2021-03-02 12:31 UTC (permalink / raw)
  To: Dmitry Safonov, Namhyung Kim
  Cc: linux-kernel, Dmitry Safonov, Alexander Shishkin, Ingo Molnar,
	Jiri Olsa, Mark Rutland, Peter Zijlstra

Em Tue, Mar 02, 2021 at 01:47:55PM +0900, Namhyung Kim escreveu:
> 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, tested, added a complete set of steps for a problem to be
reproduced and applied.

- Arnaldo

    Committer testing:
    
      $ perf record sleep 1
      [ perf record: Woken up 1 times to write data ]
      [ perf record: Captured and wrote 0.001 MB perf.data (8 samples) ]
      $ perf diff
      failed to open perf.data.old: No such file or directory
      Failed to open perf.data.old
      $ perf record sleep 1
      [ perf record: Woken up 1 times to write data ]
      [ perf record: Captured and wrote 0.001 MB perf.data (8 samples) ]
      $ perf diff
      # Event 'cycles:u'
      #
      # Baseline  Delta Abs  Shared Object     Symbol
      # ........  .........  ................  ..........................
      #
           0.92%    +87.66%  [unknown]         [k] 0xffffffff8825de16
          11.39%     +0.04%  ld-2.32.so        [.] __GI___tunables_init
          87.70%             ld-2.32.so        [.] _dl_check_map_versions
      $ sudo chown root:root perf.data
      [sudo] password for acme:
      $ perf diff
      failed to open perf.data: Permission denied
      Failed to open perf.data
      Segmentation fault (core dumped)
      $
    
    After the patch:
    
      $ perf diff
      failed to open perf.data: Permission denied
      Failed to open perf.data
      $
    
    Signed-off-by: Dmitry Safonov <dima@arista.com>
    Acked-by: Namhyung Kim <namhyung@kernel.org>
    Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-03-02 15:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-02  2:35 [PATCH] perf diff: Don't crash on freeing errno-session Dmitry Safonov
2021-03-02  4:47 ` Namhyung Kim
2021-03-02 12:31   ` Arnaldo Carvalho de Melo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.