perf trace/scripting: Add support for script args

One oversight of the original scripting_ops patch was a lack of
support for passing args to handler scripts.  This adds
argc/argv to the start_script() scripting_op, and changes the
rw-by-file script to take 'comm' arg rather than the 'perf'
value currently hard-coded.  It also takes the opportunity to do
some related minor cleanup.

Signed-off-by: Tom Zanussi <tzanussi@gmail.com>
Cc: fweisbec@gmail.com
Cc: rostedt@goodmis.org
LKML-Reference: <1260867220-15699-2-git-send-email-tzanussi@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Tom Zanussi 2009-12-15 02:53:35 -06:00 committed by Ingo Molnar
parent c249a4ce79
commit 586bc5cce8
5 changed files with 38 additions and 26 deletions

View file

@ -12,7 +12,9 @@
static char const *script_name; static char const *script_name;
static char const *generate_script_lang; static char const *generate_script_lang;
static int default_start_script(const char *script __attribute((unused))) static int default_start_script(const char *script __unused,
int argc __unused,
const char **argv __unused)
{ {
return 0; return 0;
} }
@ -22,7 +24,7 @@ static int default_stop_script(void)
return 0; return 0;
} }
static int default_generate_script(const char *outfile __attribute ((unused))) static int default_generate_script(const char *outfile __unused)
{ {
return 0; return 0;
} }
@ -302,15 +304,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
setup_scripting(); setup_scripting();
argc = parse_options(argc, argv, options, annotate_usage, 0); argc = parse_options(argc, argv, options, annotate_usage,
if (argc) { PARSE_OPT_STOP_AT_NON_OPTION);
/*
* Special case: if there's an argument left then assume tha
* it's a symbol filter:
*/
if (argc > 1)
usage_with_options(annotate_usage, options);
}
setup_pager(); setup_pager();
@ -350,7 +345,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
} }
if (script_name) { if (script_name) {
err = scripting_ops->start_script(script_name); err = scripting_ops->start_script(script_name, argc, argv);
if (err) if (err)
goto out; goto out;
} }

View file

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl $1

View file

@ -18,8 +18,9 @@ use lib "./Perf-Trace-Util/lib";
use Perf::Trace::Core; use Perf::Trace::Core;
use Perf::Trace::Util; use Perf::Trace::Util;
# change this to the comm of the program you're interested in my $usage = "perf trace -s rw-by-file.pl <comm>\n";
my $for_comm = "perf";
my $for_comm = shift or die $usage;
my %reads; my %reads;
my %writes; my %writes;

View file

@ -267,7 +267,7 @@ int common_lock_depth(struct scripting_context *context)
} }
static void perl_process_event(int cpu, void *data, static void perl_process_event(int cpu, void *data,
int size __attribute((unused)), int size __unused,
unsigned long long nsecs, char *comm) unsigned long long nsecs, char *comm)
{ {
struct format_field *field; struct format_field *field;
@ -359,28 +359,42 @@ static void run_start_sub(void)
/* /*
* Start trace script * Start trace script
*/ */
static int perl_start_script(const char *script) static int perl_start_script(const char *script, int argc, const char **argv)
{ {
const char *command_line[2] = { "", NULL }; const char **command_line;
int i, err = 0;
command_line = malloc((argc + 2) * sizeof(const char *));
command_line[0] = "";
command_line[1] = script; command_line[1] = script;
for (i = 2; i < argc + 2; i++)
command_line[i] = argv[i - 2];
my_perl = perl_alloc(); my_perl = perl_alloc();
perl_construct(my_perl); perl_construct(my_perl);
if (perl_parse(my_perl, xs_init, 2, (char **)command_line, if (perl_parse(my_perl, xs_init, argc + 2, (char **)command_line,
(char **)NULL)) (char **)NULL)) {
return -1; err = -1;
goto error;
}
perl_run(my_perl); perl_run(my_perl);
if (SvTRUE(ERRSV)) if (SvTRUE(ERRSV)) {
return -1; err = -1;
goto error;
}
run_start_sub(); run_start_sub();
free(command_line);
fprintf(stderr, "perf trace started with Perl script %s\n\n", script); fprintf(stderr, "perf trace started with Perl script %s\n\n", script);
return 0; return 0;
error:
perl_free(my_perl);
free(command_line);
return err;
} }
/* /*
@ -579,7 +593,9 @@ static void print_unsupported_msg(void)
"\n etc.\n"); "\n etc.\n");
} }
static int perl_start_script_unsupported(const char *script __unused) static int perl_start_script_unsupported(const char *script __unused,
int argc __unused,
const char **argv __unused)
{ {
print_unsupported_msg(); print_unsupported_msg();

View file

@ -270,7 +270,7 @@ enum trace_flag_type {
struct scripting_ops { struct scripting_ops {
const char *name; const char *name;
int (*start_script) (const char *); int (*start_script) (const char *script, int argc, const char **argv);
int (*stop_script) (void); int (*stop_script) (void);
void (*process_event) (int cpu, void *data, int size, void (*process_event) (int cpu, void *data, int size,
unsigned long long nsecs, char *comm); unsigned long long nsecs, char *comm);