Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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:
# 测试内核库
Expand Down
2 changes: 1 addition & 1 deletion kernel/crates/unified-init/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 6 additions & 0 deletions kernel/crates/unified-init/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
//! 然后在当前目录执行 `cargo expand --bin unified-init-expand`
//! 就可以看到把proc macro展开后的代码了
#![no_std]
#![allow(internal_features)]
#![feature(lang_items)]

fn main() {
todo!()
Expand All @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion kernel/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 change: 1 addition & 0 deletions kernel/src/arch/riscv64/link.ld
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ SECTIONS
_rodata = .;
*(.rodata)
*(.rodata.*)
*(.gcc_except_table .gcc_except_table.*)
_erodata = .;
}

Expand Down
2 changes: 1 addition & 1 deletion kernel/src/arch/riscv64/riscv64gc-unknown-none-elf.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"std": false,
"tier": 2
},
"panic-strategy": "unwind",
"panic-strategy": "abort",
"relocation-model": "static",
"supported-sanitizers": [
"shadow-call-stack",
Expand Down
19 changes: 13 additions & 6 deletions kernel/src/arch/riscv64/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 change: 1 addition & 0 deletions kernel/src/arch/x86_64/link.lds
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ SECTIONS
*(.rodata.*)
*(.note.gnu.*)
*(.fixup)
*(.gcc_except_table .gcc_except_table.*)
_erodata = .;
}

Expand Down
19 changes: 13 additions & 6 deletions kernel/src/arch/x86_64/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/// 系统调用初始化
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": "unwind"
"panic-strategy": "abort"
}
1 change: 1 addition & 0 deletions kernel/src/debug/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod jump_label;
pub mod klog;
pub mod kprobe;
pub mod panic;
27 changes: 27 additions & 0 deletions kernel/src/debug/panic/hook.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 46 additions & 0 deletions kernel/src/debug/panic/mod.rs
Original file line number Diff line number Diff line change
@@ -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);
}
100 changes: 0 additions & 100 deletions kernel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@
#[macro_use]
extern crate std;

use core::panic::PanicInfo;

/// 导出x86_64架构相关的代码,命名为arch模块
#[macro_use]
mod arch;
Expand Down Expand Up @@ -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
}
}
5 changes: 2 additions & 3 deletions kernel/src/syscall/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use core::{
ffi::{c_int, c_void},
hint::spin_loop,
sync::atomic::{AtomicBool, Ordering},
};

Expand All @@ -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},
Expand Down Expand Up @@ -79,14 +77,15 @@ impl Syscall {
/// 系统调用分发器,用于分发系统调用。
///
/// 与[handle]不同,这个函数会捕获系统调用处理函数的panic,返回错误码。
#[cfg(feature = "backtrace")]
pub fn catch_handle(
syscall_num: usize,
args: &[usize],
frame: &mut TrapFrame,
) -> 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 系统调用分发器,用于分发系统调用。
Expand Down
Loading