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); |
