linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] perf script: add flamegraph.py script
@ 2020-03-20 15:13 Andreas Gerstmayr
  2020-03-24 16:16 ` Kim Phillips
                   ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Andreas Gerstmayr @ 2020-03-20 15:13 UTC (permalink / raw)
  To: linux-perf-users
  Cc: Martin Spier, Brendan Gregg, Andreas Gerstmayr, Peter Zijlstra,
	Ingo Molnar, Arnaldo Carvalho de Melo, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Namhyung Kim, linux-kernel

This script works in tandem with d3-flame-graph to generate flame graphs
from perf. It supports two output formats: JSON and HTML (the default).
The HTML format will look for a standalone d3-flame-graph template file in
/usr/share/d3-flame-graph/d3-flamegraph-base.html and fill in the collected
stacks.

Usage:

    perf record -a -g -F 99 sleep 60
    perf script report flamegraph

Combined:

    perf script flamegraph -a -F 99 sleep 60

Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
---
Package for d3-flame-graph is currently under review, in the meantime you can 
download the template from:
https://cdn.jsdelivr.net/npm/d3-flame-graph@3.0.2/dist/templates/d3-flamegraph-base.html
and move it to /usr/share/d3-flame-graph/d3-flamegraph-base.html

 .../perf/scripts/python/bin/flamegraph-record |   2 +
 .../perf/scripts/python/bin/flamegraph-report |   3 +
 tools/perf/scripts/python/flamegraph.py       | 126 ++++++++++++++++++
 3 files changed, 131 insertions(+)
 create mode 100755 tools/perf/scripts/python/bin/flamegraph-record
 create mode 100755 tools/perf/scripts/python/bin/flamegraph-report
 create mode 100755 tools/perf/scripts/python/flamegraph.py

diff --git a/tools/perf/scripts/python/bin/flamegraph-record b/tools/perf/scripts/python/bin/flamegraph-record
new file mode 100755
index 000000000000..725d66e71570
--- /dev/null
+++ b/tools/perf/scripts/python/bin/flamegraph-record
@@ -0,0 +1,2 @@
+#!/usr/bin/sh
+perf record -g "$@"
diff --git a/tools/perf/scripts/python/bin/flamegraph-report b/tools/perf/scripts/python/bin/flamegraph-report
new file mode 100755
index 000000000000..b1a79afd903b
--- /dev/null
+++ b/tools/perf/scripts/python/bin/flamegraph-report
@@ -0,0 +1,3 @@
+#!/usr/bin/sh
+# description: create flame graphs
+perf script -s "$PERF_EXEC_PATH"/scripts/python/flamegraph.py -- "$@"
diff --git a/tools/perf/scripts/python/flamegraph.py b/tools/perf/scripts/python/flamegraph.py
new file mode 100755
index 000000000000..5835d190ca42
--- /dev/null
+++ b/tools/perf/scripts/python/flamegraph.py
@@ -0,0 +1,126 @@
+# flamegraph.py - create flame graphs from perf samples
+# SPDX-License-Identifier: GPL-2.0
+#
+# Usage:
+#
+#     perf record -a -g -F 99 sleep 60
+#     perf script report flamegraph
+#
+# Combined:
+#
+#     perf script flamegraph -a -F 99 sleep 60
+#
+# Written by Andreas Gerstmayr <agerstmayr@redhat.com>
+# Flame Graphs invented by Brendan Gregg <bgregg@netflix.com>
+# Works in tandem with d3-flame-graph by Martin Spier <mspier@netflix.com>
+
+import sys
+import os
+import argparse
+import json
+
+
+class Node:
+    def __init__(self, name, libtype=""):
+        self.name = name
+        self.libtype = libtype
+        self.value = 0
+        self.children = []
+
+    def toJSON(self):
+        return {
+            "n": self.name,
+            "l": self.libtype,
+            "v": self.value,
+            "c": self.children
+        }
+
+
+class FlameGraphCLI:
+    def __init__(self, args):
+        self.args = args
+        self.stack = Node("root")
+
+        if self.args.format == "html" and \
+                not os.path.isfile(self.args.template):
+            print(f"Flame Graph template {self.args.template} does not " +
+                  f"exist. Please install the js-d3-flame-graph (RPM) or " +
+                  f"libjs-d3-flame-graph (deb) package, specify an " +
+                  f"existing flame graph template (--template PATH) or " +
+                  f"another output format (--format FORMAT).",
+                  file=sys.stderr)
+            sys.exit(1)
+
+    def find_or_create_node(self, node, name, dso):
+        libtype = "kernel" if dso == "[kernel.kallsyms]" else ""
+        if name is None:
+            name = "[unknown]"
+
+        for child in node.children:
+            if child.name == name and child.libtype == libtype:
+                return child
+
+        child = Node(name, libtype)
+        node.children.append(child)
+        return child
+
+    def process_event(self, event):
+        node = self.find_or_create_node(self.stack, event["comm"], None)
+        if "callchain" in event:
+            for entry in reversed(event['callchain']):
+                node = self.find_or_create_node(
+                    node, entry.get("sym", {}).get("name"), event.get("dso"))
+        else:
+            node = self.find_or_create_node(
+                node, entry.get("symbol"), event.get("dso"))
+        node.value += 1
+
+    def trace_end(self):
+        json_str = json.dumps(self.stack, default=lambda x: x.toJSON(),
+                              indent=self.args.indent)
+
+        if self.args.format == "html":
+            try:
+                with open(self.args.template) as f:
+                    output_str = f.read().replace("/** @flamegraph_json **/",
+                                                  json_str)
+            except IOError as e:
+                print(f"Error reading template file: {e}", file=sys.stderr)
+                sys.exit(1)
+            output_fn = self.args.output or "flamegraph.html"
+        else:
+            output_str = json_str
+            output_fn = self.args.output or "stacks.json"
+
+        if output_fn == "-":
+            sys.stdout.write(output_str)
+        else:
+            print(f"dumping data to {output_fn}")
+            try:
+                with open(output_fn, "w") as out:
+                    out.write(output_str)
+            except IOError as e:
+                print(f"Error writing output file: {e}", file=sys.stderr)
+                sys.exit(1)
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description="Create flame graphs.")
+    parser.add_argument("-F", "--format",
+                        default="html", choices=["json", "html"],
+                        help="output file format")
+    parser.add_argument("-o", "--output",
+                        help="output file name")
+    parser.add_argument("--indent",
+                        type=int, help="JSON indentation")
+    parser.add_argument("--template",
+                        default="/usr/share/d3-flame-graph/d3-flamegraph-base.html",
+                        help="path to flamegraph HTML template")
+    parser.add_argument("-i", "--input",
+                        help=argparse.SUPPRESS)
+
+    args = parser.parse_args()
+    cli = FlameGraphCLI(args)
+
+    process_event = cli.process_event
+    trace_end = cli.trace_end
-- 
2.25.1


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

* Re: [PATCH] perf script: add flamegraph.py script
  2020-03-20 15:13 [PATCH] perf script: add flamegraph.py script Andreas Gerstmayr
@ 2020-03-24 16:16 ` Kim Phillips
  2020-03-24 19:05   ` Andreas Gerstmayr
  2020-04-06 15:11 ` Arnaldo Carvalho de Melo
  2020-04-22 12:17 ` [tip: perf/core] perf script: Add " tip-bot2 for Andreas Gerstmayr
  2 siblings, 1 reply; 24+ messages in thread
From: Kim Phillips @ 2020-03-24 16:16 UTC (permalink / raw)
  To: Andreas Gerstmayr, linux-perf-users
  Cc: Martin Spier, Brendan Gregg, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, linux-kernel

On 3/20/20 10:13 AM, Andreas Gerstmayr wrote:
> This script works in tandem with d3-flame-graph to generate flame graphs
> from perf. It supports two output formats: JSON and HTML (the default).
> The HTML format will look for a standalone d3-flame-graph template file in
> /usr/share/d3-flame-graph/d3-flamegraph-base.html and fill in the collected
> stacks.
> 
> Usage:
> 
>     perf record -a -g -F 99 sleep 60
>     perf script report flamegraph

On Ubuntu 19.10, where python 2.7 is still the default, I get:

$ perf script report flamegraph
  File "/usr/libexec/perf-core/scripts/python/flamegraph.py", line 46
    print(f"Flame Graph template {self.args.template} does not " +
                                                               ^
SyntaxError: invalid syntax
Error running python script /usr/libexec/perf-core/scripts/python/flamegraph.py

Installing libpython3-dev doesn't help.

$ perf script -s lang

Scripting language extensions (used in perf script -s [spec:]script.[spec]):

  Perl                                       [Perl]
  pl                                         [Perl]
  Python                                     [Python]
  py                                         [Python]

Should there be a python3 in that list?

Thanks,

Kim

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

* Re: [PATCH] perf script: add flamegraph.py script
  2020-03-24 16:16 ` Kim Phillips
