Commit 80c3a7d9 authored by Adrian Hunter's avatar Adrian Hunter Committed by Arnaldo Carvalho de Melo

perf script: Fix Python support when no libtraceevent

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: 378ef0f5 ("perf build: Use libtraceevent from the system")
Signed-off-by: default avatarAdrian 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.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 4c290d4f
......@@ -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/
......@@ -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)
......
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/
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
......@@ -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,
......
......@@ -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
......
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
......
......@@ -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",
......
......@@ -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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment