Browse Source

fix(backtrace):Use more reasonable compile options (#1056)

* fix(backtrace):Use more reasonable compile options

* 调整代码,同时解决rust analyzer未能提示warning的问题
---------

Co-authored-by: longjin <[email protected]>
linfeng 3 tháng trước cách đây
mục cha
commit
539ee3eaeb

+ 1 - 7
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:
 # 测试内核库

+ 1 - 1
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" }
+system_error = { path = "../system_error" }

+ 6 - 0
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;

+ 5 - 1
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)

+ 1 - 0
kernel/src/arch/riscv64/link.ld

@@ -62,6 +62,7 @@ SECTIONS
 		_rodata = .;	
 		*(.rodata)
 		*(.rodata.*)
+		*(.gcc_except_table .gcc_except_table.*)
 		_erodata = .;
 	}
 

+ 1 - 1
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",

+ 13 - 6
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);
 }

+ 1 - 0
kernel/src/arch/x86_64/link.lds

@@ -61,6 +61,7 @@ SECTIONS
 		*(.rodata.*)
 		*(.note.gnu.*)
 		*(.fixup)
+		*(.gcc_except_table .gcc_except_table.*)
 		_erodata = .;
 	}
 

+ 13 - 6
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);
 }
 
 /// 系统调用初始化

+ 1 - 1
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"
 }

+ 1 - 0
kernel/src/debug/mod.rs

@@ -1,3 +1,4 @@
 pub mod jump_label;
 pub mod klog;
 pub mod kprobe;
+pub mod panic;

+ 27 - 0
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
+    }
+}

+ 46 - 0
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::<hook::Tracer>(
+            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);
+}

+ 0 - 100
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::<Tracer>(
-            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
-    }
-}

+ 2 - 3
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<usize, SystemError> {
         let res = unwinding::panic::catch_unwind(|| Self::handle(syscall_num, args, frame));
         res.unwrap_or_else(|_| loop {
-            spin_loop();
+            core::hint::spin_loop();
         })
     }
     /// @brief 系统调用分发器,用于分发系统调用。