]> git.itanic.dy.fi Git - linux-stable/commitdiff
perf script: Fix Python support when no libtraceevent
authorAdrian Hunter <adrian.hunter@intel.com>
Wed, 15 Mar 2023 08:43:21 +0000 (10:43 +0200)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 15 Mar 2023 13:27:07 +0000 (10:27 -0300)
Python scripting can be used without libtraceevent. In particular,
scripting for Intel PT does not use tracepoints, and so does not need
libtraceevent support.

Alter the build and employ conditional compilation to allow Python
scripting without libtraceevent.

Example:

 Before:

    $ ldd `which perf` | grep -i python
    $ ldd `which perf` | grep -i libtraceevent
    $ perf record -e intel_pt//u uname
    Linux
    [ perf record: Woken up 1 times to write data ]
    [ perf record: Captured and wrote 0.031 MB perf.data ]
    $ perf script intel-pt-events.py |& head -3
      Error: Couldn't find script `intel-pt-events.py'

     See perf script -l for available scripts.

 After:

    $ ldd `which perf` | grep -i python
            libpython3.10.so.1.0 => /lib/x86_64-linux-gnu/libpython3.10.so.1.0 (0x00007f4bac400000)
    $ ldd `which perf` | grep -i libtraceevent
    $ perf script intel-pt-events.py | head
    Intel PT Branch Trace, Power Events, Event Trace and PTWRITE
         Switch In    8021/8021  [000]     11234.097713404     0/0
           perf-exec  8021/8021  [000]     11234.098041726       psb                        offset: 0x0                0 [unknown] ([unknown])
           perf-exec  8021/8021  [000]     11234.098041726       cbr                         45  freq: 4505 MHz  (161%)                0 [unknown] ([unknown])
               uname  8021/8021  [000]     11234.098082170  branches:uH  tr strt                              0 [unknown] ([unknown]) => 7f3a8b9422b0 _start+0x0 (/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2)
               uname  8021/8021  [000]     11234.098082379  branches:uH  tr end                    7f3a8b9422b0 _start+0x0 (/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2) => 0 [unknown] ([unknown])
               uname  8021/8021  [000]     11234.098083629  branches:uH  tr strt                              0 [unknown] ([unknown]) => 7f3a8b9422b0 _start+0x0 (/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2)
               uname  8021/8021  [000]     11234.098083629  branches:uH  call                      7f3a8b9422b3 _start+0x3 (/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2) => 7f3a8b943050 _dl_start+0x0 (/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2)
               uname  8021/8021  [000]     11234.098083837  branches:uH  tr end                    7f3a8b943060 _dl_start+0x10 (/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2) => 0 [unknown] ([unknown])  IPC: 0.01 (9/938)
               uname  8021/8021  [000]     11234.098084670  branches:uH  tr strt                              0 [unknown] ([unknown]) => 7f3a8b943060 _dl_start+0x10 (/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2)

Fixes: 378ef0f5d9d7f465 ("perf build: Use libtraceevent from the system")
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20230315084321.14563-1-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/Build
tools/perf/builtin-script.c
tools/perf/scripts/Build
tools/perf/scripts/python/Perf-Trace-Util/Build
tools/perf/scripts/python/Perf-Trace-Util/Context.c
tools/perf/util/Build
tools/perf/util/scripting-engines/Build
tools/perf/util/scripting-engines/trace-event-python.c
tools/perf/util/trace-event-scripting.c

index 6dd67e5022955ddf1b4b8310e4666ed0f0466ff7..aa762362283492b63a5d37abb674b766c49f5457 100644 (file)
@@ -56,6 +56,6 @@ CFLAGS_builtin-report.o          += -DDOCDIR="BUILD_STR($(srcdir_SQ)/Documentation)"
 perf-y += util/
 perf-y += arch/
 perf-y += ui/
-perf-$(CONFIG_LIBTRACEEVENT) += scripts/
+perf-y += scripts/
 
 gtk-y += ui/gtk/
index 522226114263ce59700add61cada489407140cca..976f8bfe099cabd7e8b0ea4c19293c2cbdbeaa09 100644 (file)
@@ -2313,8 +2313,8 @@ static void setup_scripting(void)
 {
 #ifdef HAVE_LIBTRACEEVENT
        setup_perl_scripting();
-       setup_python_scripting();
 #endif
+       setup_python_scripting();
 }
 
 static int flush_scripting(void)
index 68d4b54574adbbb452e553c4b9591ad361934997..7d8e2e57faac5cb5fd341eef8013cec69577f039 100644 (file)
@@ -1,2 +1,4 @@
-perf-$(CONFIG_LIBPERL)   += perl/Perf-Trace-Util/
+ifeq ($(CONFIG_LIBTRACEEVENT),y)
+  perf-$(CONFIG_LIBPERL)   += perl/Perf-Trace-Util/
+endif
 perf-$(CONFIG_LIBPYTHON) += python/Perf-Trace-Util/
