aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-script.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r--tools/perf/builtin-script.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 3728b50e52e2..d079f36d342d 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1073,9 +1073,18 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
1073 1073
1074 /* 1074 /*
1075 * Print final block upto sample 1075 * Print final block upto sample
1076 *
1077 * Due to pipeline delays the LBRs might be missing a branch
1078 * or two, which can result in very large or negative blocks
1079 * between final branch and sample. When this happens just
1080 * continue walking after the last TO until we hit a branch.
1076 */ 1081 */
1077 start = br->entries[0].to; 1082 start = br->entries[0].to;
1078 end = sample->ip; 1083 end = sample->ip;
1084 if (end < start) {
1085 /* Missing jump. Scan 128 bytes for the next branch */
1086 end = start + 128;
1087 }
1079 len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true); 1088 len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);
1080 printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp); 1089 printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
1081 if (len <= 0) { 1090 if (len <= 0) {
@@ -1084,7 +1093,6 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
1084 machine, thread, &x.is64bit, &x.cpumode, false); 1093 machine, thread, &x.is64bit, &x.cpumode, false);
1085 if (len <= 0) 1094 if (len <= 0)
1086 goto out; 1095 goto out;
1087
1088 printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip, 1096 printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip,
1089 dump_insn(&x, sample->ip, buffer, len, NULL)); 1097 dump_insn(&x, sample->ip, buffer, len, NULL));
1090 if (PRINT_FIELD(SRCCODE)) 1098 if (PRINT_FIELD(SRCCODE))
@@ -1096,6 +1104,13 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
1096 dump_insn(&x, start + off, buffer + off, len - off, &ilen)); 1104 dump_insn(&x, start + off, buffer + off, len - off, &ilen));
1097 if (ilen == 0) 1105 if (ilen == 0)
1098 break; 1106 break;
1107 if (arch_is_branch(buffer + off, len - off, x.is64bit) && start + off != sample->ip) {
1108 /*
1109 * Hit a missing branch. Just stop.
1110 */
1111 printed += fprintf(fp, "\t... not reaching sample ...\n");
1112 break;
1113 }
1099 if (PRINT_FIELD(SRCCODE)) 1114 if (PRINT_FIELD(SRCCODE))
1100 print_srccode(thread, x.cpumode, start + off); 1115 print_srccode(thread, x.cpumode, start + off);
1101 } 1116 }
@@ -1167,7 +1182,7 @@ static int perf_sample__fprintf_callindent(struct perf_sample *sample,
1167 struct addr_location *al, FILE *fp) 1182 struct addr_location *al, FILE *fp)
1168{ 1183{
1169 struct perf_event_attr *attr = &evsel->attr; 1184 struct perf_event_attr *attr = &evsel->attr;
1170 size_t depth = thread_stack__depth(thread); 1185 size_t depth = thread_stack__depth(thread, sample->cpu);
1171 const char *name = NULL; 1186 const char *name = NULL;
1172 static int spacing; 1187 static int spacing;
1173 int len = 0; 1188 int len = 0;
@@ -1701,7 +1716,7 @@ static bool show_event(struct perf_sample *sample,
1701 struct thread *thread, 1716 struct thread *thread,
1702 struct addr_location *al) 1717 struct addr_location *al)
1703{ 1718{
1704 int depth = thread_stack__depth(thread); 1719 int depth = thread_stack__depth(thread, sample->cpu);
1705 1720
1706 if (!symbol_conf.graph_function) 1721 if (!symbol_conf.graph_function)
1707 return true; 1722 return true;