]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
perf script: Allow the generated script to be a path
authorIan Rogers <irogers@google.com>
Mon, 9 Feb 2026 20:22:06 +0000 (12:22 -0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 12 Feb 2026 20:45:22 +0000 (17:45 -0300)
Allow the script generated by "perf script -g <language>" to be a file
path and the language determined by the file extension.

This is useful in testing so that the generated script file can be
written to a test directory.

Committer testing:

  $ perf record ls a.a
  ls: cannot access 'a.a': No such file or directory
  [ perf record: Woken up 2 times to write data ]
  [ perf record: Captured and wrote 0.003 MB perf.data (7 samples) ]
  $ perf script -g python
  generated Python script: perf-script.py
  $ perf script -g myscript.py
  generated Python script: myscript.py
  $ diff -u perf-script.py myscript.py
  $ tail myscript.py
  def trace_unhandled(event_name, context, event_fields_dict, perf_sample_dict):
   print(get_dict_as_string(event_fields_dict))
   print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

  def print_header(event_name, cpu, secs, nsecs, pid, comm):
   print("%-20s %5u %05u.%09u %8u %-20s " % \
   (event_name, cpu, secs, nsecs, pid, comm), end="")

  def get_dict_as_string(a_dict, delimiter=' '):
   return delimiter.join(['%s=%s'%(k,str(v))for k,v in sorted(a_dict.items())])
  $

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Leo Yan <leo.yan@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Yujie Liu <yujie.liu@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/Documentation/perf-script.txt
tools/perf/builtin-script.c

index 03d1129606328d6d1f07d8298386f8cce3e5fa5a..ddf92f9c78212974c15d859a6e3e46e8875a8c2b 100644 (file)
@@ -98,8 +98,10 @@ OPTIONS
 
 -g::
 --gen-script=::
-        Generate perf-script.[ext] starter script for given language,
-        using current perf.data.
+       Generate a starter script. If a language is given then the
+        script is named perf-script.[ext] according to the
+        language. If a file path is given then python is used for
+        files ending '.py' and perl used for files ending '.pl'.
 
 --dlfilter=<file>::
        Filter sample events using the given shared object file.
index 14c6f6c3c4f2f79a44b393be8e32ec9b17d44848..7c743a303507fc6e16908247dc9a9dffa326b995 100644 (file)
@@ -4489,6 +4489,7 @@ script_found:
        if (generate_script_lang) {
                struct stat perf_stat;
                int input;
+               char *filename = strdup("perf-script");
 
                if (output_set_by_user()) {
                        fprintf(stderr,
@@ -4516,17 +4517,32 @@ script_found:
                }
 
                scripting_ops = script_spec__lookup(generate_script_lang);
+               if (!scripting_ops && ends_with(generate_script_lang, ".py")) {
+                       scripting_ops = script_spec__lookup("python");
+                       free(filename);
+                       filename = strdup(generate_script_lang);
+                       filename[strlen(filename) - 3] = '\0';
+               } else if (!scripting_ops && ends_with(generate_script_lang, ".pl")) {
+                       scripting_ops = script_spec__lookup("perl");
+                       free(filename);
+                       filename = strdup(generate_script_lang);
+                       filename[strlen(filename) - 3] = '\0';
+               }
                if (!scripting_ops) {
-                       fprintf(stderr, "invalid language specifier");
+                       fprintf(stderr, "invalid language specifier '%s'\n", generate_script_lang);
                        err = -ENOENT;
                        goto out_delete;
                }
+               if (!filename) {
+                       err = -ENOMEM;
+                       goto out_delete;
+               }
 #ifdef HAVE_LIBTRACEEVENT
-               err = scripting_ops->generate_script(session->tevent.pevent,
-                                                    "perf-script");
+               err = scripting_ops->generate_script(session->tevent.pevent, filename);
 #else
-               err = scripting_ops->generate_script(NULL, "perf-script");
+               err = scripting_ops->generate_script(NULL, filename);
 #endif
+               free(filename);
                goto out_delete;
        }