diff options
author | Tom Zanussi <tom.zanussi@linux.intel.com> | 2010-11-10 09:15:43 -0500 |
---|---|---|
committer | Tom Zanussi <tom.zanussi@linux.intel.com> | 2010-11-10 09:15:43 -0500 |
commit | 34c86ea97ed811bb40ee4db63f710eb522162c77 (patch) | |
tree | c1236cd3272988ed78ad827c14dd2769e13c0b26 | |
parent | bca647aac5067fec8dfcbf8ddb79a4c0d5afdfdd (diff) |
perf trace record: handle commands correctly
Because the perf-trace shell scripts hard-coded the use of the
perf-record system-wide param, a perf trace record session was always
system wide, even if it was given a command.
If given a command, perf trace record now only records the events for
the command, as users expect.
If no command is given, or if the '-a' option is used, the recorded
events are system-wide, as before.
root@tropicana:~# perf trace record syscall-counts ls -al
root@tropicana:~# perf trace
ls-23152 [000] 39984.890387: sys_enter: NR 12 (0, 0, 0, 0, 0, 0)
ls-23152 [000] 39984.890404: sys_enter: NR 9 (0, 0, 0, 0, 0, 0)
root@tropicana:~# perf trace record syscall-counts -a ls -al
root@tropicana:~# perf trace
npviewer.bin-22297 [000] 39831.102709: sys_enter: NR 168 (0, 0, 0, 0, 0, 0)
ls-23111 [000] 39831.107679: sys_enter: NR 59 (0, 0, 0, 0, 0, 0)
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Acked-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
-rw-r--r-- | tools/perf/builtin-trace.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 368e6249290a..0de7fcb90965 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include "util/symbol.h" | 10 | #include "util/symbol.h" |
11 | #include "util/thread.h" | 11 | #include "util/thread.h" |
12 | #include "util/trace-event.h" | 12 | #include "util/trace-event.h" |
13 | #include "util/parse-options.h" | ||
13 | #include "util/util.h" | 14 | #include "util/util.h" |
14 | 15 | ||
15 | static char const *script_name; | 16 | static char const *script_name; |
@@ -17,6 +18,7 @@ static char const *generate_script_lang; | |||
17 | static bool debug_mode; | 18 | static bool debug_mode; |
18 | static u64 last_timestamp; | 19 | static u64 last_timestamp; |
19 | static u64 nr_unordered; | 20 | static u64 nr_unordered; |
21 | extern const struct option record_options[]; | ||
20 | 22 | ||
21 | static int default_start_script(const char *script __unused, | 23 | static int default_start_script(const char *script __unused, |
22 | int argc __unused, | 24 | int argc __unused, |
@@ -566,6 +568,20 @@ static const struct option options[] = { | |||
566 | OPT_END() | 568 | OPT_END() |
567 | }; | 569 | }; |
568 | 570 | ||
571 | static bool have_cmd(int argc, const char **argv) | ||
572 | { | ||
573 | char **__argv = malloc(sizeof(const char *) * argc); | ||
574 | |||
575 | if (!__argv) | ||
576 | die("malloc"); | ||
577 | memcpy(__argv, argv, sizeof(const char *) * argc); | ||
578 | argc = parse_options(argc, (const char **)__argv, record_options, | ||
579 | NULL, PARSE_OPT_STOP_AT_NON_OPTION); | ||
580 | free(__argv); | ||
581 | |||
582 | return argc != 0; | ||
583 | } | ||
584 | |||
569 | int cmd_trace(int argc, const char **argv, const char *prefix __used) | 585 | int cmd_trace(int argc, const char **argv, const char *prefix __used) |
570 | { | 586 | { |
571 | struct perf_session *session; | 587 | struct perf_session *session; |
@@ -663,20 +679,28 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) | |||
663 | } | 679 | } |
664 | 680 | ||
665 | if (suffix) { | 681 | if (suffix) { |
682 | bool system_wide = false; | ||
683 | int j = 0; | ||
684 | |||
666 | script_path = get_script_path(argv[2], suffix); | 685 | script_path = get_script_path(argv[2], suffix); |
667 | if (!script_path) { | 686 | if (!script_path) { |
668 | fprintf(stderr, "script not found\n"); | 687 | fprintf(stderr, "script not found\n"); |
669 | return -1; | 688 | return -1; |
670 | } | 689 | } |
671 | 690 | ||
691 | if (!strcmp(suffix, RECORD_SUFFIX)) | ||
692 | system_wide = !have_cmd(argc - 2, &argv[2]); | ||
693 | |||
672 | __argv = malloc((argc + 1) * sizeof(const char *)); | 694 | __argv = malloc((argc + 1) * sizeof(const char *)); |
673 | if (!__argv) | 695 | if (!__argv) |
674 | die("malloc"); | 696 | die("malloc"); |
675 | __argv[0] = "/bin/sh"; | 697 | __argv[j++] = "/bin/sh"; |
676 | __argv[1] = script_path; | 698 | __argv[j++] = script_path; |
699 | if (system_wide) | ||
700 | __argv[j++] = "-a"; | ||
677 | for (i = 3; i < argc; i++) | 701 | for (i = 3; i < argc; i++) |
678 | __argv[i - 1] = argv[i]; | 702 | __argv[j++] = argv[i]; |
679 | __argv[argc - 1] = NULL; | 703 | __argv[j++] = NULL; |
680 | 704 | ||
681 | execvp("/bin/sh", (char **)__argv); | 705 | execvp("/bin/sh", (char **)__argv); |
682 | free(__argv); | 706 | free(__argv); |