perf script brstackinsn: Fix recovery from LBR/binary mismatch
When the LBR data and the instructions in a binary do not match the loop printing instructions could get confused and print a long stream of bogus <bad> instructions. The problem was that if the instruction decoder cannot decode an instruction it ilen wasn't initialized, so the loop going through the basic block would continue with the previous value. Harden the code to avoid such problems: - Make sure ilen is always freshly initialized and is 0 for bad instructions. - Do not overrun the code buffer while printing instructions - Print a warning message if the final jump is not on an instruction boundary. Signed-off-by: Andi Kleen <ak@linux.intel.com> Cc: Jiri Olsa <jolsa@kernel.org> Link: http://lore.kernel.org/lkml/20190927233546.11533-1-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
2657983b4c
commit
e98df280bc
|
@ -1063,7 +1063,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
|
|||
continue;
|
||||
|
||||
insn = 0;
|
||||
for (off = 0;; off += ilen) {
|
||||
for (off = 0; off < (unsigned)len; off += ilen) {
|
||||
uint64_t ip = start + off;
|
||||
|
||||
printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
|
||||
|
@ -1074,6 +1074,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
|
|||
printed += print_srccode(thread, x.cpumode, ip);
|
||||
break;
|
||||
} else {
|
||||
ilen = 0;
|
||||
printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", ip,
|
||||
dump_insn(&x, ip, buffer + off, len - off, &ilen));
|
||||
if (ilen == 0)
|
||||
|
@ -1083,6 +1084,8 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
|
|||
insn++;
|
||||
}
|
||||
}
|
||||
if (off != (unsigned)len)
|
||||
printed += fprintf(fp, "\tmismatch of LBR data and executable\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1123,6 +1126,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
|
|||
goto out;
|
||||
}
|
||||
for (off = 0; off <= end - start; off += ilen) {
|
||||
ilen = 0;
|
||||
printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", start + off,
|
||||
dump_insn(&x, start + off, buffer + off, len - off, &ilen));
|
||||
if (ilen == 0)
|
||||
|
|
Loading…
Reference in New Issue