Force spill registers to fix missing backtrace (#3272)

This commit is contained in:
Dániel Buga 2025-03-19 16:21:29 +01:00 committed by GitHub
parent d7eae19a70
commit 284b0666f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 34 additions and 8 deletions

View File

@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Stack traces no longer stop at recursive functions (#3270)
- ESP32/S2/S3: Fixed an issue where the backtrace wasn't correctly captured in some cases (#3272)
### Removed

View File

@ -357,15 +357,40 @@ F15=0x{:08x}",
}
}
/// Get an array of backtrace addresses.
pub fn backtrace() -> [Option<usize>; MAX_BACKTRACE_ADDRESSES] {
let sp = unsafe {
let mut _tmp: u32;
asm!("mov {0}, a1", out(reg) _tmp);
_tmp
};
/// This function returns the caller's frame pointer.
#[inline(never)]
#[cold]
fn sp() -> u32 {
let mut sp: u32;
unsafe {
asm!(
"mov {0}, a1", // current stack pointer
// Spill registers, otherwise `sp - 12` will not contain the previous stack pointer
"add a12,a12,a12",
"rotw 3",
"add a12,a12,a12",
"rotw 3",
"add a12,a12,a12",
"rotw 3",
"add a12,a12,a12",
"rotw 3",
"add a12,a12,a12",
"rotw 4",
out(reg) sp
);
}
backtrace_internal(sp, 1)
// current frame pointer, caller's stack pointer
unsafe { ((sp - 12) as *const u32).read_volatile() }
}
/// Get an array of backtrace addresses.
#[inline(never)]
#[cold]
pub fn backtrace() -> [Option<usize>; MAX_BACKTRACE_ADDRESSES] {
let sp = sp();
backtrace_internal(sp, 0)
}
pub(crate) fn remove_window_increment(address: u32) -> u32 {