index d5fed4e426179597609659a57aee807067f1cc09..7d0e33ce6aba44f4820252412b48b63d983e425d 100644 (file)
@@ -1,3 +1,3 @@
-perf-$(CONFIG_LIBTRACEEVENT) += Context.o
+perf-y += Context.o
 
 CFLAGS_Context.o += $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs
index 895f5fc2396536b7bf5ca00b9bd7330cc7522816..b0d449f41650ff7636129ec9e8ab1fe9254796fb 100644 (file)
@@ -59,6 +59,7 @@ static struct scripting_context *get_scripting_context(PyObject *args)
        return get_args(args, "context", NULL);
 }
 
+#ifdef HAVE_LIBTRACEEVENT
 static PyObject *perf_trace_context_common_pc(PyObject *obj, PyObject *args)
 {
        struct scripting_context *c = get_scripting_context(args);
@@ -90,6 +91,7 @@ static PyObject *perf_trace_context_common_lock_depth(PyObject *obj,
 
        return Py_BuildValue("i", common_lock_depth(c));
 }
+#endif
 
 static PyObject *perf_sample_insn(PyObject *obj, PyObject *args)
 {
@@ -178,12 +180,14 @@ static PyObject *perf_sample_srccode(PyObject *obj, PyObject *args)
 }
 
 static PyMethodDef ContextMethods[] = {
+#ifdef HAVE_LIBTRACEEVENT
        { "common_pc", perf_trace_context_common_pc, METH_VARARGS,
          "Get the common preempt count event field value."},
        { "common_flags", perf_trace_context_common_flags, METH_VARARGS,
          "Get the common flags event field value."},
        { "common_lock_depth", perf_trace_context_common_lock_depth,
          METH_VARARGS, "Get the common lock depth event field value."},
+#endif
        { "perf_sample_insn", perf_sample_insn,
          METH_VARARGS, "Get the machine code instruction."},
        { "perf_set_itrace_options", perf_set_itrace_options,
index 8607575183a99e744c9d415bf6957a498022b43e..0806bc0361ada869f71aae5943da7d2afd3eb417 100644 (file)
@@ -78,7 +78,7 @@ perf-y += pmu-bison.o
 perf-y += pmu-hybrid.o
 perf-y += svghelper.o
 perf-$(CONFIG_LIBTRACEEVENT) += trace-event-info.o
-perf-$(CONFIG_LIBTRACEEVENT) += trace-event-scripting.o
+perf-y += trace-event-scripting.o
 perf-$(CONFIG_LIBTRACEEVENT) += trace-event.o
 perf-$(CONFIG_LIBTRACEEVENT) += trace-event-parse.o
 perf-$(CONFIG_LIBTRACEEVENT) += trace-event-read.o
index 2c96aa3cc1ec83c02fa2265a987759742185a1fd..c220fec970324d85eeea1d3b45fe0d16be3ee340 100644 (file)
@@ -1,7 +1,7 @@
 ifeq ($(CONFIG_LIBTRACEEVENT),y)
   perf-$(CONFIG_LIBPERL)   += trace-event-perl.o
-  perf-$(CONFIG_LIBPYTHON) += trace-event-python.o
 endif
+perf-$(CONFIG_LIBPYTHON) += trace-event-python.o
 
 CFLAGS_trace-event-perl.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-nested-externs -Wno-undef -Wno-switch-default -Wno-bad-function-cast -Wno-declaration-after-statement -Wno-switch-enum
 
index 2c2697c5d02547c7ba8b21552e8e84971f0b5d5d..0f4ef61f2ffaefbf576a8320694783d7ec0d5bac 100644 (file)
@@ -30,7 +30,9 @@
 #include <linux/bitmap.h>
 #include <linux/compiler.h>
 #include <linux/time64.h>
+#ifdef HAVE_LIBTRACEEVENT
 #include <traceevent/event-parse.h>
+#endif
 
 #include "../build-id.h"
 #include "../counts.h"
@@ -87,18 +89,21 @@ PyMODINIT_FUNC initperf_trace_context(void);
 PyMODINIT_FUNC PyInit_perf_trace_context(void);
 #endif
 
+#ifdef HAVE_LIBTRACEEVENT
 #define TRACE_EVENT_TYPE_MAX                           \
        ((1 << (sizeof(unsigned short) * 8)) - 1)
 
 static DECLARE_BITMAP(events_defined, TRACE_EVENT_TYPE_MAX);
 
-#define MAX_FIELDS     64
 #define N_COMMON_FIELDS        7
 
-extern struct scripting_context *scripting_context;
-
 static char *cur_field_name;
 static int zero_flag_atom;
+#endif
+
+#define MAX_FIELDS     64
+
+extern struct scripting_context *scripting_context;
 
 static PyObject *main_module, *main_dict;
 
@@ -153,6 +158,26 @@ static PyObject *get_handler(const char *handler_name)
        return handler;
 }
 
+static void call_object(PyObject *handler, PyObject *args, const char *die_msg)
+{
+       PyObject *retval;
+
+       retval = PyObject_CallObject(handler, args);
+       if (retval == NULL)
+               handler_call_die(die_msg);
+       Py_DECREF(retval);
+}
+
+static void try_call_object(const char *handler_name, PyObject *args)
+{
+       PyObject *handler;
+
+       handler = get_handler(handler_name);
+       if (handler)
+               call_object(handler, args, handler_name);
+}
+
+#ifdef HAVE_LIBTRACEEVENT
 static int get_argument_count(PyObject *handler)
 {
        int arg_count = 0;
@@ -181,25 +206,6 @@ static int get_argument_count(PyObject *handler)
        return arg_count;
 }
 
-static void call_object(PyObject *handler, PyObject *args, const char *die_msg)
-{
-       PyObject *retval;
-
-       retval = PyObject_CallObject(handler, args);
-       if (retval == NULL)
-               handler_call_die(die_msg);
-       Py_DECREF(retval);
-}
-
-static void try_call_object(const char *handler_name, PyObject *args)
-{
-       PyObject *handler;
-
-       handler = get_handler(handler_name);
-       if (handler)
-               call_object(handler, args, handler_name);
-}
-
 static void define_value(enum tep_print_arg_type field_type,
                         const char *ev_name,
                         const char *field_name,
@@ -379,6 +385,7 @@ static PyObject *get_field_numeric_entry(struct tep_event *event,
                obj = list;
        return obj;
 }
+#endif
 
 static const char *get_dsoname(struct map *map)
 {
@@ -906,6 +913,7 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample,
        return dict;
 }
 
+#ifdef HAVE_LIBTRACEEVENT
 static void python_process_tracepoint(struct perf_sample *sample,
                                      struct evsel *evsel,
                                      struct addr_location *al,
@@ -1035,6 +1043,16 @@ static void python_process_tracepoint(struct perf_sample *sample,
 
        Py_DECREF(t);
 }
+#else
+static void python_process_tracepoint(struct perf_sample *sample __maybe_unused,
+                                     struct evsel *evsel __maybe_unused,
+                                     struct addr_location *al __maybe_unused,
+                                     struct addr_location *addr_al __maybe_unused)
+{
+       fprintf(stderr, "Tracepoint events are not supported because "
+                       "perf is not linked with libtraceevent.\n");
+}
+#endif
 
 static PyObject *tuple_new(unsigned int sz)
 {
@@ -1965,6 +1983,7 @@ static int python_stop_script(void)
        return 0;
 }
 
+#ifdef HAVE_LIBTRACEEVENT
 static int python_generate_script(struct tep_handle *pevent, const char *outfile)
 {
        int i, not_first, count, nr_events;
@@ -2155,6 +2174,18 @@ static int python_generate_script(struct tep_handle *pevent, const char *outfile
 
        return 0;
 }
+#else
+static int python_generate_script(struct tep_handle *pevent __maybe_unused,
+                                 const char *outfile __maybe_unused)
+{
+       fprintf(stderr, "Generating Python perf-script is not supported."
+               "  Install libtraceevent and rebuild perf to enable it.\n"
+               "For example:\n  # apt install libtraceevent-dev (ubuntu)"
+               "\n  # yum install libtraceevent-devel (Fedora)"
+               "\n  etc.\n");
+       return -1;
+}
+#endif
 
 struct scripting_ops python_scripting_ops = {
        .name                   = "Python",
index 56175c53f9af7f36ed9a9087b5e6981bfa0bcda5..bd0000300c774210b386d952340fdd312bb4f2c3 100644 (file)
@@ -9,7 +9,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#ifdef HAVE_LIBTRACEEVENT
 #include <traceevent/event-parse.h>
+#endif
 
 #include "debug.h"
 #include "trace-event.h"
@@ -27,10 +29,11 @@ void scripting_context__update(struct scripting_context *c,
                               struct addr_location *addr_al)
 {
        c->event_data = sample->raw_data;
+       c->pevent = NULL;
+#ifdef HAVE_LIBTRACEEVENT
        if (evsel->tp_format)
                c->pevent = evsel->tp_format->tep;
-       else
-               c->pevent = NULL;
+#endif
        c->event = event;
        c->sample = sample;
        c->evsel = evsel;
@@ -122,6 +125,7 @@ void setup_python_scripting(void)
 }
 #endif
 
+#ifdef HAVE_LIBTRACEEVENT
 static void print_perl_unsupported_msg(void)
 {
        fprintf(stderr, "Perl scripting not supported."
@@ -186,3 +190,4 @@ void setup_perl_scripting(void)
        register_perl_scripting(&perl_scripting_ops);
 }
 #endif
+#endif