Skip to content

Commit

Permalink
perf script: Fix Python support when no libtraceevent
Browse files Browse the repository at this point in the history
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: 378ef0f ("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>
  • Loading branch information
Adrian Hunter authored and Arnaldo Carvalho de Melo committed Mar 15, 2023
1 parent 4c290d4 commit 80c3a7d
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 30 deletions.
2 changes: 1 addition & 1 deletion tools/perf/Build
Original file line number Diff line number Diff line change
Expand Up @@ -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/
2 changes: 1 addition & 1 deletion tools/perf/builtin-script.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion tools/perf/scripts/Build
Original file line number Diff line number Diff line change
@@ -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/
2 changes: 1 addition & 1 deletion tools/perf/scripts/python/Perf-Trace-Util/Build
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions tools/perf/scripts/python/Perf-Trace-Util/Context.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/Build
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/scripting-engines/Build
Original file line number Diff line number Diff line change
@@ -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

Expand Down
75 changes: 53 additions & 22 deletions tools/perf/util/scripting-engines/trace-event-python.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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",
Expand Down
9 changes: 7 additions & 2 deletions tools/perf/util/trace-event-scripting.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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;
Expand Down Expand Up @@ -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."
Expand Down Expand Up @@ -186,3 +190,4 @@ void setup_perl_scripting(void)
register_perl_scripting(&perl_scripting_ops);
}
#endif
#endif

0 comments on commit 80c3a7d

Please sign in to comment.