This crate provides backtrace support for arceos
.
There are 1 prerequisites for using this crate:
- Unwind tables must be built into the binary, even with unwinding is set to
abort. This can be done with the
-C force-unwind-tables
flag.
This can be done by setting RUSTFLAGS
:
export RUSTFLAGS="-Cforce-unwind-tables"
Add the axbacktrace
crate as a dependency to your program:
[dependencies]
axbacktrace = { git = "https://github.com/kern-crates/axbacktrace.git" }
You can capture a backtrace by using the dump_trace
,
A sample to dump current task backtrace
use axbacktrace::{dump_backtrace, Unwind, UnwindIf, StackInfo};
// Prepare dump stack range
let stack_low = curr_task.get_kernel_stack_down().unwrap();
let stack_high = curr_task.get_kernel_stack_top().unwrap();
let stack_info = {low: stack_low, high: stack_high};
// Init Unwind instance from current context
let mut unwind = Unwind::new_from_cur_ctx(stack_info)
// dump current task trace
dump_trace(&mut unwind);
A sample to dump another task trace
use axbacktrace::{dump_backtrace, Unwind, UnwindIf, StackInfo};
// this excute on TaskA, and TaskB is not running
let (pc, fp) = taskb.ctx_unwind();
let stack_low = taskb.get_kernel_stack_down().unwrap();
let stack_high = taskb.get_kernel_stack_top().unwrap();
let stack_info = {low: stack_low, high: stack_high};
// Init Unwind instance from current context
let mut unwind = Unwind::new(pc, fp, stack_info)
// dump another task trace
dump_trace(&mut unwind);
This will output:
[ 1.707132 0 axbacktrace:42] Call trace:
[ 1.707929 0 axbacktrace::aarch64:71] 0xFFFF0000401F1C0C
[ 1.708731 0 axbacktrace::aarch64:71] 0xFFFF0000401EEB2C
[ 1.709370 0 axbacktrace::aarch64:71] 0xFFFF0000401F03E4
[ 1.709996 0 axbacktrace::aarch64:71] 0xFFFF000040082A08
[ 1.710619 0 axbacktrace::aarch64:71] 0xFFFF0000401D6594
[ 1.711239 0 axbacktrace::aarch64:71] 0xFFFF0000401D57D4
[ 1.711819 0 axbacktrace::aarch64:71] 0xFFFF00004008CAD0
[ 1.712394 0 axbacktrace::aarch64:71] 0x00000040080048
The addresses generated by Backtrace
can be converted to human-readable
function names, filenames and line numbers by using the addr2line
tool from
LLVM or binutils with rustfilt to demangle Rust symbol names.
Simply run addr2line -fipe /path/to/binary | rustfilt
in a terminal and then
paste the addresses from the backtrace:
$ llvm-addr2line-17 -fipe ./target/aarch64-unknown-none-softfloat/debug/monolithic_userboot \
> 0xFFFF0000401F1C0C \
> 0xFFFF0000401EEB2C \
> 0xFFFF0000401F03E4 \
> 0xFFFF000040082A08 \
> 0xFFFF0000401D6594 \
> 0xFFFF0000401D57D4 \
> 0xFFFF00004008CAD0 \
> 0x00000040080048 \
> |rustfilt
core::ptr::drop_in_place<core::fmt::Error> at /rustc/c987ad527540e8f1565f57c31204bde33f63df76/library/core/src/ptr/mod.rs:514
core::array::<impl core::fmt::Debug for [T; N]>::fmt at /rustc/c987ad527540e8f1565f57c31204bde33f63df76/library/core/src/array/mod.rs:314
handle_el1h_64_irq_exception at /home/guoweikang/code/cicv/starry-mod/Starry/crates/axtrap/src/arch/aarch64/trap.rs:105
handle_el1h_64_irq at axstarry.17d3f64c3501fb0b-cgu.0:0
axruntime::init_interrupt at /home/guoweikang/code/cicv/starry-mod/Starry/crates/axruntime/src/lib.rs:306
rust_main at /home/guoweikang/code/cicv/starry-mod/Starry/crates/axruntime/src/lib.rs:173
arch_boot::platform::aarch64_common::rust_entry at /home/guoweikang/code/cicv/starry-mod/Starry/crates/arch_boot/src/platform/aarch64_common/mod.rs:40
_percpu_size_aligned at ??:0
Licensed under either of:
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)