aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Zanussi <tzanussi@gmail.com>2009-12-15 03:53:39 -0500
committerIngo Molnar <mingo@elte.hu>2009-12-15 04:31:33 -0500
commit3875294f5c0d7b9ef96ffc373d8a956ebd7c0c7f (patch)
tree546faf7874c7147c0f30f2e393b14e481c6b5407
parent4b9c0c596ea826ef784eb83f663c5351ed01ba6d (diff)
perf trace/scripting: Add 'record' and 'report' options
Allow scripts to be recorded/executed by simply specifying the script root name (the script name minus extension) along with 'record' or 'report' to 'perf trace'. The script names shown by 'perf trace -l' can be directly used to run the command-line contained within the corresponding '-record' and '-report' versions of scripts in the scripts/*/bin directories. For example, to record the trace data needed to run the wakeup-latency.pl script, the user can easily find the name of the corresponding script from the script list and invoke it using 'perf trace record', without having to remember the details of how to do the same thing using the lower-level perf trace command-line options: root@tropicana:~# perf trace -l List of available trace scripts: workqueue-stats workqueue stats (ins/exe/create/destroy) wakeup-latency system-wide min/max/avg wakeup latency rw-by-file <comm> r/w activity for a program, by file check-perf-trace useless but exhaustive test script rw-by-pid system-wide r/w activity root@tropicana:~# perf trace record wakeup-latency ^C[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.296 MB perf.data (~12931 samples) ] To run the wakeup-latency.pl script using the captured data, change 'record' to 'report' in the command-line: root@tropicana:~# perf trace report wakeup-latency wakeup_latency stats: total_wakeups: 65 avg_wakeup_latency (ns): 22417 min_wakeup_latency (ns): 3470 max_wakeup_latency (ns): 223311 perf trace Perl script stopped If the script takes options, thay can be simply added to the end of the 'report' invocation: root@tropicana:~# perf trace record rw-by-file ^C[ perf record: Woken up 2 times to write data ] [ perf record: Captured and wrote 0.782 MB perf.data (~34171 samples) ] root@tropicana:~# perf trace report rw-by-file perf file read counts for perf: fd # reads bytes_requested ------ ---------- ----------- 122 1934 1980416 120 1 32 file write counts for perf: fd # writes bytes_written ------ ---------- ----------- 3 4006 280568 perf trace Perl script stopped Signed-off-by: Tom Zanussi <tzanussi@gmail.com> Cc: fweisbec@gmail.com Cc: rostedt@goodmis.org LKML-Reference: <1260867220-15699-6-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--tools/perf/builtin-trace.c84
1 files changed, 83 insertions, 1 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 7674153c4bbe..7e744f774047 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -469,6 +469,49 @@ static int list_available_scripts(const struct option *opt __used,
469 exit(0); 469 exit(0);
470} 470}
471 471
472static char *get_script_path(const char *script_root, const char *suffix)
473{
474 struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
475 char scripts_path[MAXPATHLEN];
476 char script_path[MAXPATHLEN];
477 DIR *scripts_dir, *lang_dir;
478 char lang_path[MAXPATHLEN];
479 char *str, *__script_root;
480 char *path = NULL;
481
482 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
483
484 scripts_dir = opendir(scripts_path);
485 if (!scripts_dir)
486 return NULL;
487
488 for_each_lang(scripts_dir, lang_dirent, lang_next) {
489 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
490 lang_dirent.d_name);
491 lang_dir = opendir(lang_path);
492 if (!lang_dir)
493 continue;
494
495 for_each_script(lang_dir, script_dirent, script_next) {
496 __script_root = strdup(script_dirent.d_name);
497 str = ends_with(__script_root, suffix);
498 if (str) {
499 *str = '\0';
500 if (strcmp(__script_root, script_root))
501 continue;
502 snprintf(script_path, MAXPATHLEN, "%s/%s",
503 lang_path, script_dirent.d_name);
504 path = strdup(script_path);
505 free(__script_root);
506 break;
507 }
508 free(__script_root);
509 }
510 }
511
512 return path;
513}
514
472static const char * const annotate_usage[] = { 515static const char * const annotate_usage[] = {
473 "perf trace [<options>] <command>", 516 "perf trace [<options>] <command>",
474 NULL 517 NULL
@@ -494,8 +537,47 @@ static const struct option options[] = {
494 537
495int cmd_trace(int argc, const char **argv, const char *prefix __used) 538int cmd_trace(int argc, const char **argv, const char *prefix __used)
496{ 539{
497 int err;
498 struct perf_session *session; 540 struct perf_session *session;
541 const char *suffix = NULL;
542 const char **__argv;
543 char *script_path;
544 int i, err;
545
546 if (argc >= 2 && strncmp(argv[1], "rec", strlen("rec")) == 0) {
547 if (argc < 3) {
548 fprintf(stderr,
549 "Please specify a record script\n");
550 return -1;
551 }
552 suffix = RECORD_SUFFIX;
553 }
554
555 if (argc >= 2 && strncmp(argv[1], "rep", strlen("rep")) == 0) {
556 if (argc < 3) {
557 fprintf(stderr,
558 "Please specify a report script\n");
559 return -1;
560 }
561 suffix = REPORT_SUFFIX;
562 }
563
564 if (suffix) {
565 script_path = get_script_path(argv[2], suffix);
566 if (!script_path) {
567 fprintf(stderr, "script not found\n");
568 return -1;
569 }
570
571 __argv = malloc((argc + 1) * sizeof(const char *));
572 __argv[0] = "/bin/sh";
573 __argv[1] = script_path;
574 for (i = 3; i < argc; i++)
575 __argv[i - 1] = argv[i];
576 __argv[argc - 1] = NULL;
577
578 execvp("/bin/sh", (char **)__argv);
579 exit(-1);
580 }
499 581
500 symbol__init(0); 582 symbol__init(0);
501 583