Commit 16c632de authored by Tom Zanussi's avatar Tom Zanussi Committed by Ingo Molnar

perf trace: Add Perl scripting support

Implement trace_scripting_ops to make Perl a supported perf
trace scripting language.

Additionally adds code that allows Perl trace scripts to access
the 'flag' and 'symbolic' (__print_flags(), __print_symbolic())
field information parsed from the trace format files.

Also adds the Perl implementation of the generate_script()
trace_scripting_op, which creates a ready-to-run perf trace Perl
script based on existing trace data.  Scripts generated by this
implementation print out all the fields for each event mentioned
in perf.data (and will detect and generate the proper scripting
code for 'flag' and 'symbolic' fields), and will additionally
generate handlers for the special 'trace_unhandled',
'trace_begin' and 'trace_end' handlers.  Script authors can
simply remove the printing code to implement their own custom
event handling.
Signed-off-by: default avatarTom Zanussi <tzanussi@gmail.com>
Cc: fweisbec@gmail.com
Cc: rostedt@goodmis.org
Cc: anton@samba.org
Cc: hch@infradead.org
LKML-Reference: <1259133352-23685-4-git-send-email-tzanussi@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent eb9a42ca
......@@ -407,6 +407,7 @@ LIB_OBJS += util/thread.o
LIB_OBJS += util/trace-event-parse.o
LIB_OBJS += util/trace-event-read.o
LIB_OBJS += util/trace-event-info.o
LIB_OBJS += util/trace-event-perl.o
LIB_OBJS += util/svghelper.o
LIB_OBJS += util/sort.o
LIB_OBJS += util/hist.o
......@@ -489,6 +490,15 @@ else
LIB_OBJS += util/probe-finder.o
endif
PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts`
PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts`
ifneq ($(shell sh -c "(echo '\#include <EXTERN.h>'; echo '\#include <perl.h>'; echo 'int main(void) { perl_alloc(); return 0; }') | $(CC) -x c - $(PERL_EMBED_CCOPTS) -o /dev/null $(PERL_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y)
BASIC_CFLAGS += -DNO_LIBPERL
else
ALL_LDFLAGS += $(PERL_EMBED_LDOPTS)
endif
ifdef NO_DEMANGLE
BASIC_CFLAGS += -DNO_DEMANGLE
else
......@@ -860,6 +870,9 @@ util/hweight.o: ../../lib/hweight.c PERF-CFLAGS
util/find_next_bit.o: ../../lib/find_next_bit.c PERF-CFLAGS
$(QUIET_CC)$(CC) -o util/find_next_bit.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
util/trace-event-perl.o: util/trace-event-perl.c PERF-CFLAGS
$(QUIET_CC)$(CC) -o util/trace-event-perl.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter $<
perf-%$X: %.o $(PERFLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
......
......@@ -38,6 +38,8 @@ static void setup_scripting(void)
/* make sure PERF_EXEC_PATH is set for scripts */
perf_set_argv_exec_path(perf_exec_path());
setup_perl_scripting();
scripting_ops = &default_scripting_ops;
}
......
......@@ -1888,7 +1888,7 @@ find_any_field(struct event *event, const char *name)
return find_field(event, name);
}
static unsigned long long read_size(void *ptr, int size)
unsigned long long read_size(void *ptr, int size)
{
switch (size) {
case 1:
......@@ -1973,7 +1973,7 @@ int trace_parse_common_type(void *data)
"common_type");
}
static int parse_common_pid(void *data)
int trace_parse_common_pid(void *data)
{
static int pid_offset;
static int pid_size;
......@@ -2025,6 +2025,14 @@ struct event *trace_find_event(int id)
return event;
}
struct event *trace_find_next_event(struct event *event)
{
if (!event)
return event_list;
return event->next;
}
static unsigned long long eval_num_arg(void *data, int size,
struct event *event, struct print_arg *arg)
{
......@@ -2164,7 +2172,7 @@ static const struct flag flags[] = {
{ "HRTIMER_RESTART", 1 },
};
static unsigned long long eval_flag(const char *flag)
unsigned long long eval_flag(const char *flag)
{
int i;
......@@ -2694,7 +2702,7 @@ get_return_for_leaf(int cpu, int cur_pid, unsigned long long cur_func,
if (!(event->flags & EVENT_FL_ISFUNCRET))
return NULL;
pid = parse_common_pid(next->data);
pid = trace_parse_common_pid(next->data);
field = find_field(event, "func");
if (!field)
die("function return does not have field func");
......@@ -2980,7 +2988,7 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs,
return;
}
pid = parse_common_pid(data);
pid = trace_parse_common_pid(data);
if (event->flags & (EVENT_FL_ISFUNCENT | EVENT_FL_ISFUNCRET))
return pretty_print_func_graph(data, size, event, cpu,
......
This diff is collapsed.
#ifndef __PERF_TRACE_EVENT_PERL_H
#define __PERF_TRACE_EVENT_PERL_H
#ifdef NO_LIBPERL
typedef int INTERP;
#define dSP
#define ENTER
#define SAVETMPS
#define PUTBACK
#define SPAGAIN
#define FREETMPS
#define LEAVE
#define SP
#define ERRSV
#define G_SCALAR (0)
#define G_DISCARD (0)
#define G_NOARGS (0)
#define PUSHMARK(a)
#define SvTRUE(a) (0)
#define XPUSHs(s)
#define sv_2mortal(a)
#define newSVpv(a,b)
#define newSVuv(a)
#define newSViv(a)
#define get_cv(a,b) (0)
#define call_pv(a,b) (0)
#define perl_alloc() (0)
#define perl_construct(a) (0)
#define perl_parse(a,b,c,d,e) (0)
#define perl_run(a) (0)
#define perl_destruct(a) (0)
#define perl_free(a) (0)
#else
#include <EXTERN.h>
#include <perl.h>
typedef PerlInterpreter * INTERP;
#endif
struct scripting_context {
void *event_data;
};
#endif /* __PERF_TRACE_EVENT_PERL_H */
......@@ -245,10 +245,14 @@ extern int latency_format;
int parse_header_page(char *buf, unsigned long size);
int trace_parse_common_type(void *data);
int trace_parse_common_pid(void *data);
struct event *trace_find_event(int id);
struct event *trace_find_next_event(struct event *event);
unsigned long long read_size(void *ptr, int size);
unsigned long long
raw_field_value(struct event *event, const char *name, void *data);
void *raw_field_ptr(struct event *event, const char *name, void *data);
unsigned long long eval_flag(const char *flag);
int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events);
......@@ -272,4 +276,7 @@ struct scripting_ops {
int script_spec_register(const char *spec, struct scripting_ops *ops);
extern struct scripting_ops perl_scripting_ops;
void setup_perl_scripting(void);
#endif /* __PERF_TRACE_EVENTS_H */
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