Skip to content

Commit

Permalink
feat: update to new backtrace lib
Browse files Browse the repository at this point in the history
  • Loading branch information
Godones committed Nov 13, 2024
1 parent ff76b0f commit 13d7970
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 20 deletions.
11 changes: 9 additions & 2 deletions kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ members = [
[features]
default = ["backtrace", "kvm", "fatfs", "fatfs-secure"]
# 内核栈回溯
backtrace = []
backtrace = ["dep:unwinding"]
# kvm
kvm = []

Expand Down Expand Up @@ -67,9 +67,16 @@ lru = "0.12.3"

rbpf = { path = "crates/rbpf" }
printf-compat = { version = "0.1.1", default-features = false }

unwinding = { git = "https://github.com/Godones/unwinding.git", branch = "hook", default-features = false, optional = true, features = [
"unwinder",
"fde-gnu-eh-frame-hdr",
"panic",
"personality"
]}

# target为x86_64时,使用下面的依赖
[target.'cfg(target_arch = "x86_64")'.dependencies]
mini-backtrace = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/mini-backtrace.git", rev = "e0b1d90940" }
multiboot2 = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/multiboot2", rev = "05739aab40" }
raw-cpuid = "11.0.1"
x86 = "=0.52.0"
Expand Down
2 changes: 1 addition & 1 deletion kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ clean:
fmt:
RUSTFLAGS="$(RUSTFLAGS)" cargo fmt --all $(FMT_CHECK)
ifeq ($(ARCH), x86_64)
RUSTFLAGS="$(RUSTFLAGS)" cargo clippy --all-features
# RUSTFLAGS="$(RUSTFLAGS)" cargo clippy --all-features
endif


Expand Down
2 changes: 2 additions & 0 deletions kernel/src/arch/riscv64/link.ld
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ SECTIONS

. = ALIGN(4096);
text_start_pa = .;
__executable_start = .;
.text (text_start_pa): AT(text_start_pa - KERNEL_VMA)
{
_text = .;
Expand All @@ -39,6 +40,7 @@ SECTIONS
*(.text.*)

_etext = .;
__etext = .;
}
. = ALIGN(32768);
data_start_pa = .;
Expand Down
2 changes: 2 additions & 0 deletions kernel/src/arch/x86_64/link.lds
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ SECTIONS
. = ALIGN(32768);
. += KERNEL_VMA;
text_start_pa = .;
__executable_start = .;
.text (text_start_pa): AT(text_start_pa - KERNEL_VMA)
{
_text = .;
Expand All @@ -37,6 +38,7 @@ SECTIONS
*(.text.*)

_etext = .;
__etext = .;
}
. = ALIGN(32768);
data_start_pa = .;
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/arch/x86_64/x86_64-unknown-none.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
"executables": true,
"features": "-mmx,-sse,+soft-float",
"disable-redzone": true,
"panic-strategy": "abort"
"panic-strategy": "unwind"
}
83 changes: 67 additions & 16 deletions kernel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,11 @@ extern crate wait_queue_macros;

use crate::mm::allocator::kernel_allocator::KernelAllocator;

#[cfg(all(feature = "backtrace", target_arch = "x86_64"))]
extern crate mini_backtrace;
#[cfg(feature = "backtrace")]
use unwinding::{
abi::{UnwindContext, UnwindReasonCode, _Unwind_GetIP},
panic::UserUnwindTrace,
};

extern "C" {
fn lookup_kallsyms(addr: u64, level: i32) -> i32;
Expand All @@ -105,12 +108,37 @@ extern "C" {
pub static KERNEL_ALLOCATOR: KernelAllocator = KernelAllocator;

/// 全局的panic处理函数
///
/// How to use unwinding lib:
///
/// ```
/// pub fn test_unwind() {
/// struct UnwindTest;
/// impl Drop for UnwindTest {
/// fn drop(&mut self) {
/// println!("Drop UnwindTest");
/// }
/// }
/// let res1 = unwinding::panic::catch_unwind(|| {
/// let _unwind_test = UnwindTest;
/// println!("Test panic...");
/// panic!("Test panic");
/// });
/// assert_eq!(res1.is_err(), true);
/// let res2 = unwinding::panic::catch_unwind(|| {
/// let _unwind_test = UnwindTest;
/// println!("Test no panic...");
/// 0
/// });
/// assert_eq!(res2.is_ok(), true);
/// }
/// ```
///
#[cfg(target_os = "none")]
#[panic_handler]
#[no_mangle]
pub fn panic(info: &PanicInfo) -> ! {
use log::error;
use process::ProcessManager;

error!("Kernel Panic Occurred.");

Expand All @@ -128,21 +156,44 @@ pub fn panic(info: &PanicInfo) -> ! {
}
}
println!("Message:\n\t{}", info.message());

#[cfg(all(feature = "backtrace", target_arch = "x86_64"))]
const MAX_DEPTH: u8 = 2;
static DEPTH: core::sync::atomic::AtomicU8 = core::sync::atomic::AtomicU8::new(0);
let depth = DEPTH.fetch_add(1, core::sync::atomic::Ordering::SeqCst);
if depth >= MAX_DEPTH {
println!("Panic depth is too deep, stop unwinding.");
loop {}
}
#[cfg(feature = "backtrace")]
{
unsafe {
let bt = mini_backtrace::Backtrace::<16>::capture();
println!("Rust Panic Backtrace:");
let mut level = 0;
for frame in bt.frames {
lookup_kallsyms(frame as u64, level);
level += 1;
}
};
let mut data = CallbackData { counter: 0 };
println!("Rust Panic Backtrace:");
let res = unwinding::panic::begin_panic_with_hook::<Tracer>(
alloc::boxed::Box::new(()),
&mut data,
);
panic!("panic unreachable: {:?}", res.0);
}
// println!("Current PCB:\n\t{:?}", (ProcessManager::current_pcb()));
// process::ProcessManager::exit(usize::MAX);
}

println!("Current PCB:\n\t{:?}", (ProcessManager::current_pcb()));
/// User hook for unwinding
///
/// During stack backtrace, the user can print the function location of the current stack frame.
struct Tracer;
struct CallbackData {
counter: usize,
}
impl UserUnwindTrace for Tracer {
type Arg = CallbackData;

ProcessManager::exit(usize::MAX);
fn trace(ctx: &UnwindContext<'_>, arg: *mut Self::Arg) -> UnwindReasonCode {
let data = unsafe { &mut *(arg) };
data.counter += 1;
let pc = _Unwind_GetIP(ctx);
unsafe {
lookup_kallsyms(pc as u64, data.counter as i32);
}
UnwindReasonCode::NO_REASON
}
}

0 comments on commit 13d7970

Please sign in to comment.