Make perf report -D command print captured LBR callstack chain when it is
collected together with raw thread stack data:

  2752673087247083 0x5d10 [0x548]: PERF_RECORD_SAMPLE(IP, 0x4002): 5841/5841: 
0x40121f period: 1543862 addr: 0
  ... FP chain: nr:0
  ... branch callstack: nr:3
  .....  0: 00000000004011d0
  .....  1: 00007f393c388411
  .....  2: 0000000000401098
  ... user regs: mask 0xff0fff ABI 64-bit
  .... AX    0x34e7
  .... BX    0x7fff5f6dd3c0
  .... CX    0xffffffff
  .... DX    0x34e6
  .... SI    0x7f393c5268d0
  .... DI    0x0
  .... BP    0x401260
  .... SP    0x7fff5f6dd3c0
  .... IP    0x40121f
  .... FLAGS 0x29f
  .... CS    0x33
  .... SS    0x2b
  .... R8    0x7f393c526800
  .... R9    0x7f393c525da0
  .... R10   0xfffffffffffff70a
  .... R11   0x246
  .... R12   0x401070
  .... R13   0x7fff5f6ddcb0
  .... R14   0x0
  .... R15   0x0
  ... ustack: size 1024, offset 0x130
   . data_src: 0x5080021
   ... thread: stack_test:5841
   ...... dso: /root/abudanko/stacks/stack_test

Signed-off-by: Alexey Budankov <[email protected]>
---
 tools/perf/util/session.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index b9fe71d11bf6..82e0438a9160 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1051,23 +1051,30 @@ static void callchain__printf(struct evsel *evsel,
                       i, callchain->ips[i]);
 }
 
-static void branch_stack__printf(struct perf_sample *sample)
+static void branch_stack__printf(struct perf_sample *sample, bool callstack)
 {
        uint64_t i;
 
-       printf("... branch stack: nr:%" PRIu64 "\n", sample->branch_stack->nr);
+       printf("%s: nr:%" PRIu64 "\n",
+               !callstack ? "... branch stack" : "... branch callstack",
+               sample->branch_stack->nr);
 
        for (i = 0; i < sample->branch_stack->nr; i++) {
                struct branch_entry *e = &sample->branch_stack->entries[i];
 
-               printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 " %hu 
cycles %s%s%s%s %x\n",
-                       i, e->from, e->to,
-                       (unsigned short)e->flags.cycles,
-                       e->flags.mispred ? "M" : " ",
-                       e->flags.predicted ? "P" : " ",
-                       e->flags.abort ? "A" : " ",
-                       e->flags.in_tx ? "T" : " ",
-                       (unsigned)e->flags.reserved);
+               if (!callstack) {
+                       printf("..... %2"PRIu64": %016" PRIx64 " -> %016" 
PRIx64 " %hu cycles %s%s%s%s %x\n",
+                               i, e->from, e->to,
+                               (unsigned short)e->flags.cycles,
+                               e->flags.mispred ? "M" : " ",
+                               e->flags.predicted ? "P" : " ",
+                               e->flags.abort ? "A" : " ",
+                               e->flags.in_tx ? "T" : " ",
+                               (unsigned)e->flags.reserved);
+               } else {
+                       printf("..... %2"PRIu64": %016" PRIx64 "\n",
+                               i, i > 0 ? e->from : e->to);
+               }
        }
 }
 
@@ -1217,8 +1224,8 @@ static void dump_sample(struct evsel *evsel, union 
perf_event *event,
        if (evsel__has_callchain(evsel))
                callchain__printf(evsel, sample);
 
-       if ((sample_type & PERF_SAMPLE_BRANCH_STACK) && 
!perf_evsel__has_branch_callstack(evsel))
-               branch_stack__printf(sample);
+       if (sample_type & PERF_SAMPLE_BRANCH_STACK)
+               branch_stack__printf(sample, 
perf_evsel__has_branch_callstack(evsel));
 
        if (sample_type & PERF_SAMPLE_REGS_USER)
                regs_user__printf(sample);
-- 
2.20.1

Reply via email to