From: Tom Zanussi <tzanussi@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: mingo@elte.hu, fweisbec@gmail.com, rostedt@goodmis.org,
lizf@cn.fujitsu.com, hch@infradead.org
Subject: [RFC][PATCH 6/9] perf trace: Add scripting op for generating empty event handling scripts
Date: Tue, 6 Oct 2009 01:09:55 -0500 [thread overview]
Message-ID: <1254809398-8078-7-git-send-email-tzanussi@gmail.com> (raw)
In-Reply-To: <1254809398-8078-1-git-send-email-tzanussi@gmail.com>
To give script writers an easy starting point for writing scripts,
scripting language support for a particular language can implement a
generate_event_handlers() scripting op that will output an empty (or
near-empty) set of handlers in the supported language for all the
events contained in a give perf.data trace file.
This patch adds the generate_event_handlers() scripting op and also
adds a Perl implementation that creates a ready-to-run Perl script
that can be passed to perf trace for generic event printing. Scripts
generated by this implementation print out all the fields for each
event (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: Tom Zanussi <tzanussi@gmail.com>
---
tools/perf/builtin-trace.c | 23 +++++++-
tools/perf/util/trace-event-perl.c | 114 ++++++++++++++++++++++++++++++++++++
tools/perf/util/trace-event.h | 1 +
3 files changed, 136 insertions(+), 2 deletions(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 74aec38..b151e77 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -30,6 +30,7 @@ static u64 sample_type;
static char const *script_name;
static int do_perl;
+static int generate_handlers;
static int default_start_script(const char *script __attribute((unused)))
{
@@ -41,10 +42,16 @@ static int default_stop_script(void)
return 0;
}
+static int default_generate_event_handlers(const char *outfile __attribute ((unused)))
+{
+ return 0;
+}
+
static struct trace_scripting_operations default_scripting_ops = {
.start_script = default_start_script,
.stop_script = default_stop_script,
.process_event = print_event,
+ .generate_event_handlers = default_generate_event_handlers,
};
static struct trace_scripting_operations *scripting_ops;
@@ -263,6 +270,8 @@ static const struct option options[] = {
"be more verbose (show symbol address, etc)"),
OPT_BOOLEAN('p', "perl", &do_perl,
"send output to a Perl script"),
+ OPT_BOOLEAN('g', "generate-event-handlers", &generate_handlers,
+ "generate empty event handlers for scripting languages"),
OPT_STRING('s', "script", &script_name, "file",
"script file name"),
OPT_END()
@@ -270,11 +279,14 @@ static const struct option options[] = {
static int setup_scripting(const char *script)
{
+ if (do_perl && generate_handlers)
+ goto setup;
+
if ((do_perl && !script) || (script && !do_perl))
usage_with_options(annotate_usage, options);
scripting_ops = &default_scripting_ops;
-
+setup:
if (do_perl) {
scripting_ops = setup_perl_scripting();
if (!scripting_ops)
@@ -312,9 +324,16 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
if (err)
goto out;
+ if (generate_handlers) {
+ trace_report();
+ err = scripting_ops->generate_event_handlers("perf-trace.pl");
+ goto out;
+ }
+
if (script_name) {
err = scripting_ops->start_script(script_name);
- goto out;
+ if (err)
+ goto out;
}
err = __cmd_trace();
diff --git a/tools/perf/util/trace-event-perl.c b/tools/perf/util/trace-event-perl.c
index 1264e14..657b87a 100644
--- a/tools/perf/util/trace-event-perl.c
+++ b/tools/perf/util/trace-event-perl.c
@@ -356,10 +356,124 @@ static int perl_stop_script(void)
return 0;
}
+static int perl_generate_event_handlers(const char *outfile)
+{
+ struct event *event = NULL;
+ struct format_field *f;
+ int not_first;
+ FILE *ofp;
+
+ ofp = fopen(outfile, "w");
+ if (ofp == NULL) {
+ fprintf(stderr, "couldn't open %s\n", outfile);
+ return -1;
+ }
+
+ fprintf(ofp, "# perf trace event handlers, "
+ "generated by perf trace -p -g\n\n");
+
+ fprintf(ofp, "# The common_* event handler fields are the most useful "
+ "fields common to\n");
+
+ fprintf(ofp, "# all events. They don't necessarily correspond to "
+ "the 'common_*' fields\n");
+
+ fprintf(ofp, "# in the status files. Those fields not available as "
+ "handler params can\n");
+
+ fprintf(ofp, "# be retrieved via script functions of the form "
+ "get_common_*().\n\n");
+
+ fprintf(ofp, "use lib \"$ENV{'PERF_EXEC_PATH'}/scripts/perl/"
+ "Perf-Trace-Util/lib\";\n");
+
+ fprintf(ofp, "use lib \"./Perf-Trace-Util/lib\";\n");
+ fprintf(ofp, "use Perf::Trace::Core;\n");
+ fprintf(ofp, "use Perf::Trace::Util;\n\n");
+
+ fprintf(ofp, "sub trace_begin\n{\n # optional\n}\n\n");
+ fprintf(ofp, "sub trace_end\n{\n # optional\n}\n\n");
+
+ while ((event = trace_find_next_event(event))) {
+ fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
+ fprintf(ofp, " my (");
+
+ fprintf(ofp, "$event_name, ");
+ fprintf(ofp, "$common_cpu, ");
+ fprintf(ofp, "$common_secs, ");
+ fprintf(ofp, "$common_nsecs, ");
+ fprintf(ofp, "$common_pid, ");
+ fprintf(ofp, "$common_comm,\n ");
+
+ not_first = 0;
+
+ for (f = event->format.fields; f; f = f->next) {
+ if (not_first++)
+ fprintf(ofp, ", ");
+
+ fprintf(ofp, "$%s", f->name);
+ }
+ fprintf(ofp, ") = @_;\n\n");
+
+ fprintf(ofp, " print_header($event_name, $common_cpu, "
+ "$common_secs, $common_nsecs, $common_pid, "
+ "$common_comm);\n\n");
+
+ fprintf(ofp, " printf(\"");
+
+ not_first = 0;
+
+ for (f = event->format.fields; f; f = f->next) {
+ if (not_first++)
+ fprintf(ofp, ", ");
+
+ fprintf(ofp, "%s=", f->name);
+ if (f->flags & FIELD_IS_STRING)
+ fprintf(ofp, "%%s");
+ else if (f->flags & FIELD_IS_SIGNED)
+ fprintf(ofp, "%%d");
+ else
+ fprintf(ofp, "%%u");
+ }
+
+ fprintf(ofp, "\\n\", ");
+
+ not_first = 0;
+
+ for (f = event->format.fields; f; f = f->next) {
+ if (not_first++)
+ fprintf(ofp, ", ");
+
+ fprintf(ofp, "$%s", f->name);
+ }
+
+ fprintf(ofp, ");\n");
+ fprintf(ofp, "}\n\n");
+ }
+
+ fprintf(ofp, "sub trace_unhandled\n{\n my ($event_name, "
+ "$common_cpu, $common_secs, $common_nsecs, $common_pid, "
+ "$common_comm) = @_;\n\n");
+
+ fprintf(ofp, " print_header($event_name, $common_cpu, "
+ "$common_secs, $common_nsecs, $common_pid, "
+ "$common_comm);\n}\n\n");
+
+ fprintf(ofp, "sub print_header\n{\n"
+ " my ($event_name, $cpu, $secs, $nsecs, $pid, $comm) = @_;\n\n"
+ " printf(\"%%-20s %%5u %%05u.%%09u %%8u %%-20s \", "
+ "$event_name, $cpu, $secs, $nsecs, $pid, $comm);\n}");
+
+ fclose(ofp);
+
+ return 0;
+}
+
struct trace_scripting_operations perl_scripting_ops = {
.start_script = perl_start_script,
.stop_script = perl_stop_script,
.process_event = perl_process_event,
+ .generate_event_handlers = perl_generate_event_handlers,
};
#ifdef NO_LIBPERL
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index f812a8e..582e0eb 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -255,6 +255,7 @@ struct trace_scripting_operations {
int (*stop_script) (void);
void (*process_event) (int cpu, void *data, int size,
unsigned long long nsecs, char *comm);
+ int (*generate_event_handlers) (const char *outfile);
};
extern struct trace_scripting_operations perl_scripting_ops;
--
1.6.4.GIT
next prev parent reply other threads:[~2009-10-06 6:10 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-06 6:09 [RFC][PATCH 0/9] perf trace: support for general-purpose scripting Tom Zanussi
2009-10-06 6:09 ` [RFC][PATCH 1/9] tracing/events: Add 'signed' field to format files Tom Zanussi
2009-10-06 13:06 ` [tip:perf/core] " tip-bot for Tom Zanussi
2009-10-06 15:05 ` Frederic Weisbecker
2009-10-07 4:30 ` Tom Zanussi
2009-10-07 1:06 ` [RFC][PATCH 1/9] " Steven Rostedt
2009-10-07 5:04 ` Tom Zanussi
2009-10-07 13:07 ` Steven Rostedt
2009-10-11 9:00 ` Ingo Molnar
2009-10-06 6:09 ` [RFC][PATCH 2/9] perf trace: Add subsystem string to struct event Tom Zanussi
2009-10-06 13:06 ` [tip:perf/core] " tip-bot for Tom Zanussi
2009-10-06 6:09 ` [RFC][PATCH 3/9] perf trace: Add string/dynamic cases to format_flags Tom Zanussi
2009-10-06 13:07 ` [tip:perf/core] " tip-bot for Tom Zanussi
2009-10-06 6:09 ` [RFC][PATCH 4/9] perf trace: Add trace scripting ops Tom Zanussi
2009-10-06 6:09 ` [RFC][PATCH 5/9] perf trace: Add Perl scripting support Tom Zanussi
2009-10-06 13:00 ` Ingo Molnar
2009-10-07 4:09 ` Tom Zanussi
2009-10-07 14:13 ` Christoph Hellwig
2009-10-08 4:01 ` Tom Zanussi
2009-10-11 8:58 ` Ingo Molnar
2009-10-11 12:16 ` Frederic Weisbecker
2009-10-12 6:03 ` Ingo Molnar
2009-10-06 6:09 ` Tom Zanussi [this message]
2009-10-06 6:09 ` [RFC][PATCH 7/9] perf trace: Add FIELD_IS_FLAG/SYMBOLIC cases to format_flags Tom Zanussi
2009-10-06 6:09 ` [RFC][PATCH 8/9] perf trace: Add perf trace scripting support modules for Perl Tom Zanussi
2009-10-06 12:39 ` Ingo Molnar
2009-10-07 4:02 ` Tom Zanussi
2009-10-06 12:45 ` Ingo Molnar
2009-10-07 4:05 ` Tom Zanussi
2009-10-06 6:09 ` [RFC][PATCH 9/9] perf trace: Add throwaway timestamp sorting Tom Zanussi
2009-10-06 9:09 ` [RFC][PATCH 0/9] perf trace: support for general-purpose scripting Ingo Molnar
2009-10-06 13:25 ` Peter Zijlstra
2009-10-06 13:53 ` Ingo Molnar
2009-10-07 4:01 ` Tom Zanussi
2009-10-06 9:40 ` Frédéric Weisbecker
2009-10-06 12:54 ` Ingo Molnar
2009-10-06 13:09 ` Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1254809398-8078-7-git-send-email-tzanussi@gmail.com \
--to=tzanussi@gmail.com \
--cc=fweisbec@gmail.com \
--cc=hch@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lizf@cn.fujitsu.com \
--cc=mingo@elte.hu \
--cc=rostedt@goodmis.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®