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

View File

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

View File

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

View File

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

View File

@ -18,7 +18,7 @@
"std": false,
"tier": 2
},
"panic-strategy": "unwind",
"panic-strategy": "abort",
"relocation-model": "static",
"supported-sanitizers": [
"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];
syscall_return!(
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),
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.*)
*(.note.gnu.*)
*(.fixup)
*(.gcc_except_table .gcc_except_table.*)
_erodata = .;
}

View File

@ -117,12 +117,19 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) {
}
_ => {}
}
syscall_return!(
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,
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,
"features": "-mmx,-sse,+soft-float",
"disable-redzone": true,
"panic-strategy": "unwind"
"panic-strategy": "abort"
}

View File

@ -1,3 +1,4 @@
pub mod jump_label;
pub mod klog;
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]
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
}
}

View File

@ -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 系统调用分发器,用于分发系统调用。