perf script: Print sample flags more nicely
authorAdrian Hunter <adrian.hunter@intel.com>
Thu, 23 Jun 2016 13:40:56 +0000 (16:40 +0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 23 Jun 2016 19:36:59 +0000 (16:36 -0300)
The flags field is synthesized and may have a value when Instruction
Trace decoding. The flags are "bcrosyiABEx" which stand for branch,
call, return, conditional, system, asynchronous, interrupt, transaction
abort, trace begin, trace end, and in transaction, respectively.

Change the display so that known combinations of flags are printed more
nicely e.g.: "call" for "bc", "return" for "br", "jcc" for "bo", "jmp"
for "b", "int" for "bci", "iret" for "bri", "syscall" for "bcs",
"sysret" for "brs", "async" for "by", "hw int" for "bcyi", "tx abrt" for
"bA", "tr strt" for "bB", "tr end" for "bE".

However the "x" flag will be displayed separately in those cases e.g.
"jcc (x)" for a condition branch within a transaction.

Example:

    perf record -e intel_pt//u ls
    perf script --ns -F comm,cpu,pid,tid,time,ip,addr,sym,dso,symoff,flags
    ...
    ls  3689/3689  [001]  2062.020965237:   jcc          7f06a958847a _dl_sysdep_start+0xfa (/lib/x86_64-linux-gnu/ld-2.19.so) =>     7f06a9588450 _dl_sysdep_start+0xd0 (/lib/x86_64-linux-gnu/ld-2.19.so)
    ls  3689/3689  [001]  2062.020965237:   jmp          7f06a9588461 _dl_sysdep_start+0xe1 (/lib/x86_64-linux-gnu/ld-2.19.so) =>     7f06a95885a0 _dl_sysdep_start+0x220 (/lib/x86_64-linux-gnu/ld-2.19.so)
    ls  3689/3689  [001]  2062.020965237:   jmp          7f06a95885a4 _dl_sysdep_start+0x224 (/lib/x86_64-linux-gnu/ld-2.19.so) =>     7f06a9588470 _dl_sysdep_start+0xf0 (/lib/x86_64-linux-gnu/ld-2.19.so)
    ls  3689/3689  [001]  2062.020965904:   call         7f06a95884c3 _dl_sysdep_start+0x143 (/lib/x86_64-linux-gnu/ld-2.19.so) =>     7f06a9589140 brk+0x0 (/lib/x86_64-linux-gnu/ld-2.19.so)
    ls  3689/3689  [001]  2062.020965904:   syscall      7f06a958914a brk+0xa (/lib/x86_64-linux-gnu/ld-2.19.so) =>                0 [unknown] ([unknown])
    ls  3689/3689  [001]  2062.020966237:   tr strt                 0 [unknown] ([unknown]) =>     7f06a958914c brk+0xc (/lib/x86_64-linux-gnu/ld-2.19.so)
    ls  3689/3689  [001]  2062.020966237:   return       7f06a9589165 brk+0x25 (/lib/x86_64-linux-gnu/ld-2.19.so) =>     7f06a95884c8 _dl_sysdep_start+0x148 (/lib/x86_64-linux-gnu/ld-2.19.so)
    ls  3689/3689  [001]  2062.020966237:   jcc          7f06a95884d7 _dl_sysdep_start+0x157 (/lib/x86_64-linux-gnu/ld-2.19.so) =>     7f06a95885f0 _dl_sysdep_start+0x270 (/lib/x86_64-linux-gnu/ld-2.19.so)
    ls  3689/3689  [001]  2062.020966237:   call         7f06a95885f0 _dl_sysdep_start+0x270 (/lib/x86_64-linux-gnu/ld-2.19.so) =>     7f06a958ac50 strlen+0x0 (/lib/x86_64-linux-gnu/ld-2.19.so)
    ls  3689/3689  [001]  2062.020966237:   jcc          7f06a958ac6e strlen+0x1e (/lib/x86_64-linux-gnu/ld-2.19.so) =>     7f06a958ac60 strlen+0x10 (/lib/x86_64-linux-gnu/ld-2.19.so)
    ...

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Andi Kleen <ak@linux.intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1466689258-28493-2-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/Documentation/perf-script.txt
tools/perf/builtin-script.c

index 4f34379ebd775d1a0a53f2c52ad152c12222a628..a46030d8962d2ba73a80b58fa9ac4dc72987786a 100644 (file)
@@ -170,7 +170,12 @@ OPTIONS
        Trace decoding. The flags are "bcrosyiABEx" which stand for branch,
        call, return, conditional, system, asynchronous, interrupt,
        transaction abort, trace begin, trace end, and in transaction,
-       respectively.
+       respectively. Known combinations of flags are printed more nicely e.g.
+       "call" for "bc", "return" for "br", "jcc" for "bo", "jmp" for "b",
+       "int" for "bci", "iret" for "bri", "syscall" for "bcs", "sysret" for "brs",
+       "async" for "by", "hw int" for "bcyi", "tx abrt" for "bA", "tr strt" for "bB",
+       "tr end" for "bE". However the "x" flag will be display separately in those
+       cases e.g. "jcc     (x)" for a condition branch within a transaction.
 
        Finally, a user may not set fields to none for all event types.
        i.e., -F "" is not allowed.
index 0e18e06e7fd58098eba6caa84f8d80aaa9d72cb6..56b2fb8135ce5add5a06f03ce4b4b306a677c5fc 100644 (file)
@@ -606,13 +606,42 @@ static void print_sample_bts(struct perf_sample *sample,
        printf("\n");
 }
 
+static struct {
+       u32 flags;
+       const char *name;
+} sample_flags[] = {
+       {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"},
+       {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"},
+       {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"},
+       {PERF_IP_FLAG_BRANCH, "jmp"},
+       {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"},
+       {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"},
+       {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"},
+       {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"},
+       {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"},
+       {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT, "hw int"},
+       {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"},
+       {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"},
+       {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"},
+       {0, NULL}
+};
+
 static void print_sample_flags(u32 flags)
 {
        const char *chars = PERF_IP_FLAG_CHARS;
        const int n = strlen(PERF_IP_FLAG_CHARS);
+       bool in_tx = flags & PERF_IP_FLAG_IN_TX;
+       const char *name = NULL;
        char str[33];
        int i, pos = 0;
 
+       for (i = 0; sample_flags[i].name ; i++) {
+               if (sample_flags[i].flags == (flags & ~PERF_IP_FLAG_IN_TX)) {
+                       name = sample_flags[i].name;
+                       break;
+               }
+       }
+
        for (i = 0; i < n; i++, flags >>= 1) {
                if (flags & 1)
                        str[pos++] = chars[i];
@@ -622,7 +651,11 @@ static void print_sample_flags(u32 flags)
                        str[pos++] = '?';
        }
        str[pos] = 0;
-       printf("  %-4s ", str);
+
+       if (name)
+               printf("  %-7s%4s ", name, in_tx ? "(x)" : "");
+       else
+               printf("  %-11s ", str);
 }
 
 struct printer_data {