2017-12-26 10:31:28 +08:00
|
|
|
#![feature(libc, panic_unwind)]
|
2017-12-26 01:55:20 +08:00
|
|
|
#![no_std]
|
|
|
|
|
|
|
|
extern crate unwind;
|
|
|
|
extern crate libc;
|
|
|
|
|
|
|
|
use unwind as uw;
|
|
|
|
use libc::c_void;
|
|
|
|
|
|
|
|
pub fn backtrace<F>(mut f: F) -> Result<(), uw::_Unwind_Reason_Code>
|
|
|
|
where F: FnMut(usize) -> ()
|
|
|
|
{
|
|
|
|
extern fn trace<F>(context: *mut uw::_Unwind_Context, arg: *mut c_void)
|
|
|
|
-> uw::_Unwind_Reason_Code
|
|
|
|
where F: FnMut(usize) -> ()
|
|
|
|
{
|
|
|
|
unsafe {
|
|
|
|
let step_fn = &mut *(arg as *mut F);
|
|
|
|
step_fn(uw::_Unwind_GetIP(context));
|
|
|
|
uw::_URC_NO_REASON
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
2017-12-26 10:31:28 +08:00
|
|
|
match uw::_Unwind_Backtrace(trace::<F>, &mut f as *mut _ as *mut c_void) {
|
2017-12-26 01:55:20 +08:00
|
|
|
uw::_URC_NO_REASON => Ok(()),
|
|
|
|
err => Err(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|