mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 16:29:59 +00:00
![Adrian Hunter](/assets/img/avatar_default.png)
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: 378ef0f5d9
("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>
193 lines
4.8 KiB
C
193 lines
4.8 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* trace-event-scripting. Scripting engine common and initialization code.
|
|
*
|
|
* Copyright (C) 2009-2010 Tom Zanussi <tzanussi@gmail.com>
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#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"
|
|
#include "evsel.h"
|
|
#include <linux/zalloc.h>
|
|
#include "util/sample.h"
|
|
|
|
struct scripting_context *scripting_context;
|
|
|
|
void scripting_context__update(struct scripting_context *c,
|
|
union perf_event *event,
|
|
struct perf_sample *sample,
|
|
struct evsel *evsel,
|
|
struct addr_location *al,
|
|
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;
|
|
#endif
|
|
c->event = event;
|
|
c->sample = sample;
|
|
c->evsel = evsel;
|
|
c->al = al;
|
|
c->addr_al = addr_al;
|
|
}
|
|
|
|
static int flush_script_unsupported(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int stop_script_unsupported(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static void process_event_unsupported(union perf_event *event __maybe_unused,
|
|
struct perf_sample *sample __maybe_unused,
|
|
struct evsel *evsel __maybe_unused,
|
|
struct addr_location *al __maybe_unused,
|
|
struct addr_location *addr_al __maybe_unused)
|
|
{
|
|
}
|
|
|
|
static void print_python_unsupported_msg(void)
|
|
{
|
|
fprintf(stderr, "Python scripting not supported."
|
|
" Install libpython and rebuild perf to enable it.\n"
|
|
"For example:\n # apt-get install python-dev (ubuntu)"
|
|
"\n # yum install python-devel (Fedora)"
|
|
"\n etc.\n");
|
|
}
|
|
|
|
static int python_start_script_unsupported(const char *script __maybe_unused,
|
|
int argc __maybe_unused,
|
|
const char **argv __maybe_unused,
|
|
struct perf_session *session __maybe_unused)
|
|
{
|
|
print_python_unsupported_msg();
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int python_generate_script_unsupported(struct tep_handle *pevent
|
|
__maybe_unused,
|
|
const char *outfile
|
|
__maybe_unused)
|
|
{
|
|
print_python_unsupported_msg();
|
|
|
|
return -1;
|
|
}
|
|
|
|
struct scripting_ops python_scripting_unsupported_ops = {
|
|
.name = "Python",
|
|
.dirname = "python",
|
|
.start_script = python_start_script_unsupported,
|
|
.flush_script = flush_script_unsupported,
|
|
.stop_script = stop_script_unsupported,
|
|
.process_event = process_event_unsupported,
|
|
.generate_script = python_generate_script_unsupported,
|
|
};
|
|
|
|
static void register_python_scripting(struct scripting_ops *scripting_ops)
|
|
{
|
|
if (scripting_context == NULL)
|
|
scripting_context = malloc(sizeof(*scripting_context));
|
|
|
|
if (scripting_context == NULL ||
|
|
script_spec_register("Python", scripting_ops) ||
|
|
script_spec_register("py", scripting_ops)) {
|
|
pr_err("Error registering Python script extension: disabling it\n");
|
|
zfree(&scripting_context);
|
|
}
|
|
}
|
|
|
|
#ifndef HAVE_LIBPYTHON_SUPPORT
|
|
void setup_python_scripting(void)
|
|
{
|
|
register_python_scripting(&python_scripting_unsupported_ops);
|
|
}
|
|
#else
|
|
extern struct scripting_ops python_scripting_ops;
|
|
|
|
void setup_python_scripting(void)
|
|
{
|
|
register_python_scripting(&python_scripting_ops);
|
|
}
|
|
#endif
|
|
|
|
#ifdef HAVE_LIBTRACEEVENT
|
|
static void print_perl_unsupported_msg(void)
|
|
{
|
|
fprintf(stderr, "Perl scripting not supported."
|
|
" Install libperl and rebuild perf to enable it.\n"
|
|
"For example:\n # apt-get install libperl-dev (ubuntu)"
|
|
"\n # yum install 'perl(ExtUtils::Embed)' (Fedora)"
|
|
"\n etc.\n");
|
|
}
|
|
|
|
static int perl_start_script_unsupported(const char *script __maybe_unused,
|
|
int argc __maybe_unused,
|
|
const char **argv __maybe_unused,
|
|
struct perf_session *session __maybe_unused)
|
|
{
|
|
print_perl_unsupported_msg();
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int perl_generate_script_unsupported(struct tep_handle *pevent
|
|
__maybe_unused,
|
|
const char *outfile __maybe_unused)
|
|
{
|
|
print_perl_unsupported_msg();
|
|
|
|
return -1;
|
|
}
|
|
|
|
struct scripting_ops perl_scripting_unsupported_ops = {
|
|
.name = "Perl",
|
|
.dirname = "perl",
|
|
.start_script = perl_start_script_unsupported,
|
|
.flush_script = flush_script_unsupported,
|
|
.stop_script = stop_script_unsupported,
|
|
.process_event = process_event_unsupported,
|
|
.generate_script = perl_generate_script_unsupported,
|
|
};
|
|
|
|
static void register_perl_scripting(struct scripting_ops *scripting_ops)
|
|
{
|
|
if (scripting_context == NULL)
|
|
scripting_context = malloc(sizeof(*scripting_context));
|
|
|
|
if (scripting_context == NULL ||
|
|
script_spec_register("Perl", scripting_ops) ||
|
|
script_spec_register("pl", scripting_ops)) {
|
|
pr_err("Error registering Perl script extension: disabling it\n");
|
|
zfree(&scripting_context);
|
|
}
|
|
}
|
|
|
|
#ifndef HAVE_LIBPERL_SUPPORT
|
|
void setup_perl_scripting(void)
|
|
{
|
|
register_perl_scripting(&perl_scripting_unsupported_ops);
|
|
}
|
|
#else
|
|
extern struct scripting_ops perl_scripting_ops;
|
|
|
|
void setup_perl_scripting(void)
|
|
{
|
|
register_perl_scripting(&perl_scripting_ops);
|
|
}
|
|
#endif
|
|
#endif
|