forked from M-Labs/artiq
firmware: adjust backtrace addresses correctly.
This commit is contained in:
parent
d4f074b1e1
commit
5744d97d59
|
@ -32,9 +32,7 @@ pub fn backtrace<F>(f: F) -> Result<(), uw::_Unwind_Reason_Code>
|
||||||
trace_context.prev_sp = cur_sp;
|
trace_context.prev_sp = cur_sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIP gives us the return address, i.e. the address after the delay slot,
|
(trace_context.step_fn)(uw::_Unwind_GetIP(context));
|
||||||
// but we're interested in the call instruction.
|
|
||||||
(trace_context.step_fn)(uw::_Unwind_GetIP(context) - 2 * 4);
|
|
||||||
uw::_URC_NO_REASON
|
uw::_URC_NO_REASON
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -313,7 +313,9 @@ pub extern fn panic_fmt(args: core::fmt::Arguments, file: &'static str,
|
||||||
println!("backtrace for software version {}:",
|
println!("backtrace for software version {}:",
|
||||||
include_str!(concat!(env!("OUT_DIR"), "/git-describe")));
|
include_str!(concat!(env!("OUT_DIR"), "/git-describe")));
|
||||||
let _ = unwind_backtrace::backtrace(|ip| {
|
let _ = unwind_backtrace::backtrace(|ip| {
|
||||||
println!("{:#08x}", ip);
|
// Backtrace gives us the return address, i.e. the address after the delay slot,
|
||||||
|
// but we're interested in the call instruction.
|
||||||
|
println!("{:#08x}", ip - 2 * 4);
|
||||||
});
|
});
|
||||||
|
|
||||||
if config::read_str("panic_reset", |r| r == Ok("1")) {
|
if config::read_str("panic_reset", |r| r == Ok("1")) {
|
||||||
|
|
|
@ -201,7 +201,7 @@ mod imp {
|
||||||
const SKIP_FRAMES: i32 = 3;
|
const SKIP_FRAMES: i32 = 3;
|
||||||
|
|
||||||
#[inline(always)] // make the top of backtrace predictable
|
#[inline(always)] // make the top of backtrace predictable
|
||||||
fn record(profile: &mut Profile, pc: usize) -> Result<(), ()> {
|
fn record(profile: &mut Profile, exn_pc: usize) -> Result<(), ()> {
|
||||||
let mut result = Ok(());
|
let mut result = Ok(());
|
||||||
let mut frame = -SKIP_FRAMES;
|
let mut frame = -SKIP_FRAMES;
|
||||||
|
|
||||||
|
@ -212,6 +212,12 @@ mod imp {
|
||||||
if profile.has_edges() {
|
if profile.has_edges() {
|
||||||
let mut prev_pc = 0;
|
let mut prev_pc = 0;
|
||||||
let _ = backtrace(|pc| {
|
let _ = backtrace(|pc| {
|
||||||
|
// Backtrace gives us the return address, i.e. the address after the delay slot,
|
||||||
|
// but we're interested in the call instruction, *except* when going through
|
||||||
|
// the frame directly below the exception frame, which has the address that's
|
||||||
|
// being executed.
|
||||||
|
let pc = if pc != exn_pc { pc - 2 * 4 } else { pc };
|
||||||
|
|
||||||
if frame == 0 {
|
if frame == 0 {
|
||||||
result = result.and_then(|()|
|
result = result.and_then(|()|
|
||||||
profile.record_hit(Address::new(pc)));
|
profile.record_hit(Address::new(pc)));
|
||||||
|
@ -221,6 +227,7 @@ mod imp {
|
||||||
profile.record_edge(Address::new(pc),
|
profile.record_edge(Address::new(pc),
|
||||||
Address::new(prev_pc)));
|
Address::new(prev_pc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_pc = pc;
|
prev_pc = pc;
|
||||||
frame += 1;
|
frame += 1;
|
||||||
});
|
});
|
||||||
|
@ -229,7 +236,7 @@ mod imp {
|
||||||
// If we couldn't get anything useful out of a backtrace, at least
|
// If we couldn't get anything useful out of a backtrace, at least
|
||||||
// record a hit at the exception PC.
|
// record a hit at the exception PC.
|
||||||
if frame <= 0 {
|
if frame <= 0 {
|
||||||
result = profile.record_hit(Address::new(pc));
|
result = profile.record_hit(Address::new(exn_pc));
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
|
|
Loading…
Reference in New Issue