@ 2020-03-24 19:05   ` Andreas Gerstmayr
  2020-03-24 21:26     ` Arnaldo Melo
  2020-03-26 19:04     ` Kim Phillips
  0 siblings, 2 replies; 24+ messages in thread
From: Andreas Gerstmayr @ 2020-03-24 19:05 UTC (permalink / raw)
  To: Kim Phillips, linux-perf-users
  Cc: Martin Spier, Brendan Gregg, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, linux-kernel

On 24.03.20 17:16, Kim Phillips wrote:
> On Ubuntu 19.10, where python 2.7 is still the default, I get:
> 
> $ perf script report flamegraph
>    File "/usr/libexec/perf-core/scripts/python/flamegraph.py", line 46
>      print(f"Flame Graph template {self.args.template} does not " +
>                                                                 ^
> SyntaxError: invalid syntax
> Error running python script /usr/libexec/perf-core/scripts/python/flamegraph.py
> 
> Installing libpython3-dev doesn't help.

Hmm, I was hoping that I can drop support for Python 2 in 2020 ;) (it's 
officially EOL since Jan 1, 2020)

The Ubuntu 18.04 release notes mention that "Python 2 is no longer 
installed by default. Python 3 has been updated to 3.6. This is the last 
LTS release to include Python 2 in main." 
(https://wiki.ubuntu.com/BionicBeaver/ReleaseNotes) - so imho it should 
be fine to drop Python 2 support.

I tested it with a Ubuntu VM, and by default the Python bindings aren't 
enabled in perf (see 
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1707875).

But you can compile perf and select Python 3:

$ make -j2 PYTHON=python3

in the perf source directory (libpython3-dev must be installed).


Does this work for you?


Cheers,
Andreas


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

* Re: [PATCH] perf script: add flamegraph.py script
  2020-03-24 19:05   ` Andreas Gerstmayr
@ 2020-03-24 21:26     ` Arnaldo Melo
  2020-03-26 19:04     ` Kim Phillips
  1 sibling, 0 replies; 24+ messages in thread
From: Arnaldo Melo @ 2020-03-24 21:26 UTC (permalink / raw)
  To: Andreas Gerstmayr, Kim Phillips, linux-perf-users
  Cc: Martin Spier, Brendan Gregg, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, linux-kernel



On March 24, 2020 4:05:15 PM GMT-03:00, Andreas Gerstmayr <agerstmayr@redhat.com> wrote:
>On 24.03.20 17:16, Kim Phillips wrote:
>> On Ubuntu 19.10, where python 2.7 is still the default, I get:
>> 
>> $ perf script report flamegraph
>>    File "/usr/libexec/perf-core/scripts/python/flamegraph.py", line
>46
>>      print(f"Flame Graph template {self.args.template} does not " +
>>                                                                 ^
>> SyntaxError: invalid syntax
>> Error running python script
>/usr/libexec/perf-core/scripts/python/flamegraph.py
>> 
>> Installing libpython3-dev doesn't help.
>
>Hmm, I was hoping that I can drop support for Python 2 in 2020 ;) (it's
>
>officially EOL since Jan 1, 2020)
>
>The Ubuntu 18.04 release notes mention that "Python 2 is no longer 
>installed by default. Python 3 has been updated to 3.6. This is the
>last 
>LTS release to include Python 2 in main." 
>(https://wiki.ubuntu.com/BionicBeaver/ReleaseNotes) - so imho it should
>
>be fine to drop Python 2 support.
>
>I tested it with a Ubuntu VM, and by default the Python bindings aren't
>
>enabled in perf (see 
>https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1707875).
>
>But you can compile perf and select Python 3:
>
>$ make -j2 PYTHON=python3
>

I plan to make this the default soon.

- Arnaldo
>in the perf source directory (libpython3-dev must be installed).
>
>
>Does this work for you?
>
>
>Cheers,
>Andreas

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.

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

* Re: [PATCH] perf script: add flamegraph.py script
  2020-03-24 19:05   ` Andreas Gerstmayr
  2020-03-24 21:26     ` Arnaldo Melo
@ 2020-03-26 19:04     ` Kim Phillips
  2020-04-02 12:43       ` [PATCH] perf script: fix invalid read Andreas Gerstmayr
                         ` (2 more replies)
  1 sibling, 3 replies; 24+ messages in thread
From: Kim Phillips @ 2020-03-26 19:04 UTC (permalink / raw)
  To: Andreas Gerstmayr, linux-perf-users
  Cc: Martin Spier, Brendan Gregg, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, linux-kernel

On 3/24/20 2:05 PM, Andreas Gerstmayr wrote:
> On 24.03.20 17:16, Kim Phillips wrote:
>> On Ubuntu 19.10, where python 2.7 is still the default, I get:
>>
>> $ perf script report flamegraph
>>    File "/usr/libexec/perf-core/scripts/python/flamegraph.py", line 46
>>      print(f"Flame Graph template {self.args.template} does not " +
>>                                                                 ^
>> SyntaxError: invalid syntax
>> Error running python script /usr/libexec/perf-core/scripts/python/flamegraph.py
>>
>> Installing libpython3-dev doesn't help.
> 
> Hmm, I was hoping that I can drop support for Python 2 in 2020 ;) (it's officially EOL since Jan 1, 2020)
> 
> The Ubuntu 18.04 release notes mention that "Python 2 is no longer installed by default. Python 3 has been updated to 3.6. This is the last LTS release to include Python 2 in main." (https://wiki.ubuntu.com/BionicBeaver/ReleaseNotes) - so imho it should be fine to drop Python 2 support.
> 
> I tested it with a Ubuntu VM, and by default the Python bindings aren't enabled in perf (see https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1707875).
> 
> But you can compile perf and select Python 3:
> 
> $ make -j2 PYTHON=python3
> 
> in the perf source directory (libpython3-dev must be installed).
> 
> 
> Does this work for you?

Not on Ubuntu 18.04.4 LTS, but it does on 19.10.

On 19.10 however, when specifying dwarf on the record, e.g.:

sudo perf record -a -g -C2,4 --call-graph=dwarf -- sleep 10

I now get a SIGSEGV when executing perf script report flamegraph.

Here's a trace:

#0  0x000055555590a9b2 in regs_map (regs=0x7fffffffbfc8, mask=16715775, 
    bf=0x7fffffffba60 "", size=512) at util/scripting-engines/trace-event-python.c:696
#1  0x000055555590ab03 in set_regs_in_dict (dict=0x7ffff61dd500, sample=0x7fffffffbf20, 
    evsel=0x555555d7a700) at util/scripting-engines/trace-event-python.c:718
#2  0x000055555590af1f in get_perf_sample_dict (sample=0x7fffffffbf20, 
    evsel=0x555555d7a700, al=0x7fffffffbdd0, callchain=0x7ffff625b780)
    at util/scripting-engines/trace-event-python.c:787
#3  0x000055555590ce3e in python_process_general_event (sample=0x7fffffffbf20, 
    evsel=0x555555d7a700, al=0x7fffffffbdd0)
    at util/scripting-engines/trace-event-python.c:1301
#4  0x000055555590cf94 in python_process_event (event=0x7ffff60b0a48, 
    sample=0x7fffffffbf20, evsel=0x555555d7a700, al=0x7fffffffbdd0)
    at util/scripting-engines/trace-event-python.c:1328
#5  0x000055555577375c in process_sample_event (tool=0x7fffffffcf30, 
    event=0x7ffff60b0a48, sample=0x7fffffffbf20, evsel=0x555555d7a700, 
    machine=0x555555d73168) at builtin-script.c:2072
#6  0x000055555585f3d9 in perf_evlist__deliver_sample (evlist=0x555555d79c60, 
    tool=0x7fffffffcf30, event=0x7ffff60b0a48, sample=0x7fffffffbf20, 
    evsel=0x555555d7a700, machine=0x555555d73168) at util/session.c:1389
#7  0x000055555585f588 in machines__deliver_event (machines=0x555555d73168, 
    evlist=0x555555d79c60, event=0x7ffff60b0a48, sample=0x7fffffffbf20, 
    tool=0x7fffffffcf30, file_offset=3037768) at util/session.c:1426
#8  0x000055555585fa32 in perf_session__deliver_event (session=0x555555d72fe0, 
    event=0x7ffff60b0a48, tool=0x7fffffffcf30, file_offset=3037768)
    at util/session.c:1499
#9  0x000055555585bf5e in ordered_events__deliver_event (oe=0x555555d79b20, 
    event=0x555556446588) at util/session.c:183
#10 0x0000555555864010 in do_flush (oe=0x555555d79b20, show_progress=false)
    at util/ordered-events.c:244
#11 0x000055555586435f in __ordered_events__flush (oe=0x555555d79b20, 
    how=OE_FLUSH__ROUND, timestamp=0) at util/ordered-events.c:323
#12 0x0000555555864447 in ordered_events__flush (oe=0x555555d79b20, how=OE_FLUSH__ROUND)
    at util/ordered-events.c:341
#13 0x000055555585e2b1 in process_finished_round (tool=0x7fffffffcf30, 
    event=0x7ffff60ec040, oe=0x555555d79b20) at util/session.c:997
#14 0x000055555585fcea in perf_session__process_user_event (session=0x555555d72fe0, 
    event=0x7ffff60ec040, file_offset=3280960) at util/session.c:1546
#15 0x000055555586055d in perf_session__process_event (session=0x555555d72fe0, 
    event=0x7ffff60ec040, file_offset=3280960) at util/session.c:1706
#16 0x0000555555861973 in process_simple (session=0x555555d72fe0, event=0x7ffff60ec040, 
    file_offset=3280960) at util/session.c:2202
#17 0x0000555555861792 in reader__process_events (rd=0x7fffffffcd70, 
    session=0x555555d72fe0, prog=0x7fffffffcd90) at util/session.c:2168
#18 0x0000555555861a68 in __perf_session__process_events (session=0x555555d72fe0)
    at util/session.c:2225
#19 0x0000555555861b9d in perf_session__process_events (session=0x555555d72fe0)
    at util/session.c:2258
#20 0x0000555555774d02 in __cmd_script (script=0x7fffffffcf30) at builtin-script.c:2557
#21 0x0000555555779988 in cmd_script (argc=0, argv=0x7fffffffebd0)
    at builtin-script.c:3926
#22 0x00005555557f2a93 in run_builtin (p=0x555555bb44d8 <commands+408>, argc=4, 
    argv=0x7fffffffebd0) at perf.c:312
#23 0x00005555557f2d18 in handle_internal_command (argc=4, argv=0x7fffffffebd0)
    at perf.c:364
#24 0x00005555557f2e6b in run_argv (argcp=0x7fffffffea2c, argv=0x7fffffffea20)
    at perf.c:408
#25 0x00005555557f326e in main (argc=4, argv=0x7fffffffebd0) at perf.c:538

This is on today's acme's perf/urgent branch.

Thanks,

Kim

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

* [PATCH] perf script: fix invalid read
  2020-03-26 19:04     ` Kim Phillips
@ 2020-04-02 12:43       ` Andreas Gerstmayr
  2020-04-02 15:15         ` Arnaldo Carvalho de Melo
  2020-04-04  8:41         ` [tip: perf/urgent] perf script: Fix invalid read of directory entry after closedir() tip-bot2 for Andreas Gerstmayr
  2020-04-02 12:54       ` [PATCH] perf script report: fix segfault when using DWARF mode Andreas Gerstmayr
  2020-04-02 13:04       ` [PATCH] perf script: add flamegraph.py script Andreas Gerstmayr
  2 siblings, 2 replies; 24+ messages in thread
From: Andreas Gerstmayr @ 2020-04-02 12:43 UTC (permalink / raw)
  To: linux-perf-users
  Cc: Andreas Gerstmayr, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, linux-kernel

closedir(lang_dir) frees the memory of script_dirent->d_name, which
gets accessed in the next line in a call to scnprintf().

Valgrind report:

Invalid read of size 1
==413557==    at 0x483CBE6: strlen (vg_replace_strmem.c:461)
==413557==    by 0x4DD45FD: __vfprintf_internal (vfprintf-internal.c:1688)
==413557==    by 0x4DE6679: __vsnprintf_internal (vsnprintf.c:114)
==413557==    by 0x53A037: vsnprintf (stdio2.h:80)
==413557==    by 0x53A037: scnprintf (vsprintf.c:21)
==413557==    by 0x435202: get_script_path (builtin-script.c:3223)
==413557==  Address 0x52e7313 is 1,139 bytes inside a block of size 32,816 free'd
==413557==    at 0x483AA0C: free (vg_replace_malloc.c:540)
==413557==    by 0x4E303C0: closedir (closedir.c:50)
==413557==    by 0x4351DC: get_script_path (builtin-script.c:3222)

Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
---
 tools/perf/builtin-script.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 656b347f6dd8..170af13b4d53 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -3218,10 +3218,10 @@ static char *get_script_path(const char *script_root, const char *suffix)
 			__script_root = get_script_root(script_dirent, suffix);
 			if (__script_root && !strcmp(script_root, __script_root)) {
 				free(__script_root);
-				closedir(lang_dir);
 				closedir(scripts_dir);
 				scnprintf(script_path, MAXPATHLEN, "%s/%s",
 					  lang_path, script_dirent->d_name);
+				closedir(lang_dir);
 				return strdup(script_path);
 			}
 			free(__script_root);
-- 
2.25.1


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

* [PATCH] perf script report: fix segfault when using DWARF mode
  2020-03-26 19:04     ` Kim Phillips
  2020-04-02 12:43       ` [PATCH] perf script: fix invalid read Andreas Gerstmayr
@ 2020-04-02 12:54       ` Andreas Gerstmayr
  2020-04-02 15:16         ` Arnaldo Carvalho de Melo
                           ` (2 more replies)
  2020-04-02 13:04       ` [PATCH] perf script: add flamegraph.py script Andreas Gerstmayr
  2 siblings, 3 replies; 24+ messages in thread
From: Andreas Gerstmayr @ 2020-04-02 12:54 UTC (permalink / raw)
  To: linux-perf-users
  Cc: Andreas Gerstmayr, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, Adrian Hunter, Steven Rostedt (VMware),
	Kan Liang, linux-kernel

When running perf script report with a Python script and a callgraph in
DWARF mode, intr_regs->regs can be 0 and therefore crashing the regs_map
function.

Added a check for this condition (same check as in builtin-script.c:595).

Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
---
 tools/perf/util/scripting-engines/trace-event-python.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 8c1b27cd8b99..2c372cf5495e 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -694,6 +694,9 @@ static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size)
 
 	bf[0] = 0;
 
+	if (!regs || !regs->regs)
+		return 0;
+
 	for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
 		u64 val = regs->regs[i++];
 
-- 
2.25.1


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

* Re: [PATCH] perf script: add flamegraph.py script
  2020-03-26 19:04     ` Kim Phillips
  2020-04-02 12:43       ` [PATCH] perf script: fix invalid read Andreas Gerstmayr
  2020-04-02 12:54       ` [PATCH] perf script report: fix segfault when using DWARF mode Andreas Gerstmayr
@ 2020-04-02 13:04       ` Andreas Gerstmayr
  2020-04-06 14:27         ` Kim Phillips
  2 siblings, 1 reply; 24+ messages in thread
From: Andreas Gerstmayr @ 2020-04-02 13:04 UTC (permalink / raw)
  To: Kim Phillips, linux-perf-users
  Cc: Martin Spier, Brendan Gregg, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, linux-kernel

On 26.03.20 20:04, Kim Phillips wrote:
> I now get a SIGSEGV when executing perf script report flamegraph.
> 
> Here's a trace:
> 
> #0  0x000055555590a9b2 in regs_map (regs=0x7fffffffbfc8, mask=16715775,
>      bf=0x7fffffffba60 "", size=512) at util/scripting-engines/trace-event-python.c:696
> #1  0x000055555590ab03 in set_regs_in_dict (dict=0x7ffff61dd500, sample=0x7fffffffbf20,
>      evsel=0x555555d7a700) at util/scripting-engines/trace-event-python.c:718

