diff options
Diffstat (limited to 'tools/perf/builtin-script.c')
| -rw-r--r-- | tools/perf/builtin-script.c | 17 | 
1 files changed, 16 insertions, 1 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 3728b50e52e2..88d52ed85ffc 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,  	/*  	 * Print final block upto sample +	 * +	 * Due to pipeline delays the LBRs might be missing a branch +	 * or two, which can result in very large or negative blocks +	 * between final branch and sample. When this happens just +	 * continue walking after the last TO until we hit a branch.  	 */  	start = br->entries[0].to;  	end = sample->ip; +	if (end < start) { +		/* Missing jump. Scan 128 bytes for the next branch */ +		end = start + 128; +	}  	len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);  	printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp);  	if (len <= 0) { @@ -1084,7 +1093,6 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,  			      machine, thread, &x.is64bit, &x.cpumode, false);  		if (len <= 0)  			goto out; -  		printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip,  			dump_insn(&x, sample->ip, buffer, len, NULL));  		if (PRINT_FIELD(SRCCODE)) @@ -1096,6 +1104,13 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,  				   dump_insn(&x, start + off, buffer + off, len - off, &ilen));  		if (ilen == 0)  			break; +		if (arch_is_branch(buffer + off, len - off, x.is64bit) && start + off != sample->ip) { +			/* +			 * Hit a missing branch. Just stop. +			 */ +			printed += fprintf(fp, "\t... not reaching sample ...\n"); +			break; +		}  		if (PRINT_FIELD(SRCCODE))  			print_srccode(thread, x.cpumode, start + off);  	}  | 
