From: Adrian Hunter <adrian.hunter@xxxxxxxxx> [ Upstream commit 80c3a7d9f20401169283b5670dbb8d7ac07a1d55 ] 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@xxxxxxxxx> Cc: Ian Rogers <irogers@xxxxxxxxxx> Cc: Jiri Olsa <jolsa@xxxxxxxxxx> Cc: Namhyung Kim <namhyung@xxxxxxxxxx> Link: https://lore.kernel.org/r/20230315084321.14563-1-adrian.hunter@xxxxxxxxx Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> --- tools/perf/Build | 2 +- tools/perf/builtin-script.c | 2 +- tools/perf/scripts/Build | 4 +- .../perf/scripts/python/Perf-Trace-Util/Build | 2 +- .../scripts/python/Perf-Trace-Util/Context.c | 4 + tools/perf/util/Build | 2 +- tools/perf/util/scripting-engines/Build | 2 +- .../scripting-engines/trace-event-python.c | 75 +++++++++++++------ tools/perf/util/trace-event-scripting.c | 9 ++- 9 files changed, 72 insertions(+), 30 deletions(-) diff --git a/tools/perf/Build b/tools/perf/Build index 6dd67e5022955..aa76236228349 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -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/ diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index a792214d1af85..6f085602b7bd3 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -2318,8 +2318,8 @@ static void setup_scripting(void) { #ifdef HAVE_LIBTRACEEVENT setup_perl_scripting(); - setup_python_scripting(); #endif + setup_python_scripting(); } static int flush_scripting(void) diff --git a/tools/perf/scripts/Build b/tools/perf/scripts/Build index 68d4b54574adb..7d8e2e57faac5 100644 --- a/tools/perf/scripts/Build +++ b/tools/perf/scripts/Build @@ -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/ diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Build b/tools/perf/scripts/python/Perf-Trace-Util/Build index d5fed4e426179..7d0e33ce6aba4 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/Build +++ b/tools/perf/scripts/python/Perf-Trace-Util/Build @@ -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 diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Context.c b/tools/perf/scripts/python/Perf-Trace-Util/Context.c index 895f5fc239653..b0d449f41650f 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/Context.c +++ b/tools/perf/scripts/python/Perf-Trace-Util/Context.c @@ -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, diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 918b501f9bd8b..4868e3bf7df96 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -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 diff --git a/tools/perf/util/scripting-engines/Build b/tools/perf/util/scripting-engines/Build index 2c96aa3cc1ec8..c220fec970324 100644 --- a/tools/perf/util/scripting-engines/Build +++ b/tools/perf/util/scripting-engines/Build @@ -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 diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 2c2697c5d0254..0f4ef61f2ffae 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -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", diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 56175c53f9af7..bd0000300c774 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c @@ -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 -- 2.39.2