This error seems unrelated to flamegraph.py (occurs also with the 
stackcollapse.py script).

Looks like the intr_regs->regs can be 0 when running in DWARF mode (this 
error doesn't occur in the default mode). I've added a check and sent a 
patch. While at it, valgrind reported an invalid read in a different 
code path, which is fixed by the other patch I just sent a few minutes ago.

Can you please test again and report if there are any other issues?


Cheers,
Andreas


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

* Re: [PATCH] perf script: fix invalid read
  2020-04-02 12:43       ` [PATCH] perf script: fix invalid read Andreas Gerstmayr
@ 2020-04-02 15:15         ` Arnaldo Carvalho de Melo
  2020-04-04  8:41         ` [tip: perf/urgent] perf script: Fix invalid read of directory entry after closedir() tip-bot2 for Andreas Gerstmayr
  1 sibling, 0 replies; 24+ messages in thread
From: Arnaldo Carvalho de Melo @ 2020-04-02 15:15 UTC (permalink / raw)
  To: Andreas Gerstmayr
  Cc: linux-perf-users, Peter Zijlstra, Ingo Molnar, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Namhyung Kim, linux-kernel

Em Thu, Apr 02, 2020 at 02:43:38PM +0200, Andreas Gerstmayr escreveu:
> closedir(lang_dir) frees the memory of script_dirent->d_name, which
> gets accessed in the next line in a call to scnprintf().
> 
> Valgrind report:
> 
> Invalid read of size 1
> ==413557==    at 0x483CBE6: strlen (vg_replace_strmem.c:461)
> ==413557==    by 0x4DD45FD: __vfprintf_internal (vfprintf-internal.c:1688)
> ==413557==    by 0x4DE6679: __vsnprintf_internal (vsnprintf.c:114)
> ==413557==    by 0x53A037: vsnprintf (stdio2.h:80)
> ==413557==    by 0x53A037: scnprintf (vsprintf.c:21)
> ==413557==    by 0x435202: get_script_path (builtin-script.c:3223)
> ==413557==  Address 0x52e7313 is 1,139 bytes inside a block of size 32,816 free'd
> ==413557==    at 0x483AA0C: free (vg_replace_malloc.c:540)
> ==413557==    by 0x4E303C0: closedir (closedir.c:50)
> ==413557==    by 0x4351DC: get_script_path (builtin-script.c:3222)

Thanks, applied to perf/urgent.

- Arnaldo
 
> Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
> ---
>  tools/perf/builtin-script.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> index 656b347f6dd8..170af13b4d53 100644
> --- a/tools/perf/builtin-script.c
> +++ b/tools/perf/builtin-script.c
> @@ -3218,10 +3218,10 @@ static char *get_script_path(const char *script_root, const char *suffix)
>  			__script_root = get_script_root(script_dirent, suffix);
>  			if (__script_root && !strcmp(script_root, __script_root)) {
>  				free(__script_root);
> -				closedir(lang_dir);
>  				closedir(scripts_dir);
>  				scnprintf(script_path, MAXPATHLEN, "%s/%s",
>  					  lang_path, script_dirent->d_name);
> +				closedir(lang_dir);
>  				return strdup(script_path);
>  			}
>  			free(__script_root);
> -- 
> 2.25.1
> 

-- 

- Arnaldo

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

* Re: [PATCH] perf script report: fix segfault when using DWARF mode
  2020-04-02 12:54       ` [PATCH] perf script report: fix segfault when using DWARF mode Andreas Gerstmayr
@ 2020-04-02 15:16         ` Arnaldo Carvalho de Melo
  2020-04-02 19:07         ` Kim Phillips
  2020-04-04  8:41         ` [tip: perf/urgent] perf script report: Fix SEGFAULT " tip-bot2 for Andreas Gerstmayr
  2 siblings, 0 replies; 24+ messages in thread
From: Arnaldo Carvalho de Melo @ 2020-04-02 15:16 UTC (permalink / raw)
  To: Andreas Gerstmayr
  Cc: linux-perf-users, Peter Zijlstra, Ingo Molnar, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Namhyung Kim, Adrian Hunter,
	Steven Rostedt (VMware),
	Kan Liang, linux-kernel

Em Thu, Apr 02, 2020 at 02:54:16PM +0200, Andreas Gerstmayr escreveu:
> When running perf script report with a Python script and a callgraph in
> DWARF mode, intr_regs->regs can be 0 and therefore crashing the regs_map
> function.
> 
> Added a check for this condition (same check as in builtin-script.c:595).

Thanks, applied to perf/urgent.

- Arnaldo
 
> Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
> ---
>  tools/perf/util/scripting-engines/trace-event-python.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
> index 8c1b27cd8b99..2c372cf5495e 100644
> --- a/tools/perf/util/scripting-engines/trace-event-python.c
> +++ b/tools/perf/util/scripting-engines/trace-event-python.c
> @@ -694,6 +694,9 @@ static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size)
>  
>  	bf[0] = 0;
>  
> +	if (!regs || !regs->regs)
> +		return 0;
> +
>  	for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
>  		u64 val = regs->regs[i++];
>  
> -- 
> 2.25.1
> 

-- 

- Arnaldo

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

* Re: [PATCH] perf script report: fix segfault when using DWARF mode
  2020-04-02 12:54       ` [PATCH] perf script report: fix segfault when using DWARF mode Andreas Gerstmayr
  2020-04-02 15:16         ` Arnaldo Carvalho de Melo
@ 2020-04-02 19:07         ` Kim Phillips
  2020-04-03 12:40           ` Arnaldo Carvalho de Melo
  2020-04-04  8:41         ` [tip: perf/urgent] perf script report: Fix SEGFAULT " tip-bot2 for Andreas Gerstmayr
  2 siblings, 1 reply; 24+ messages in thread
From: Kim Phillips @ 2020-04-02 19:07 UTC (permalink / raw)
  To: Andreas Gerstmayr, linux-perf-users
  Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Adrian Hunter, Steven Rostedt (VMware),
	Kan Liang, linux-kernel

On 4/2/20 7:54 AM, Andreas Gerstmayr wrote:
> When running perf script report with a Python script and a callgraph in
> DWARF mode, intr_regs->regs can be 0 and therefore crashing the regs_map
> function.
> 
> Added a check for this condition (same check as in builtin-script.c:595).
> 
> Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
> ---

Tested-by: Kim Phillips <kim.phillips@amd.com>

Thanks,

Kim

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

* Re: [PATCH] perf script report: fix segfault when using DWARF mode
  2020-04-02 19:07         ` Kim Phillips
@ 2020-04-03 12:40           ` Arnaldo Carvalho de Melo
  2020-04-03 13:16             ` Andreas Gerstmayr
  0 siblings, 1 reply; 24+ messages in thread
From: Arnaldo Carvalho de Melo @ 2020-04-03 12:40 UTC (permalink / raw)
  To: Kim Phillips
  Cc: Andreas Gerstmayr, linux-perf-users, Peter Zijlstra, Ingo Molnar,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Adrian Hunter, Steven Rostedt (VMware),
	Kan Liang, linux-kernel

Em Thu, Apr 02, 2020 at 02:07:51PM -0500, Kim Phillips escreveu:
> On 4/2/20 7:54 AM, Andreas Gerstmayr wrote:
> > When running perf script report with a Python script and a callgraph in
> > DWARF mode, intr_regs->regs can be 0 and therefore crashing the regs_map
> > function.
> > 
> > Added a check for this condition (same check as in builtin-script.c:595).
> > 
> > Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
> > ---
> 
> Tested-by: Kim Phillips <kim.phillips@amd.com>

Thanks, added this to that patch.

- Arnaldo

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

* Re: [PATCH] perf script report: fix segfault when using DWARF mode
  2020-04-03 12:40           ` Arnaldo Carvalho de Melo
@ 2020-04-03 13:16             ` Andreas Gerstmayr
  2020-04-06  9:30               ` Andreas Gerstmayr
  0 siblings, 1 reply; 24+ messages in thread
From: Andreas Gerstmayr @ 2020-04-03 13:16 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, Kim Phillips
  Cc: linux-perf-users, Peter Zijlstra, Ingo Molnar, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Namhyung Kim, Adrian Hunter,
	Steven Rostedt (VMware),
	Kan Liang, linux-kernel

On 03.04.20 14:40, Arnaldo Carvalho de Melo wrote:
> Em Thu, Apr 02, 2020 at 02:07:51PM -0500, Kim Phillips escreveu:
>> On 4/2/20 7:54 AM, Andreas Gerstmayr wrote:
>>> When running perf script report with a Python script and a callgraph in
>>> DWARF mode, intr_regs->regs can be 0 and therefore crashing the regs_map
>>> function.
>>>
>>> Added a check for this condition (same check as in builtin-script.c:595).
>>>
>>> Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
>>> ---
>>
>> Tested-by: Kim Phillips <kim.phillips@amd.com>
> 
> Thanks, added this to that patch.
> 

Great, thanks!


Cheers,
Andreas


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

* [tip: perf/urgent] perf script: Fix invalid read of directory entry after closedir()
  2020-04-02 12:43       ` [PATCH] perf script: fix invalid read Andreas Gerstmayr
  2020-04-02 15:15         ` Arnaldo Carvalho de Melo
@ 2020-04-04  8:41         ` tip-bot2 for Andreas Gerstmayr
  1 sibling, 0 replies; 24+ messages in thread
From: tip-bot2 for Andreas Gerstmayr @ 2020-04-04  8:41 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Andreas Gerstmayr, Alexander Shishkin, Jiri Olsa, Mark Rutland,
	Namhyung Kim, Peter Zijlstra, Arnaldo Carvalho de Melo, x86,
	LKML

The following commit has been merged into the perf/urgent branch of tip:

Commit-ID:     27486a85cb65bd258a9a213b3e95bdf8c24fd781
Gitweb:        https://git.kernel.org/tip/27486a85cb65bd258a9a213b3e95bdf8c24fd781
Author:        Andreas Gerstmayr <agerstmayr@redhat.com>
AuthorDate:    Thu, 02 Apr 2020 14:43:38 +02:00
Committer:     Arnaldo Carvalho de Melo <acme@redhat.com>
CommitterDate: Fri, 03 Apr 2020 10:03:18 -03:00

perf script: Fix invalid read of directory entry after closedir()

closedir(lang_dir) frees the memory of script_dirent->d_name, which
gets accessed in the next line in a call to scnprintf().

Valgrind report:

  Invalid read of size 1
  ==413557==    at 0x483CBE6: strlen (vg_replace_strmem.c:461)
  ==413557==    by 0x4DD45FD: __vfprintf_internal (vfprintf-internal.c:1688)
  ==413557==    by 0x4DE6679: __vsnprintf_internal (vsnprintf.c:114)
  ==413557==    by 0x53A037: vsnprintf (stdio2.h:80)
  ==413557==    by 0x53A037: scnprintf (vsprintf.c:21)
  ==413557==    by 0x435202: get_script_path (builtin-script.c:3223)
  ==413557==  Address 0x52e7313 is 1,139 bytes inside a block of size 32,816 free'd
  ==413557==    at 0x483AA0C: free (vg_replace_malloc.c:540)
  ==413557==    by 0x4E303C0: closedir (closedir.c:50)
  ==413557==    by 0x4351DC: get_script_path (builtin-script.c:3222)

Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.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>
Link: http://lore.kernel.org/lkml/20200402124337.419456-1-agerstmayr@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-script.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 186ebf8..1f57a7e 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -3265,10 +3265,10 @@ static char *get_script_path(const char *script_root, const char *suffix)
 			__script_root = get_script_root(script_dirent, suffix);
 			if (__script_root && !strcmp(script_root, __script_root)) {
 				free(__script_root);
-				closedir(lang_dir);
 				closedir(scripts_dir);
 				scnprintf(script_path, MAXPATHLEN, "%s/%s",
 					  lang_path, script_dirent->d_name);
+				closedir(lang_dir);
 				return strdup(script_path);
 			}
 			free(__script_root);

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

* [tip: perf/urgent] perf script report: Fix SEGFAULT when using DWARF mode
  2020-04-02 12:54       ` [PATCH] perf script report: fix segfault when using DWARF mode Andreas Gerstmayr
  2020-04-02 15:16         ` Arnaldo Carvalho de Melo
  2020-04-02 19:07         ` Kim Phillips
@ 2020-04-04  8:41         ` tip-bot2 for Andreas Gerstmayr
  2 siblings, 0 replies; 24+ messages in thread
From: tip-bot2 for Andreas Gerstmayr @ 2020-04-04  8:41 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Andreas Gerstmayr, Kim Phillips, Adrian Hunter,
	Alexander Shishkin, Jiri Olsa, Kan Liang, Mark Rutland,
	Namhyung Kim, Peter Zijlstra, Steven Rostedt (VMware),
	Arnaldo Carvalho de Melo, x86, LKML

The following commit has been merged into the perf/urgent branch of tip:

Commit-ID:     1a4025f06059eeaecb2ef24363350ea3431568df
Gitweb:        https://git.kernel.org/tip/1a4025f06059eeaecb2ef24363350ea3431568df
Author:        Andreas Gerstmayr <agerstmayr@redhat.com>
AuthorDate:    Thu, 02 Apr 2020 14:54:16 +02:00
Committer:     Arnaldo Carvalho de Melo <acme@redhat.com>
CommitterDate: Fri, 03 Apr 2020 09:39:53 -03:00

perf script report: Fix SEGFAULT when using DWARF mode

When running perf script report with a Python script and a callgraph in
DWARF mode, intr_regs->regs can be 0 and therefore crashing the regs_map
function.

Added a check for this condition (same check as in builtin-script.c:595).

Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
Tested-by: Kim Phillips <kim.phillips@amd.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt (VMware) <rostedt@goodmis.org>
Link: http://lore.kernel.org/lkml/20200402125417.422232-1-agerstmayr@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/scripting-engines/trace-event-python.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 8c1b27c..2c372cf 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -694,6 +694,9 @@ static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size)
 
 	bf[0] = 0;
 
+	if (!regs || !regs->regs)
+		return 0;
+
 	for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
 		u64 val = regs->regs[i++];
 

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

* Re: [PATCH] perf script report: fix segfault when using DWARF mode
  2020-04-03 13:16             ` Andreas Gerstmayr
@ 2020-04-06  9:30               ` Andreas Gerstmayr
  2020-04-06 12:59                 ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 24+ messages in thread
From: Andreas Gerstmayr @ 2020-04-06  9:30 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, Kim Phillips
  Cc: linux-perf-users, Peter Zijlstra, Ingo Molnar, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Namhyung Kim, Adrian Hunter,
	Steven Rostedt (VMware),
	Kan Liang, linux-kernel

On 03.04.20 15:16, Andreas Gerstmayr wrote:
> On 03.04.20 14:40, Arnaldo Carvalho de Melo wrote:
>> Em Thu, Apr 02, 2020 at 02:07:51PM -0500, Kim Phillips escreveu:
>>> On 4/2/20 7:54 AM, Andreas Gerstmayr wrote:
>>>> When running perf script report with a Python script and a callgraph in
>>>> DWARF mode, intr_regs->regs can be 0 and therefore crashing the 
>>>> regs_map
>>>> function.
>>>>
>>>> Added a check for this condition (same check as in 
>>>> builtin-script.c:595).
>>>>
>>>> Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
>>>> ---
>>>
>>> Tested-by: Kim Phillips <kim.phillips@amd.com>
>>
>> Thanks, added this to that patch.
>>
> 
> Great, thanks!

Ah, I thought you were referring to my initial flamegraph.py perf script.
Is there anything I can do to get it merged?


Cheers,
Andreas


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

* Re: [PATCH] perf script report: fix segfault when using DWARF mode
  2020-04-06  9:30               ` Andreas Gerstmayr
@ 2020-04-06 12:59                 ` Arnaldo Carvalho de Melo
  2020-04-06 14:28                   ` Kim Phillips
  0 siblings, 1 reply; 24+ messages in thread
From: Arnaldo Carvalho de Melo @ 2020-04-06 12:59 UTC (permalink / raw)
  To: Andreas Gerstmayr
  Cc: Arnaldo Carvalho de Melo, Kim Phillips, linux-perf-users,
	Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, Adrian Hunter, Steven Rostedt (VMware),
	Kan Liang, linux-kernel

Em Mon, Apr 06, 2020 at 11:30:23AM +0200, Andreas Gerstmayr escreveu:
> On 03.04.20 15:16, Andreas Gerstmayr wrote:
> > On 03.04.20 14:40, Arnaldo Carvalho de Melo wrote:
> > > Em Thu, Apr 02, 2020 at 02:07:51PM -0500, Kim Phillips escreveu:
> > > > On 4/2/20 7:54 AM, Andreas Gerstmayr wrote:
> > > > > When running perf script report with a Python script and a callgraph in
> > > > > DWARF mode, intr_regs->regs can be 0 and therefore crashing
> > > > > the regs_map
> > > > > function.

> > > > > Added a check for this condition (same check as in
> > > > > builtin-script.c:595).

> > > > > Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>

> > > > Tested-by: Kim Phillips <kim.phillips@amd.com>

> > > Thanks, added this to that patch.

> > Great, thanks!
 
> Ah, I thought you were referring to my initial flamegraph.py perf script.
> Is there anything I can do to get it merged?

I'll test it today, were there any Tested-by: or Reviewed-by: to that
flamegraph.py?

That is not yet a strict requirement for having patches accepted, but
help me a lot in dedicating time to test things that passed thru some
testing by other people,

Thanks,

- Arnaldo

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

* Re: [PATCH] perf script: add flamegraph.py script
  2020-04-02 13:04       ` [PATCH] perf script: add flamegraph.py script Andreas Gerstmayr
@ 2020-04-06 14:27         ` Kim Phillips
  0 siblings, 0 replies; 24+ messages in thread
From: Kim Phillips @ 2020-04-06 14:27 UTC (permalink / raw)
  To: Andreas Gerstmayr, linux-perf-users
  Cc: Martin Spier, Brendan Gregg, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, linux-kernel

On 4/2/20 8:04 AM, Andreas Gerstmayr wrote:
> On 26.03.20 20:04, Kim Phillips wrote:
>> I now get a SIGSEGV when executing perf script report flamegraph.
>>
>> Here's a trace:
>>
>> #0  0x000055555590a9b2 in regs_map (regs=0x7fffffffbfc8, mask=16715775,
>>      bf=0x7fffffffba60 "", size=512) at util/scripting-engines/trace-event-python.c:696
>> #1  0x000055555590ab03 in set_regs_in_dict (dict=0x7ffff61dd500, sample=0x7fffffffbf20,
>>      evsel=0x555555d7a700) at util/scripting-engines/trace-event-python.c:718
> 
> This error seems unrelated to flamegraph.py (occurs also with the stackcollapse.py script).
> 
> Looks like the intr_regs->regs can be 0 when running in DWARF mode (this error doesn't occur in the default mode). I've added a check and sent a patch. While at it, valgrind reported an invalid read in a different code path, which is fixed by the other patch I just sent a few minutes ago.
> 
> Can you please test again and report if there are any other issues?

This flamegraph patch works for me now:

Tested-by: Kim Phillips <kim.phillips@amd.com>

Thanks,

Kim

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

* Re: [PATCH] perf script report: fix segfault when using DWARF mode
  2020-04-06 12:59                 ` Arnaldo Carvalho de Melo
@ 2020-04-06 14:28                   ` Kim Phillips
  0 siblings, 0 replies; 24+ messages in thread
From: Kim Phillips @ 2020-04-06 14:28 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, Andreas Gerstmayr
  Cc: linux-perf-users, Peter Zijlstra, Ingo Molnar, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Namhyung Kim, Adrian Hunter,
	Steven Rostedt (VMware),
	Kan Liang, linux-kernel

On 4/6/20 7:59 AM, Arnaldo Carvalho de Melo wrote:
> Em Mon, Apr 06, 2020 at 11:30:23AM +0200, Andreas Gerstmayr escreveu:
>> On 03.04.20 15:16, Andreas Gerstmayr wrote:
>>> On 03.04.20 14:40, Arnaldo Carvalho de Melo wrote:
>>>> Em Thu, Apr 02, 2020 at 02:07:51PM -0500, Kim Phillips escreveu:
>>>>> On 4/2/20 7:54 AM, Andreas Gerstmayr wrote:
>>>>>> When running perf script report with a Python script and a callgraph in
>>>>>> DWARF mode, intr_regs->regs can be 0 and therefore crashing
>>>>>> the regs_map
>>>>>> function.
>>>>>> Added a check for this condition (same check as in
>>>>>> builtin-script.c:595).
>>>>>> Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
>>>>> Tested-by: Kim Phillips <kim.phillips@amd.com>
>>>> Thanks, added this to that patch.
>>> Great, thanks!
>> Ah, I thought you were referring to my initial flamegraph.py perf script.
>> Is there anything I can do to get it merged?
> 
> I'll test it today, were there any Tested-by: or Reviewed-by: to that
> flamegraph.py?

I just added mine.

Kim

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

* Re: [PATCH] perf script: add flamegraph.py script
  2020-03-20 15:13 [PATCH] perf script: add flamegraph.py script Andreas Gerstmayr
  2020-03-24 16:16 ` Kim Phillips
@ 2020-04-06 15:11 ` Arnaldo Carvalho de Melo
  2020-04-09 16:57   ` [PATCH] perf script flamegraph: python2 support, update cli args Andreas Gerstmayr
  2020-04-09 17:14   ` [PATCH] perf script: add flamegraph.py script Andreas Gerstmayr
  2020-04-22 12:17 ` [tip: perf/core] perf script: Add " tip-bot2 for Andreas Gerstmayr
  2 siblings, 2 replies; 24+ messages in thread
From: Arnaldo Carvalho de Melo @ 2020-04-06 15:11 UTC (permalink / raw)
  To: Andreas Gerstmayr
  Cc: linux-perf-users, Martin Spier, Brendan Gregg, Peter Zijlstra,
	Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Namhyung Kim, linux-kernel

Em Fri, Mar 20, 2020 at 04:13:48PM +0100, Andreas Gerstmayr escreveu:
> This script works in tandem with d3-flame-graph to generate flame graphs
> from perf. It supports two output formats: JSON and HTML (the default).
> The HTML format will look for a standalone d3-flame-graph template file in
> /usr/share/d3-flame-graph/d3-flamegraph-base.html and fill in the collected
> stacks.
> 
> Usage:
> 
>     perf record -a -g -F 99 sleep 60
>     perf script report flamegraph
> 
> Combined:
> 
>     perf script flamegraph -a -F 99 sleep 60
> 
> Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>

Trying it now with:

[root@five ~]# perf record -a -g -F 99 sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 1.120 MB perf.data (59 samples) ]
[root@five ~]#  perf script report flamegraph
  File "/home/acme/libexec/perf-core/scripts/python/flamegraph.py", line 46
    print(f"Flame Graph template {self.args.template} does not " +
                                                               ^
SyntaxError: invalid syntax
Error running python script /home/acme/libexec/perf-core/scripts/python/flamegraph.py
[root@five ~]#



Ok, gets better when I build with 'make -C tools/perf PYTHON=python3'

[root@five ~]#  perf script report flamegraph
Flame Graph template /usr/share/d3-flame-graph/d3-flamegraph-base.html does not exist. Please install the js-d3-flame-graph (RPM) or libjs-d3-flame-graph (deb) package, specify an existing flame graph template (--template PATH) or another output format (--format FORMAT).
[root@five ~]#

It works then, so I'll add a note to that effect. But please consider
fixing it so that it works with both python2 and python3, if possible,
or to fail gracefully and state that only python3 is supported and that
perf should be built with "PYTHON=python3" on the make command line.

Some RFEs for you to consider:

1. make:

   perf flamegraph -a -F 99 sleep 1

be equivalent, should be easy.

2. make the command somehow create a new tab on an existing browser with
the generated file, and switch the focus to that tab.

3. get whats in:

[root@five ~]# perf report --header-only
# ========
# captured on    : Mon Apr  6 12:02:52 2020
# header version : 1
# data offset    : 336
# data size      : 1173584
# feat offset    : 1173920
# hostname : five
# os release : 5.5.10-200.fc31.x86_64
# perf version : 5.6.gb6b7dc6ec0c8
# arch : x86_64
# nrcpus online : 12
# nrcpus avail : 12
# cpudesc : AMD Ryzen 5 3600X 6-Core Processor
# cpuid : AuthenticAMD,23,113,0
# total memory : 32890748 kB
# cmdline : /home/acme/bin/perf record -a -g -F 99 sleep 1
# event : name = cycles, , id = { 2918625, 2918626, 2918627, 2918628, 2918629, 2918630, 2918631, 2918632, 2918633, 2918634, 2918635, 2918636 }, size = 120, { sample_period, sample_freq } = 99, sample_type = IP|TID|TIME|CALLCHAIN|CPU|PERIOD, read_format = ID, disabled = 1,>
# CPU_TOPOLOGY info available, use -I to display
# NUMA_TOPOLOGY info available, use -I to display
# pmu mappings: amd_df = 8, software = 1, ibs_op = 11, ibs_fetch = 10, uprobe = 7, cpu = 4, amd_iommu_0 = 12, breakpoint = 5, amd_l3 = 9, tracepoint = 2, kprobe = 6, msr = 13
# CACHE info available, use -I to display
# time of first sample : 87600.831767
# time of last sample : 87601.096829
# sample duration :    265.062 ms
# MEM_TOPOLOGY info available, use -I to display
# bpf_prog_info 40: bpf_prog_6deef7357e7b4530 addr 0xffffffffc030650c size 66
# bpf_prog_info 41: bpf_prog_6deef7357e7b4530 addr 0xffffffffc03080e8 size 66
# bpf_prog_info 42: bpf_prog_6deef7357e7b4530 addr 0xffffffffc030a218 size 66
# bpf_prog_info 43: bpf_prog_6deef7357e7b4530 addr 0xffffffffc036c698 size 66
# bpf_prog_info 44: bpf_prog_5a2b06eab81b8f51 addr 0xffffffffc036e2c0 size 1132
# bpf_prog_info 45: bpf_prog_6deef7357e7b4530 addr 0xffffffffc06e7118 size 66
# bpf_prog_info 46: bpf_prog_6deef7357e7b4530 addr 0xffffffffc06e9cd8 size 66
# bpf_prog_info 47: bpf_prog_f3b9e166f6c1aaaa addr 0xffffffffc089732c size 1786
# bpf_prog_info 48: bpf_prog_6deef7357e7b4530 addr 0xffffffffc0dcb64c size 66
# bpf_prog_info 49: bpf_prog_6deef7357e7b4530 addr 0xffffffffc0dcd0fc size 66
# bpf_prog_info 50: bpf_prog_6deef7357e7b4530 addr 0xffffffffc0f4d8dc size 66
# bpf_prog_info 51: bpf_prog_6deef7357e7b4530 addr 0xffffffffc0f4fc7c size 66
# bpf_prog_info 52: bpf_prog_84efc2eecc454ca6 addr 0xffffffffc0f6e584 size 373
# missing features: TRACING_DATA BRANCH_STACK GROUP_DESC AUXTRACE STAT CLOCKID DIR_FORMAT COMPRESSED
# ========
#
[root@five ~]#

And make it available in some UI element.

Thanks,

- Arnaldo


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

* [PATCH] perf script flamegraph: python2 support, update cli args
  2020-04-06 15:11 ` Arnaldo Carvalho de Melo
@ 2020-04-09 16:57   ` Andreas Gerstmayr
  2020-04-13 13:59     ` Arnaldo Carvalho de Melo
  2020-04-09 17:14   ` [PATCH] perf script: add flamegraph.py script Andreas Gerstmayr
  1 sibling, 1 reply; 24+ messages in thread
From: Andreas Gerstmayr @ 2020-04-09 16:57 UTC (permalink / raw)
  To: linux-perf-users
  Cc: Andreas Gerstmayr, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, linux-kernel

* removed --indent argument
* renamed -F to -f argument to be consistent with other arguments

Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
---
 tools/perf/scripts/python/flamegraph.py | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/tools/perf/scripts/python/flamegraph.py b/tools/perf/scripts/python/flamegraph.py
index 5835d190ca42..61f3be9add6b 100755
--- a/tools/perf/scripts/python/flamegraph.py
+++ b/tools/perf/scripts/python/flamegraph.py
@@ -14,6 +14,7 @@
 # Flame Graphs invented by Brendan Gregg <bgregg@netflix.com>
 # Works in tandem with d3-flame-graph by Martin Spier <mspier@netflix.com>
 
+from __future__ import print_function
 import sys
 import os
 import argparse
@@ -43,11 +44,11 @@ class FlameGraphCLI:
 
         if self.args.format == "html" and \
                 not os.path.isfile(self.args.template):
-            print(f"Flame Graph template {self.args.template} does not " +
-                  f"exist. Please install the js-d3-flame-graph (RPM) or " +
-                  f"libjs-d3-flame-graph (deb) package, specify an " +
-                  f"existing flame graph template (--template PATH) or " +
-                  f"another output format (--format FORMAT).",
+            print("Flame Graph template {} does not exist. Please install "
+                  "the js-d3-flame-graph (RPM) or libjs-d3-flame-graph (deb) "
+                  "package, specify an existing flame graph template "
+                  "(--template PATH) or another output format "
+                  "(--format FORMAT).".format(self.args.template),
                   file=sys.stderr)
             sys.exit(1)
 
@@ -76,8 +77,7 @@ class FlameGraphCLI:
         node.value += 1
 
     def trace_end(self):
-        json_str = json.dumps(self.stack, default=lambda x: x.toJSON(),
-                              indent=self.args.indent)
+        json_str = json.dumps(self.stack, default=lambda x: x.toJSON())
 
         if self.args.format == "html":
             try:
@@ -85,7 +85,7 @@ class FlameGraphCLI:
                     output_str = f.read().replace("/** @flamegraph_json **/",
                                                   json_str)
             except IOError as e:
-                print(f"Error reading template file: {e}", file=sys.stderr)
+                print("Error reading template file: {}".format(e), file=sys.stderr)
                 sys.exit(1)
             output_fn = self.args.output or "flamegraph.html"
         else:
@@ -95,24 +95,22 @@ class FlameGraphCLI:
         if output_fn == "-":
             sys.stdout.write(output_str)
         else:
-            print(f"dumping data to {output_fn}")
+            print("dumping data to {}".format(output_fn))
             try:
                 with open(output_fn, "w") as out:
                     out.write(output_str)
             except IOError as e:
-                print(f"Error writing output file: {e}", file=sys.stderr)
+                print("Error writing output file: {}".format(e), file=sys.stderr)
                 sys.exit(1)
 
 
 if __name__ == "__main__":
     parser = argparse.ArgumentParser(description="Create flame graphs.")
-    parser.add_argument("-F", "--format",
+    parser.add_argument("-f", "--format",
                         default="html", choices=["json", "html"],
                         help="output file format")
     parser.add_argument("-o", "--output",
                         help="output file name")
-    parser.add_argument("--indent",
-                        type=int, help="JSON indentation")
     parser.add_argument("--template",
                         default="/usr/share/d3-flame-graph/d3-flamegraph-base.html",
                         help="path to flamegraph HTML template")
-- 
2.25.2


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

* Re: [PATCH] perf script: add flamegraph.py script
  2020-04-06 15:11 ` Arnaldo Carvalho de Melo
  2020-04-09 16:57   ` [PATCH] perf script flamegraph: python2 support, update cli args Andreas Gerstmayr
@ 2020-04-09 17:14   ` Andreas Gerstmayr
  1 sibling, 0 replies; 24+ messages in thread
From: Andreas Gerstmayr @ 2020-04-09 17:14 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: linux-perf-users, Martin Spier, Brendan Gregg, Peter Zijlstra,
	Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Namhyung Kim, linux-kernel

Hi Arnaldo,

thanks for merging!

On 06.04.20 17:11, Arnaldo Carvalho de Melo wrote:
> It works then, so I'll add a note to that effect. But please consider
> fixing it so that it works with both python2 and python3, if possible,
> or to fail gracefully and state that only python3 is supported and that
> perf should be built with "PYTHON=python3" on the make command line.

Ok, I just sent a patch (based on your perf/core branch) to add Python 2 
support. I hope soon Python 2 support won't be required anymore ;)

> Some RFEs for you to consider:
> 
> 1. make:
> 
>     perf flamegraph -a -F 99 sleep 1
 >
 > be equivalent, should be easy.

`perf flamegraph -a -F 99 sleep 1` should be equivalent to `perf script 
flamegraph -a -F 99 sleep 1`?
Or in other words, flamegraph should be a top-level command of perf, and 
run the flamegraph.py script?

> 2. make the command somehow create a new tab on an existing browser with
> the generated file, and switch the focus to that tab.

As a personal preference I don't like programs interfering with my 
browser session. For example I have a flame graph open in a tab, then I 
generate another one (overwriting the current file), I would not want 
another tab to open with the new flame graph, but instead I want to 
manually refresh the currently open tab.

> 3. get whats in:
> 
> [root@five ~]# perf report --header-only
> # ========
> # captured on    : Mon Apr  6 12:02:52 2020
> # header version : 1
> # data offset    : 336
> # data size      : 1173584
> # feat offset    : 1173920
> # hostname : five
> # os release : 5.5.10-200.fc31.x86_64
> # perf version : 5.6.gb6b7dc6ec0c8
> # arch : x86_64
> # nrcpus online : 12
> # nrcpus avail : 12
> # cpudesc : AMD Ryzen 5 3600X 6-Core Processor
> # cpuid : AuthenticAMD,23,113,0
> # total memory : 32890748 kB
> # cmdline : /home/acme/bin/perf record -a -g -F 99 sleep 1
> # event : name = cycles, , id = { 2918625, 2918626, 2918627, 2918628, 2918629, 2918630, 2918631, 2918632, 2918633, 2918634, 2918635, 2918636 }, size = 120, { sample_period, sample_freq } = 99, sample_type = IP|TID|TIME|CALLCHAIN|CPU|PERIOD, read_format = ID, disabled = 1,>
> # CPU_TOPOLOGY info available, use -I to display
> # NUMA_TOPOLOGY info available, use -I to display
> # pmu mappings: amd_df = 8, software = 1, ibs_op = 11, ibs_fetch = 10, uprobe = 7, cpu = 4, amd_iommu_0 = 12, breakpoint = 5, amd_l3 = 9, tracepoint = 2, kprobe = 6, msr = 13
> # CACHE info available, use -I to display
> # time of first sample : 87600.831767
> # time of last sample : 87601.096829
> # sample duration :    265.062 ms
> # MEM_TOPOLOGY info available, use -I to display
> # bpf_prog_info 40: bpf_prog_6deef7357e7b4530 addr 0xffffffffc030650c size 66
> # bpf_prog_info 41: bpf_prog_6deef7357e7b4530 addr 0xffffffffc03080e8 size 66
> # bpf_prog_info 42: bpf_prog_6deef7357e7b4530 addr 0xffffffffc030a218 size 66
> # bpf_prog_info 43: bpf_prog_6deef7357e7b4530 addr 0xffffffffc036c698 size 66
> # bpf_prog_info 44: bpf_prog_5a2b06eab81b8f51 addr 0xffffffffc036e2c0 size 1132
> # bpf_prog_info 45: bpf_prog_6deef7357e7b4530 addr 0xffffffffc06e7118 size 66
> # bpf_prog_info 46: bpf_prog_6deef7357e7b4530 addr 0xffffffffc06e9cd8 size 66
> # bpf_prog_info 47: bpf_prog_f3b9e166f6c1aaaa addr 0xffffffffc089732c size 1786
> # bpf_prog_info 48: bpf_prog_6deef7357e7b4530 addr 0xffffffffc0dcb64c size 66
> # bpf_prog_info 49: bpf_prog_6deef7357e7b4530 addr 0xffffffffc0dcd0fc size 66
> # bpf_prog_info 50: bpf_prog_6deef7357e7b4530 addr 0xffffffffc0f4d8dc size 66
> # bpf_prog_info 51: bpf_prog_6deef7357e7b4530 addr 0xffffffffc0f4fc7c size 66
> # bpf_prog_info 52: bpf_prog_84efc2eecc454ca6 addr 0xffffffffc0f6e584 size 373
> # missing features: TRACING_DATA BRANCH_STACK GROUP_DESC AUXTRACE STAT CLOCKID DIR_FORMAT COMPRESSED
> # ========
> #
> [root@five ~]#
> 
> And make it available in some UI element.

Good idea!
I'll implement this with the next set of flame graph template changes.


Thanks,
Andreas


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

* Re: [PATCH] perf script flamegraph: python2 support, update cli args
  2020-04-09 16:57   ` [PATCH] perf script flamegraph: python2 support, update cli args Andreas Gerstmayr
@ 2020-04-13 13:59     ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 24+ messages in thread
From: Arnaldo Carvalho de Melo @ 2020-04-13 13:59 UTC (permalink / raw)
  To: Andreas Gerstmayr
  Cc: linux-perf-users, Peter Zijlstra, Ingo Molnar, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Namhyung Kim, linux-kernel

Em Thu, Apr 09, 2020 at 06:57:31PM +0200, Andreas Gerstmayr escreveu:
> * removed --indent argument
> * renamed -F to -f argument to be consistent with other arguments

Ok, since I hadn't push the original patch, I've combined this one with
it it so that in systems with python2 it starts working and we can
bisect things from a good starting point.

- Arnaldo
 
> Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
> ---
>  tools/perf/scripts/python/flamegraph.py | 24 +++++++++++-------------
>  1 file changed, 11 insertions(+), 13 deletions(-)
> 
> diff --git a/tools/perf/scripts/python/flamegraph.py b/tools/perf/scripts/python/flamegraph.py
> index 5835d190ca42..61f3be9add6b 100755
> --- a/tools/perf/scripts/python/flamegraph.py
> +++ b/tools/perf/scripts/python/flamegraph.py
> @@ -14,6 +14,7 @@
>  # Flame Graphs invented by Brendan Gregg <bgregg@netflix.com>
>  # Works in tandem with d3-flame-graph by Martin Spier <mspier@netflix.com>
>  
> +from __future__ import print_function
>  import sys
>  import os
>  import argparse
> @@ -43,11 +44,11 @@ class FlameGraphCLI:
>  
>          if self.args.format == "html" and \
>                  not os.path.isfile(self.args.template):
> -            print(f"Flame Graph template {self.args.template} does not " +
> -                  f"exist. Please install the js-d3-flame-graph (RPM) or " +
> -                  f"libjs-d3-flame-graph (deb) package, specify an " +
> -                  f"existing flame graph template (--template PATH) or " +
> -                  f"another output format (--format FORMAT).",
> +            print("Flame Graph template {} does not exist. Please install "
> +                  "the js-d3-flame-graph (RPM) or libjs-d3-flame-graph (deb) "
> +                  "package, specify an existing flame graph template "
> +                  "(--template PATH) or another output format "
> +                  "(--format FORMAT).".format(self.args.template),
>                    file=sys.stderr)
>              sys.exit(1)
>  
> @@ -76,8 +77,7 @@ class FlameGraphCLI:
>          node.value += 1
>  
>      def trace_end(self):
> -        json_str = json.dumps(self.stack, default=lambda x: x.toJSON(),
> -                              indent=self.args.indent)
> +        json_str = json.dumps(self.stack, default=lambda x: x.toJSON())
>  
>          if self.args.format == "html":
>              try:
> @@ -85,7 +85,7 @@ class FlameGraphCLI:
>                      output_str = f.read().replace("/** @flamegraph_json **/",
>                                                    json_str)
>              except IOError as e:
> -                print(f"Error reading template file: {e}", file=sys.stderr)
> +                print("Error reading template file: {}".format(e), file=sys.stderr)
>                  sys.exit(1)
>              output_fn = self.args.output or "flamegraph.html"
>          else:
> @@ -95,24 +95,22 @@ class FlameGraphCLI:
>          if output_fn == "-":
>              sys.stdout.write(output_str)
>          else:
> -            print(f"dumping data to {output_fn}")
> +            print("dumping data to {}".format(output_fn))
>              try:
>                  with open(output_fn, "w") as out:
>                      out.write(output_str)
>              except IOError as e:
> -                print(f"Error writing output file: {e}", file=sys.stderr)
> +                print("Error writing output file: {}".format(e), file=sys.stderr)
>                  sys.exit(1)
>  
>  
>  if __name__ == "__main__":
>      parser = argparse.ArgumentParser(description="Create flame graphs.")
> -    parser.add_argument("-F", "--format",
> +    parser.add_argument("-f", "--format",
>                          default="html", choices=["json", "html"],
>                          help="output file format")
>      parser.add_argument("-o", "--output",
>                          help="output file name")
> -    parser.add_argument("--indent",
> -                        type=int, help="JSON indentation")
>      parser.add_argument("--template",
>                          default="/usr/share/d3-flame-graph/d3-flamegraph-base.html",
>                          help="path to flamegraph HTML template")
> -- 
> 2.25.2
> 

-- 

- Arnaldo

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

* [tip: perf/core] perf script: Add flamegraph.py script
  2020-03-20 15:13 [PATCH] perf script: add flamegraph.py script Andreas Gerstmayr
  2020-03-24 16:16 ` Kim Phillips
  2020-04-06 15:11 ` Arnaldo Carvalho de Melo
@ 2020-04-22 12:17 ` tip-bot2 for Andreas Gerstmayr
  2 siblings, 0 replies; 24+ messages in thread
From: tip-bot2 for Andreas Gerstmayr @ 2020-04-22 12:17 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Andreas Gerstmayr, Arnaldo Carvalho de Melo, Alexander Shishkin,
	Jiri Olsa, Mark Rutland, Namhyung Kim, Peter Zijlstra,
	Brendan Gregg, Martin Spier, x86, LKML

The following commit has been merged into the perf/core branch of tip:

Commit-ID:     5287f926920688e1151741d49da37a533ccf1960
Gitweb:        https://git.kernel.org/tip/5287f926920688e1151741d49da37a533ccf1960
Author:        Andreas Gerstmayr <agerstmayr@redhat.com>
AuthorDate:    Fri, 20 Mar 2020 16:13:48 +01:00
Committer:     Arnaldo Carvalho de Melo <acme@redhat.com>
CommitterDate: Thu, 16 Apr 2020 12:19:14 -03:00

perf script: Add flamegraph.py script

This script works in tandem with d3-flame-graph to generate flame graphs
from perf. It supports two output formats: JSON and HTML (the default).
The HTML format will look for a standalone d3-flame-graph template file
in /usr/share/d3-flame-graph/d3-flamegraph-base.html and fill in the
collected stacks.

Usage:

    perf record -a -g -F 99 sleep 60
    perf script report flamegraph

Combined:

    perf script flamegraph -a -F 99 sleep 60

Committer testing:

Tested both with "PYTHON=python3" and with the default, that uses
python2-devel:

Complete set of instructions:

  $ mkdir /tmp/build/perf
  $ make PYTHON=python3 -C tools/perf O=/tmp/build/perf install-bin
  $ export PATH=~/bin:$PATH
  $ perf record -a -g -F 99 sleep 60
  $ perf script report flamegraph

Now go and open the generated flamegraph.html file in a browser.

At first this required building with PYTHON=python3, but after I
reported this Andreas was kind enough to send a patch making it work
with both python and python3.

Signed-off-by: Andreas Gerstmayr <agerstmayr@redhat.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.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>
Cc: Brendan Gregg <bgregg@netflix.com>
Cc: Martin Spier <mspier@netflix.com>
Link: http://lore.kernel.org/lkml/20200320151355.66302-1-agerstmayr@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/scripts/python/bin/flamegraph-record |   2 +-
 tools/perf/scripts/python/bin/flamegraph-report |   3 +-
 tools/perf/scripts/python/flamegraph.py         | 124 +++++++++++++++-
 3 files changed, 129 insertions(+)
 create mode 100755 tools/perf/scripts/python/bin/flamegraph-record
 create mode 100755 tools/perf/scripts/python/bin/flamegraph-report
 create mode 100755 tools/perf/scripts/python/flamegraph.py

diff --git a/tools/perf/scripts/python/bin/flamegraph-record b/tools/perf/scripts/python/bin/flamegraph-record
new file mode 100755
index 0000000..725d66e
--- /dev/null
+++ b/tools/perf/scripts/python/bin/flamegraph-record
@@ -0,0 +1,2 @@
+#!/usr/bin/sh
+perf record -g "$@"
diff --git a/tools/perf/scripts/python/bin/flamegraph-report b/tools/perf/scripts/python/bin/flamegraph-report
new file mode 100755
index 0000000..b1a79af
--- /dev/null
+++ b/tools/perf/scripts/python/bin/flamegraph-report
@@ -0,0 +1,3 @@
+#!/usr/bin/sh
+# description: create flame graphs
+perf script -s "$PERF_EXEC_PATH"/scripts/python/flamegraph.py -- "$@"
diff --git a/tools/perf/scripts/python/flamegraph.py b/tools/perf/scripts/python/flamegraph.py
new file mode 100755
index 0000000..61f3be9
--- /dev/null
+++ b/tools/perf/scripts/python/flamegraph.py
@@ -0,0 +1,124 @@
+# flamegraph.py - create flame graphs from perf samples
+# SPDX-License-Identifier: GPL-2.0
+#
+# Usage:
+#
+#     perf record -a -g -F 99 sleep 60
+#     perf script report flamegraph
+#
+# Combined:
+#
+#     perf script flamegraph -a -F 99 sleep 60
+#
+# Written by Andreas Gerstmayr <agerstmayr@redhat.com>
+# Flame Graphs invented by Brendan Gregg <bgregg@netflix.com>
+# Works in tandem with d3-flame-graph by Martin Spier <mspier@netflix.com>
+
+from __future__ import print_function
+import sys
+import os
+import argparse
+import json
+
+
+class Node:
+    def __init__(self, name, libtype=""):
+        self.name = name
+        self.libtype = libtype
+        self.value = 0
+        self.children = []
+
+    def toJSON(self):
+        return {
+            "n": self.name,
+            "l": self.libtype,
+            "v": self.value,
+            "c": self.children
+        }
+
+
+class FlameGraphCLI:
+    def __init__(self, args):
+        self.args = args
+        self.stack = Node("root")
+
+        if self.args.format == "html" and \
+                not os.path.isfile(self.args.template):
+            print("Flame Graph template {} does not exist. Please install "
+                  "the js-d3-flame-graph (RPM) or libjs-d3-flame-graph (deb) "
+                  "package, specify an existing flame graph template "
+                  "(--template PATH) or another output format "
+                  "(--format FORMAT).".format(self.args.template),
+                  file=sys.stderr)
+            sys.exit(1)
+
+    def find_or_create_node(self, node, name, dso):
+        libtype = "kernel" if dso == "[kernel.kallsyms]" else ""
+        if name is None:
+            name = "[unknown]"
+
+        for child in node.children:
+            if child.name == name and child.libtype == libtype:
+                return child
+
+        child = Node(name, libtype)
+        node.children.append(child)
+        return child
+
+    def process_event(self, event):
+        node = self.find_or_create_node(self.stack, event["comm"], None)
+        if "callchain" in event:
+            for entry in reversed(event['callchain']):
+                node = self.find_or_create_node(
+                    node, entry.get("sym", {}).get("name"), event.get("dso"))
+        else:
+            node = self.find_or_create_node(
+                node, entry.get("symbol"), event.get("dso"))
+        node.value += 1
+
+    def trace_end(self):
+        json_str = json.dumps(self.stack, default=lambda x: x.toJSON())
+
+        if self.args.format == "html":
+            try:
+                with open(self.args.template) as f:
+                    output_str = f.read().replace("/** @flamegraph_json **/",
+                                                  json_str)
+            except IOError as e:
+                print("Error reading template file: {}".format(e), file=sys.stderr)
+                sys.exit(1)
+            output_fn = self.args.output or "flamegraph.html"
+        else:
+            output_str = json_str
+            output_fn = self.args.output or "stacks.json"
+
+        if output_fn == "-":
+            sys.stdout.write(output_str)
+        else:
+            print("dumping data to {}".format(output_fn))
+            try:
+                with open(output_fn, "w") as out:
+                    out.write(output_str)
+            except IOError as e:
+                print("Error writing output file: {}".format(e), file=sys.stderr)
+                sys.exit(1)
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description="Create flame graphs.")
+    parser.add_argument("-f", "--format",
+                        default="html", choices=["json", "html"],
+                        help="output file format")
+    parser.add_argument("-o", "--output",
+                        help="output file name")
+    parser.add_argument("--template",
+                        default="/usr/share/d3-flame-graph/d3-flamegraph-base.html",
+                        help="path to flamegraph HTML template")
+    parser.add_argument("-i", "--input",
+                        help=argparse.SUPPRESS)
+
+    args = parser.parse_args()
+    cli = FlameGraphCLI(args)
+
+    process_event = cli.process_event
+    trace_end = cli.trace_end

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

