forked from rust-lang/backtrace-rs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Backtrace support for the ESP-IDF framework
- Loading branch information
imarkov
committed
Aug 25, 2021
1 parent
4f925f8
commit 2ede3b0
Showing
4 changed files
with
113 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
//! Implementation of backtracing for ESP-IDF. | ||
use core::ffi::c_void; | ||
|
||
#[derive(Clone, Debug)] | ||
pub struct Frame { | ||
ip: *mut c_void, | ||
sp: *mut c_void, | ||
} | ||
|
||
// SAFETY: The pointers returned in this struct can be used from any thread. | ||
unsafe impl Send for Frame {} | ||
unsafe impl Sync for Frame {} | ||
|
||
impl Frame { | ||
pub fn ip(&self) -> *mut c_void { | ||
self.ip | ||
} | ||
|
||
pub fn sp(&self) -> *mut c_void { | ||
self.sp | ||
} | ||
|
||
pub fn symbol_address(&self) -> *mut c_void { | ||
0 as *mut _ | ||
} | ||
|
||
pub fn module_base_address(&self) -> Option<*mut c_void> { | ||
None | ||
} | ||
} | ||
|
||
// Reference: https://github.com/espressif/esp-idf/blob/master/components/esp_system/include/esp_debug_helpers.h | ||
#[cfg(target_arch = "xtensa")] | ||
#[inline(always)] | ||
pub fn trace(cb: &mut dyn FnMut(&super::Frame) -> bool) { | ||
#[repr(C)] | ||
struct esp_backtrace_frame_t { | ||
pc: *mut c_void, // PC of the current frame | ||
sp: *mut c_void, // SP of the current frame | ||
next_pc: *mut c_void, // PC of the current frame's caller | ||
exc_frame: *const c_void, // Pointer to the full frame data structure, if applicable | ||
} | ||
|
||
impl From<&esp_backtrace_frame_t> for Frame { | ||
#[inline(always)] | ||
fn from(esp_frame: &esp_backtrace_frame_t) -> Self { | ||
let mut pc = esp_frame.pc as u32; | ||
|
||
// Reference: https://github.com/espressif/esp-idf/blob/master/components/esp_hw_support/include/soc/cpu.h#L38 | ||
if (pc & 0x80000000) != 0 { | ||
// Top two bits of a0 (return address) specify window increment. Overwrite to map to address space. | ||
pc = (pc & 0x3fffffff) | 0x40000000; | ||
} | ||
pc = pc - 3; // Minus 3 to get PC of previous instruction (i.e. instruction executed before return address) | ||
|
||
Self { | ||
ip: pc as *mut _, | ||
sp: esp_frame.sp, | ||
} | ||
} | ||
} | ||
|
||
extern "C" { | ||
fn esp_backtrace_get_start( | ||
pc: *mut *mut c_void, | ||
sp: *mut *mut c_void, | ||
next_pc: *mut *mut c_void, | ||
); | ||
fn esp_backtrace_get_next_frame(frame: *mut esp_backtrace_frame_t) -> bool; | ||
} | ||
|
||
let mut frame: esp_backtrace_frame_t = unsafe { ::core::mem::zeroed() }; | ||
|
||
unsafe { | ||
esp_backtrace_get_start( | ||
&mut frame.pc as *mut _, | ||
&mut frame.sp as *mut _, | ||
&mut frame.next_pc as *mut _, | ||
) | ||
}; | ||
|
||
cb(&super::Frame { | ||
inner: (&frame).into(), | ||
}); | ||
|
||
while unsafe { esp_backtrace_get_next_frame(&mut frame as *mut _) } { | ||
cb(&super::Frame { | ||
inner: (&frame).into(), | ||
}); | ||
} | ||
} | ||
|
||
#[cfg(not(target_arch = "xtensa"))] | ||
#[inline(always)] | ||
pub fn trace(_cb: &mut dyn FnMut(&super::Frame) -> bool) { | ||
// RiscV is not supported yet | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters