From 539ee3eaeb83834e020efbb7582ed5ce2e9646ce Mon Sep 17 00:00:00 2001 From: linfeng Date: Mon, 25 Nov 2024 16:28:05 +0800 Subject: [PATCH] fix(backtrace):Use more reasonable compile options (#1056) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(backtrace):Use more reasonable compile options * 调整代码,同时解决rust analyzer未能提示warning的问题 --------- Co-authored-by: longjin --- kernel/Makefile | 8 +- kernel/crates/unified-init/Cargo.toml | 2 +- kernel/crates/unified-init/src/main.rs | 6 ++ kernel/src/Makefile | 6 +- kernel/src/arch/riscv64/link.ld | 1 + .../riscv64/riscv64gc-unknown-none-elf.json | 2 +- kernel/src/arch/riscv64/syscall/mod.rs | 19 ++-- kernel/src/arch/x86_64/link.lds | 1 + kernel/src/arch/x86_64/syscall/mod.rs | 19 ++-- .../src/arch/x86_64/x86_64-unknown-none.json | 2 +- kernel/src/debug/mod.rs | 1 + kernel/src/debug/panic/hook.rs | 27 +++++ kernel/src/debug/panic/mod.rs | 46 ++++++++ kernel/src/lib.rs | 100 ------------------ kernel/src/syscall/mod.rs | 5 +- 15 files changed, 119 insertions(+), 126 deletions(-) create mode 100644 kernel/src/debug/panic/hook.rs create mode 100644 kernel/src/debug/panic/mod.rs diff --git a/kernel/Makefile b/kernel/Makefile index 4429fb1d..f61030b2 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -33,13 +33,7 @@ endif .PHONY: check check: ECHO -# @echo "Checking kernel... ARCH=$(ARCH)" -# @exit 1 -ifeq ($(ARCH), x86_64) - RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-11-05 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON) -else ifeq ($(ARCH), riscv64) - RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-11-05 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON) -endif + $(MAKE) -C src check ARCH=$(ARCH) test: # 测试内核库 diff --git a/kernel/crates/unified-init/Cargo.toml b/kernel/crates/unified-init/Cargo.toml index d52fce58..607896f7 100644 --- a/kernel/crates/unified-init/Cargo.toml +++ b/kernel/crates/unified-init/Cargo.toml @@ -11,4 +11,4 @@ path = "src/main.rs" [dependencies] unified-init-macros = { path = "macros" } linkme = "=0.3.27" -system_error = { path = "../system_error" } \ No newline at end of file +system_error = { path = "../system_error" } diff --git a/kernel/crates/unified-init/src/main.rs b/kernel/crates/unified-init/src/main.rs index a7a4e5db..d67e5fd4 100644 --- a/kernel/crates/unified-init/src/main.rs +++ b/kernel/crates/unified-init/src/main.rs @@ -2,6 +2,8 @@ //! 然后在当前目录执行 `cargo expand --bin unified-init-expand` //! 就可以看到把proc macro展开后的代码了 #![no_std] +#![allow(internal_features)] +#![feature(lang_items)] fn main() { todo!() @@ -14,6 +16,10 @@ pub fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} } +#[cfg(target_os = "none")] +#[lang = "eh_personality"] +unsafe extern "C" fn eh_personality() {} + #[cfg(test)] mod tests { use system_error::SystemError; diff --git a/kernel/src/Makefile b/kernel/src/Makefile index 9028420c..4eb68211 100644 --- a/kernel/src/Makefile +++ b/kernel/src/Makefile @@ -16,7 +16,7 @@ RUSTFLAGS_UNWIND = ifeq ($(UNWIND_ENABLE), yes) CFLAGS_UNWIND = -funwind-tables LDFLAGS_UNWIND = --eh-frame-hdr - RUSTFLAGS_UNWIND = -Cforce-unwind-tables -Clink-arg=-Wl,eh_frame.ld + RUSTFLAGS_UNWIND = -Cforce-unwind-tables -Clink-arg=-Wl,eh_frame.ld -Cpanic=unwind endif RUSTFLAGS += $(RUSTFLAGS_UNWIND) @@ -127,3 +127,7 @@ clean: cd $$subdir && $(MAKE) clean;\ cd .. ;\ done + +.PHONY: check +check: + RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-11-05 $(CARGO_ZBUILD) check --workspace --message-format=json --target $(TARGET_JSON) \ No newline at end of file diff --git a/kernel/src/arch/riscv64/link.ld b/kernel/src/arch/riscv64/link.ld index bcd47fdd..0f88eaef 100644 --- a/kernel/src/arch/riscv64/link.ld +++ b/kernel/src/arch/riscv64/link.ld @@ -62,6 +62,7 @@ SECTIONS _rodata = .; *(.rodata) *(.rodata.*) + *(.gcc_except_table .gcc_except_table.*) _erodata = .; } diff --git a/kernel/src/arch/riscv64/riscv64gc-unknown-none-elf.json b/kernel/src/arch/riscv64/riscv64gc-unknown-none-elf.json index b474a6fb..f8967529 100644 --- a/kernel/src/arch/riscv64/riscv64gc-unknown-none-elf.json +++ b/kernel/src/arch/riscv64/riscv64gc-unknown-none-elf.json @@ -18,7 +18,7 @@ "std": false, "tier": 2 }, - "panic-strategy": "unwind", + "panic-strategy": "abort", "relocation-model": "static", "supported-sanitizers": [ "shadow-call-stack", diff --git a/kernel/src/arch/riscv64/syscall/mod.rs b/kernel/src/arch/riscv64/syscall/mod.rs index 450c0e85..6f80d244 100644 --- a/kernel/src/arch/riscv64/syscall/mod.rs +++ b/kernel/src/arch/riscv64/syscall/mod.rs @@ -35,10 +35,17 @@ pub(super) fn syscall_handler(syscall_num: usize, frame: &mut TrapFrame) -> () { } let args = [frame.a0, frame.a1, frame.a2, frame.a3, frame.a4, frame.a5]; - syscall_return!( - Syscall::catch_handle(syscall_num, &args, frame) - .unwrap_or_else(|e| e.to_posix_errno() as usize), - frame, - false - ); + let mut syscall_handle = || -> usize { + #[cfg(feature = "backtrace")] + { + Syscall::catch_handle(syscall_num, &args, frame) + .unwrap_or_else(|e| e.to_posix_errno() as usize) + } + #[cfg(not(feature = "backtrace"))] + { + Syscall::handle(syscall_num, &args, frame) + .unwrap_or_else(|e| e.to_posix_errno() as usize) + } + }; + syscall_return!(syscall_handle(), frame, false); } diff --git a/kernel/src/arch/x86_64/link.lds b/kernel/src/arch/x86_64/link.lds index 6371c095..8c9ef16b 100644 --- a/kernel/src/arch/x86_64/link.lds +++ b/kernel/src/arch/x86_64/link.lds @@ -61,6 +61,7 @@ SECTIONS *(.rodata.*) *(.note.gnu.*) *(.fixup) + *(.gcc_except_table .gcc_except_table.*) _erodata = .; } diff --git a/kernel/src/arch/x86_64/syscall/mod.rs b/kernel/src/arch/x86_64/syscall/mod.rs index df656b3b..788517b0 100644 --- a/kernel/src/arch/x86_64/syscall/mod.rs +++ b/kernel/src/arch/x86_64/syscall/mod.rs @@ -117,12 +117,19 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) { } _ => {} } - syscall_return!( - Syscall::catch_handle(syscall_num, &args, frame) - .unwrap_or_else(|e| e.to_posix_errno() as usize) as u64, - frame, - show - ); + let mut syscall_handle = || -> u64 { + #[cfg(feature = "backtrace")] + { + Syscall::catch_handle(syscall_num, &args, frame) + .unwrap_or_else(|e| e.to_posix_errno() as usize) as u64 + } + #[cfg(not(feature = "backtrace"))] + { + Syscall::handle(syscall_num, &args, frame) + .unwrap_or_else(|e| e.to_posix_errno() as usize) as u64 + } + }; + syscall_return!(syscall_handle(), frame, show); } /// 系统调用初始化 diff --git a/kernel/src/arch/x86_64/x86_64-unknown-none.json b/kernel/src/arch/x86_64/x86_64-unknown-none.json index c676f377..fbc13a4a 100644 --- a/kernel/src/arch/x86_64/x86_64-unknown-none.json +++ b/kernel/src/arch/x86_64/x86_64-unknown-none.json @@ -11,5 +11,5 @@ "executables": true, "features": "-mmx,-sse,+soft-float", "disable-redzone": true, - "panic-strategy": "unwind" + "panic-strategy": "abort" } diff --git a/kernel/src/debug/mod.rs b/kernel/src/debug/mod.rs index 085d7051..dcd4c86a 100644 --- a/kernel/src/debug/mod.rs +++ b/kernel/src/debug/mod.rs @@ -1,3 +1,4 @@ pub mod jump_label; pub mod klog; pub mod kprobe; +pub mod panic; diff --git a/kernel/src/debug/panic/hook.rs b/kernel/src/debug/panic/hook.rs new file mode 100644 index 00000000..c339a196 --- /dev/null +++ b/kernel/src/debug/panic/hook.rs @@ -0,0 +1,27 @@ +use unwinding::abi::{UnwindContext, UnwindReasonCode, _Unwind_GetIP}; +use unwinding::panic::UserUnwindTrace; + +extern "C" { + fn lookup_kallsyms(addr: u64, level: i32) -> i32; +} + +/// User hook for unwinding +/// +/// During stack backtrace, the user can print the function location of the current stack frame. +pub struct Tracer; +pub struct CallbackData { + pub counter: usize, +} +impl UserUnwindTrace for Tracer { + type Arg = CallbackData; + + 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 + } +} diff --git a/kernel/src/debug/panic/mod.rs b/kernel/src/debug/panic/mod.rs new file mode 100644 index 00000000..245058fa --- /dev/null +++ b/kernel/src/debug/panic/mod.rs @@ -0,0 +1,46 @@ +#[cfg(feature = "backtrace")] +mod hook; +use core::panic::PanicInfo; + +/// 全局的panic处理函数 +/// +#[cfg(target_os = "none")] +#[panic_handler] +#[no_mangle] +pub fn panic(info: &PanicInfo) -> ! { + use log::error; + + use crate::process; + + error!("Kernel Panic Occurred."); + + match info.location() { + Some(loc) => { + println!( + "Location:\n\tFile: {}\n\tLine: {}, Column: {}", + loc.file(), + loc.line(), + loc.column() + ); + } + None => { + println!("No location info"); + } + } + println!("Message:\n\t{}", info.message()); + #[cfg(feature = "backtrace")] + { + let mut data = hook::CallbackData { counter: 0 }; + println!("Rust Panic Backtrace:"); + let _res = unwinding::panic::begin_panic_with_hook::( + alloc::boxed::Box::new(()), + &mut data, + ); + // log::error!("panic unreachable: {:?}", res.0); + } + println!( + "Current PCB:\n\t{:?}", + process::ProcessManager::current_pcb() + ); + process::ProcessManager::exit(usize::MAX); +} diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index c650b9d5..c6aa5b49 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -37,8 +37,6 @@ #[macro_use] extern crate std; -use core::panic::PanicInfo; - /// 导出x86_64架构相关的代码,命名为arch模块 #[macro_use] mod arch; @@ -94,104 +92,6 @@ extern crate wait_queue_macros; use crate::mm::allocator::kernel_allocator::KernelAllocator; -#[cfg(feature = "backtrace")] -use unwinding::{ - abi::{UnwindContext, UnwindReasonCode, _Unwind_GetIP}, - panic::UserUnwindTrace, -}; - -extern "C" { - fn lookup_kallsyms(addr: u64, level: i32) -> i32; -} - // 声明全局的分配器 #[cfg_attr(not(test), global_allocator)] 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; - - error!("Kernel Panic Occurred."); - - match info.location() { - Some(loc) => { - println!( - "Location:\n\tFile: {}\n\tLine: {}, Column: {}", - loc.file(), - loc.line(), - loc.column() - ); - } - None => { - println!("No location info"); - } - } - println!("Message:\n\t{}", info.message()); - #[cfg(feature = "backtrace")] - { - let mut data = CallbackData { counter: 0 }; - println!("Rust Panic Backtrace:"); - let res = unwinding::panic::begin_panic_with_hook::( - alloc::boxed::Box::new(()), - &mut data, - ); - log::error!("panic unreachable: {:?}", res.0); - } - println!( - "Current PCB:\n\t{:?}", - process::ProcessManager::current_pcb() - ); - process::ProcessManager::exit(usize::MAX); - loop {} -} - -/// 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; - - 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 - } -} diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 9157fcfe..45dd2efa 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -1,6 +1,5 @@ use core::{ ffi::{c_int, c_void}, - hint::spin_loop, sync::atomic::{AtomicBool, Ordering}, }; @@ -11,7 +10,6 @@ use crate::{ libs::{futex::constant::FutexFlag, rand::GRandFlags}, mm::{page::PAGE_4K_SIZE, syscall::MremapFlags}, net::syscall::MsgHdr, - process, process::{ fork::KernelCloneArgs, resource::{RLimit64, RUsage}, @@ -79,6 +77,7 @@ impl Syscall { /// 系统调用分发器,用于分发系统调用。 /// /// 与[handle]不同,这个函数会捕获系统调用处理函数的panic,返回错误码。 + #[cfg(feature = "backtrace")] pub fn catch_handle( syscall_num: usize, args: &[usize], @@ -86,7 +85,7 @@ impl Syscall { ) -> Result { let res = unwinding::panic::catch_unwind(|| Self::handle(syscall_num, args, frame)); res.unwrap_or_else(|_| loop { - spin_loop(); + core::hint::spin_loop(); }) } /// @brief 系统调用分发器,用于分发系统调用。