end of thread, other threads:[~2020-04-22 12:18 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-20 15:13 [PATCH] perf script: add flamegraph.py script Andreas Gerstmayr
2020-03-24 16:16 ` Kim Phillips
2020-03-24 19:05   ` Andreas Gerstmayr
2020-03-24 21:26     ` Arnaldo Melo
2020-03-26 19:04     ` Kim Phillips
2020-04-02 12:43       ` [PATCH] perf script: fix invalid read Andreas Gerstmayr
2020-04-02 15:15         ` Arnaldo Carvalho de Melo
2020-04-04  8:41         ` [tip: perf/urgent] perf script: Fix invalid read of directory entry after closedir() tip-bot2 for Andreas Gerstmayr
2020-04-02 12:54       ` [PATCH] perf script report: fix segfault when using DWARF mode Andreas Gerstmayr
2020-04-02 15:16         ` Arnaldo Carvalho de Melo
2020-04-02 19:07         ` Kim Phillips
2020-04-03 12:40           ` Arnaldo Carvalho de Melo
2020-04-03 13:16             ` Andreas Gerstmayr
2020-04-06  9:30               ` Andreas Gerstmayr
2020-04-06 12:59                 ` Arnaldo Carvalho de Melo
2020-04-06 14:28                   ` Kim Phillips
2020-04-04  8:41         ` [tip: perf/urgent] perf script report: Fix SEGFAULT " tip-bot2 for Andreas Gerstmayr
2020-04-02 13:04       ` [PATCH] perf script: add flamegraph.py script Andreas Gerstmayr
2020-04-06 14:27         ` Kim Phillips
2020-04-06 15:11 ` Arnaldo Carvalho de Melo
2020-04-09 16:57   ` [PATCH] perf script flamegraph: python2 support, update cli args Andreas Gerstmayr
2020-04-13 13:59     ` Arnaldo Carvalho de Melo
2020-04-09 17:14   ` [PATCH] perf script: add flamegraph.py script Andreas Gerstmayr
2020-04-22 12:17 ` [tip: perf/core] perf script: Add " tip-bot2 for Andreas Gerstmayr

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).