perf tool: Save cmdline from user in file header vs what is passed to record
authorDavid Ahern <dsahern@gmail.com>
Mon, 30 Jul 2012 02:53:51 +0000 (20:53 -0600)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 3 Aug 2012 13:33:50 +0000 (10:33 -0300)
A number of builtin commands process some user args and then pass the rest to
cmd_record. cmd_record then saves argc/argv that it receives into the header of
the perf data file. But this loses the arguments handled by the first command
-- ie., the real command line from the user. This patch saves the command line
as typed by the user rather than what was passed to cmd_record.

As an example consider the command:
$ perf kvm --guest --host --guestmount=/tmp/guest-mount record
    -fo /tmp/perf.data -ag -- sleep 10

Currently the command saved to the header is:
    cmdline : /tmp/p3.5/perf record -o perf.data.kvm -fo /tmp/perf.data -ag -- sleep 1

(ignore the duplicated -o -- the first would be yet another bug with perf-kvm).

With this patch the command line saved to the header is:
cmdline : /tmp/p3.5/perf kvm --guest --host --guestmount=/tmp/guest-mount
    record -fo /tmp/perf.data -ag -- sleep 1

v2: simplified to saving the command in parse_options per Stephane's suggestion

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1343616831-6408-1-git-send-email-dsahern@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-record.c
tools/perf/util/header.c
tools/perf/util/parse-options.c

index dc2b62565aa18b25530187d833c5815058c16cae..4db6e1ba54e30bf780d990a8fb1d7b203e89707f 100644 (file)
@@ -844,8 +844,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
        struct perf_record *rec = &record;
        char errbuf[BUFSIZ];
 
-       perf_header__set_cmdline(argc, argv);
-
        evsel_list = perf_evlist__new(NULL, NULL);
        if (evsel_list == NULL)
                return -ENOMEM;
index 3a6d20443330b13d74b2b69b4c1d0e39cd5bb678..74ea3c2f81382c2881d9eda1e1cfb451b2a138f7 100644 (file)
@@ -174,6 +174,15 @@ perf_header__set_cmdline(int argc, const char **argv)
 {
        int i;
 
+       /*
+        * If header_argv has already been set, do not override it.
+        * This allows a command to set the cmdline, parse args and
+        * then call another builtin function that implements a
+        * command -- e.g, cmd_kvm calling cmd_record.
+        */
+       if (header_argv)
+               return 0;
+
        header_argc = (u32)argc;
 
        /* do not include NULL termination */
index 99d02aa57dbf19a8c0cb1a1a3a900486ef956b65..594f8fad5ecd5ae3e858899173b1a18403335dc0 100644 (file)
@@ -1,6 +1,7 @@
 #include "util.h"
 #include "parse-options.h"
 #include "cache.h"
+#include "header.h"
 
 #define OPT_SHORT 1
 #define OPT_UNSET 2
@@ -413,6 +414,8 @@ int parse_options(int argc, const char **argv, const struct option *options,
 {
        struct parse_opt_ctx_t ctx;
 
+       perf_header__set_cmdline(argc, argv);
+
        parse_options_start(&ctx, argc, argv, flags);
        switch (parse_options_step(&ctx, options, usagestr)) {
        case PARSE_OPT_HELP: