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

* fix(backtrace):Use more reasonable compile options

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

Co-authored-by: longjin <longjin@DragonOS.org>
This commit is contained in:
linfeng 2024-11-25 16:28:05 +08:00 committed by GitHub
parent 23ccf763b6
commit 539ee3eaeb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 119 additions and 126 deletions

View File

@ -33,13 +33,7 @@ endif
.PHONY: check .PHONY: check
check: ECHO check: ECHO
# @echo "Checking kernel... ARCH=$(ARCH)" $(MAKE) -C src check 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
test: test:
# 测试内核库 # 测试内核库

View File

@ -11,4 +11,4 @@ path = "src/main.rs"
[dependencies] [dependencies]
unified-init-macros = { path = "macros" } unified-init-macros = { path = "macros" }
linkme = "=0.3.27" linkme = "=0.3.27"
system_error = { path = "../system_error" } system_error = { path = "../system_error" }

View File

@ -2,6 +2,8 @@
//! 然后在当前目录执行 `cargo expand --bin unified-init-expand` //! 然后在当前目录执行 `cargo expand --bin unified-init-expand`
//! 就可以看到把proc macro展开后的代码了 //! 就可以看到把proc macro展开后的代码了
#![no_std] #![no_std]
#![allow(internal_features)]
#![feature(lang_items)]
fn main() { fn main() {
todo!() todo!()
@ -14,6 +16,10 @@ pub fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {} loop {}
} }
#[cfg(target_os = "none")]
#[lang = "eh_personality"]
unsafe extern "C" fn eh_personality() {}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use system_error::SystemError; use system_error::SystemError;

View File

@ -16,7 +16,7 @@ RUSTFLAGS_UNWIND =
ifeq ($(UNWIND_ENABLE), yes) ifeq ($(UNWIND_ENABLE), yes)
CFLAGS_UNWIND = -funwind-tables CFLAGS_UNWIND = -funwind-tables
LDFLAGS_UNWIND = --eh-frame-hdr 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 endif
RUSTFLAGS += $(RUSTFLAGS_UNWIND) RUSTFLAGS += $(RUSTFLAGS_UNWIND)
@ -127,3 +127,7 @@ clean:
cd $$subdir && $(MAKE) clean;\ cd $$subdir && $(MAKE) clean;\
cd .. ;\ cd .. ;\
done done
.PHONY: check
check:
RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-11-05 $(CARGO_ZBUILD) check --workspace --message-format=json --target $(TARGET_JSON)

View File

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

View File

@ -18,7 +18,7 @@
"std": false, "std": false,
"tier": 2 "tier": 2
}, },
"panic-strategy": "unwind", "panic-strategy": "abort",
"relocation-model": "static", "relocation-model": "static",
"supported-sanitizers": [ "supported-sanitizers": [
"shadow-call-stack", "shadow-call-stack",

View File

@ -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]; let args = [frame.a0, frame.a1, frame.a2, frame.a3, frame.a4, frame.a5];
syscall_return!( let mut syscall_handle = || -> usize {
Syscall::catch_handle(syscall_num, &args, frame) #[cfg(feature = "backtrace")]
.unwrap_or_else(|e| e.to_posix_errno() as usize), {
frame, Syscall::catch_handle(syscall_num, &args, frame)
false .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);
} }

View File

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

View File

@ -117,12 +117,19 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) {
} }
_ => {} _ => {}
} }
syscall_return!( let mut syscall_handle = || -> u64 {
Syscall::catch_handle(syscall_num, &args, frame) #[cfg(feature = "backtrace")]
.unwrap_or_else(|e| e.to_posix_errno() as usize) as u64, {
frame, Syscall::catch_handle(syscall_num, &args, frame)
show .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);
} }
/// 系统调用初始化 /// 系统调用初始化

View File

@ -11,5 +11,5 @@
"executables": true, "executables": true,
"features": "-mmx,-sse,+soft-float", "features": "-mmx,-sse,+soft-float",
"disable-redzone": true, "disable-redzone": true,
"panic-strategy": "unwind" "panic-strategy": "abort"
} }

View File

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

View File

@ -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
}
}

View File

@ -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);
}

View File

@ -37,8 +37,6 @@
#[macro_use] #[macro_use]
extern crate std; extern crate std;
use core::panic::PanicInfo;
/// 导出x86_64架构相关的代码命名为arch模块 /// 导出x86_64架构相关的代码命名为arch模块
#[macro_use] #[macro_use]
mod arch; mod arch;
@ -94,104 +92,6 @@ extern crate wait_queue_macros;
use crate::mm::allocator::kernel_allocator::KernelAllocator; 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)] #[cfg_attr(not(test), global_allocator)]
pub static KERNEL_ALLOCATOR: KernelAllocator = KernelAllocator; 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
}
}

View File

@ -1,6 +1,5 @@
use core::{ use core::{
ffi::{c_int, c_void}, ffi::{c_int, c_void},
hint::spin_loop,
sync::atomic::{AtomicBool, Ordering}, sync::atomic::{AtomicBool, Ordering},
}; };
@ -11,7 +10,6 @@ use crate::{
libs::{futex::constant::FutexFlag, rand::GRandFlags}, libs::{futex::constant::FutexFlag, rand::GRandFlags},
mm::{page::PAGE_4K_SIZE, syscall::MremapFlags}, mm::{page::PAGE_4K_SIZE, syscall::MremapFlags},
net::syscall::MsgHdr, net::syscall::MsgHdr,
process,
process::{ process::{
fork::KernelCloneArgs, fork::KernelCloneArgs,
resource::{RLimit64, RUsage}, resource::{RLimit64, RUsage},
@ -79,6 +77,7 @@ impl Syscall {
/// 系统调用分发器,用于分发系统调用。 /// 系统调用分发器,用于分发系统调用。
/// ///
/// 与[handle]不同这个函数会捕获系统调用处理函数的panic返回错误码。 /// 与[handle]不同这个函数会捕获系统调用处理函数的panic返回错误码。
#[cfg(feature = "backtrace")]
pub fn catch_handle( pub fn catch_handle(
syscall_num: usize, syscall_num: usize,
args: &[usize], args: &[usize],
@ -86,7 +85,7 @@ impl Syscall {
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
let res = unwinding::panic::catch_unwind(|| Self::handle(syscall_num, args, frame)); let res = unwinding::panic::catch_unwind(|| Self::handle(syscall_num, args, frame));
res.unwrap_or_else(|_| loop { res.unwrap_or_else(|_| loop {
spin_loop(); core::hint::spin_loop();
}) })
} }
/// @brief 系统调用分发器,用于分发系统调用。 /// @brief 系统调用分发器,用于分发系统调用。