mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 22:36:48 +00:00
feat: update to new backtrace lib (#1049)
* feat: update to new backtrace lib * feat: enable unwind for riscv64 --------- Co-authored-by: longjin <longjin@DragonOS.org>
This commit is contained in:
parent
2cac148dc1
commit
081428c0d8
@ -17,7 +17,7 @@ members = [
|
|||||||
[features]
|
[features]
|
||||||
default = ["backtrace", "kvm", "fatfs", "fatfs-secure", "static_keys_test"]
|
default = ["backtrace", "kvm", "fatfs", "fatfs-secure", "static_keys_test"]
|
||||||
# 内核栈回溯
|
# 内核栈回溯
|
||||||
backtrace = []
|
backtrace = ["dep:unwinding"]
|
||||||
# kvm
|
# kvm
|
||||||
kvm = []
|
kvm = []
|
||||||
|
|
||||||
@ -68,11 +68,17 @@ lru = "0.12.3"
|
|||||||
|
|
||||||
rbpf = { path = "crates/rbpf" }
|
rbpf = { path = "crates/rbpf" }
|
||||||
printf-compat = { version = "0.1.1", default-features = false }
|
printf-compat = { version = "0.1.1", default-features = false }
|
||||||
|
|
||||||
static-keys = "=0.6.1"
|
static-keys = "=0.6.1"
|
||||||
|
unwinding = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/unwinding", rev = "4eb845da62", default-features = false, optional = true, features = [
|
||||||
|
"unwinder",
|
||||||
|
"fde-gnu-eh-frame-hdr",
|
||||||
|
"panic",
|
||||||
|
"personality"
|
||||||
|
]}
|
||||||
|
|
||||||
# target为x86_64时,使用下面的依赖
|
# target为x86_64时,使用下面的依赖
|
||||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||||
mini-backtrace = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/mini-backtrace.git", rev = "e0b1d90940" }
|
|
||||||
multiboot2 = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/multiboot2", rev = "05739aab40" }
|
multiboot2 = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/multiboot2", rev = "05739aab40" }
|
||||||
raw-cpuid = "11.0.1"
|
raw-cpuid = "11.0.1"
|
||||||
x86 = "=0.52.0"
|
x86 = "=0.52.0"
|
||||||
|
@ -6,7 +6,7 @@ include ./env.mk
|
|||||||
ifeq ($(ARCH), x86_64)
|
ifeq ($(ARCH), x86_64)
|
||||||
export TARGET_JSON=arch/x86_64/x86_64-unknown-none.json
|
export TARGET_JSON=arch/x86_64/x86_64-unknown-none.json
|
||||||
else ifeq ($(ARCH), riscv64)
|
else ifeq ($(ARCH), riscv64)
|
||||||
export TARGET_JSON=riscv64gc-unknown-none-elf
|
export TARGET_JSON=arch/riscv64/riscv64gc-unknown-none-elf.json
|
||||||
endif
|
endif
|
||||||
|
|
||||||
export CARGO_ZBUILD=-Z build-std=core,alloc,compiler_builtins -Z build-std-features=compiler-builtins-mem
|
export CARGO_ZBUILD=-Z build-std=core,alloc,compiler_builtins -Z build-std-features=compiler-builtins-mem
|
||||||
@ -27,7 +27,7 @@ clean:
|
|||||||
fmt:
|
fmt:
|
||||||
RUSTFLAGS="$(RUSTFLAGS)" cargo fmt --all $(FMT_CHECK)
|
RUSTFLAGS="$(RUSTFLAGS)" cargo fmt --all $(FMT_CHECK)
|
||||||
ifeq ($(ARCH), x86_64)
|
ifeq ($(ARCH), x86_64)
|
||||||
RUSTFLAGS="$(RUSTFLAGS)" cargo clippy --all-features
|
RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-11-05 clippy --all-features
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ check: ECHO
|
|||||||
ifeq ($(ARCH), x86_64)
|
ifeq ($(ARCH), x86_64)
|
||||||
RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-11-05 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON)
|
RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-11-05 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON)
|
||||||
else ifeq ($(ARCH), riscv64)
|
else ifeq ($(ARCH), riscv64)
|
||||||
RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-11-05 check --workspace $(CARGO_ZBUILD) --message-format=json --target $(TARGET_JSON)
|
RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-11-05 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
@ -14,11 +14,9 @@ CFLAGS_UNWIND =
|
|||||||
LDFLAGS_UNWIND =
|
LDFLAGS_UNWIND =
|
||||||
RUSTFLAGS_UNWIND =
|
RUSTFLAGS_UNWIND =
|
||||||
ifeq ($(UNWIND_ENABLE), yes)
|
ifeq ($(UNWIND_ENABLE), yes)
|
||||||
CFLAGS_UNWIND = -funwind-tables
|
CFLAGS_UNWIND = -funwind-tables
|
||||||
ifeq ($(ARCH), x86_64)
|
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
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
RUSTFLAGS += $(RUSTFLAGS_UNWIND)
|
RUSTFLAGS += $(RUSTFLAGS_UNWIND)
|
||||||
@ -58,7 +56,6 @@ ECHO:
|
|||||||
@echo "$@"
|
@echo "$@"
|
||||||
|
|
||||||
$(kernel_subdirs): ECHO
|
$(kernel_subdirs): ECHO
|
||||||
|
|
||||||
$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" kernel_root_path="$(shell pwd)"
|
$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" kernel_root_path="$(shell pwd)"
|
||||||
|
|
||||||
kernel: $(kernel_subdirs) kernel_rust
|
kernel: $(kernel_subdirs) kernel_rust
|
||||||
@ -66,7 +63,26 @@ kernel: $(kernel_subdirs) kernel_rust
|
|||||||
__link_riscv64_kernel:
|
__link_riscv64_kernel:
|
||||||
@echo "Linking kernel..."
|
@echo "Linking kernel..."
|
||||||
$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/riscv64gc-unknown-none-elf/release/libdragonos_kernel.a -T arch/riscv64/link.ld --no-relax
|
$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/riscv64gc-unknown-none-elf/release/libdragonos_kernel.a -T arch/riscv64/link.ld --no-relax
|
||||||
|
# 生成kallsyms
|
||||||
|
current_dir=$(pwd)
|
||||||
|
|
||||||
|
@dbg='debug';for x in $$dbg; do \
|
||||||
|
cd $$x;\
|
||||||
|
$(MAKE) generate_kallsyms kernel_root_path="$(shell pwd)"||exit 1;\
|
||||||
|
cd ..;\
|
||||||
|
done
|
||||||
|
|
||||||
|
# 重新链接
|
||||||
|
@echo "Re-Linking kernel..."
|
||||||
|
@echo $(shell find . -name "*.o")
|
||||||
|
$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/riscv64gc-unknown-none-elf/release/libdragonos_kernel.a ./debug/kallsyms.o -T arch/riscv64/link.ld --no-relax
|
||||||
|
@echo "Generating kernel ELF file..."
|
||||||
|
|
||||||
|
ifeq ($(UNWIND_ENABLE), yes)
|
||||||
|
$(OBJCOPY) -I elf64-littleriscv -O elf64-littleriscv kernel ../../bin/kernel/kernel.elf
|
||||||
|
else
|
||||||
$(OBJCOPY) -I elf64-littleriscv -O elf64-littleriscv -R ".eh_frame" kernel ../../bin/kernel/kernel.elf
|
$(OBJCOPY) -I elf64-littleriscv -O elf64-littleriscv -R ".eh_frame" kernel ../../bin/kernel/kernel.elf
|
||||||
|
endif
|
||||||
@rm kernel
|
@rm kernel
|
||||||
$(MAKE) __dragon_stub PAYLOAD_ELF="$(shell pwd)/../../bin/kernel/kernel.elf"
|
$(MAKE) __dragon_stub PAYLOAD_ELF="$(shell pwd)/../../bin/kernel/kernel.elf"
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ SECTIONS
|
|||||||
|
|
||||||
. = ALIGN(4096);
|
. = ALIGN(4096);
|
||||||
text_start_pa = .;
|
text_start_pa = .;
|
||||||
|
__executable_start = .;
|
||||||
.text (text_start_pa): AT(text_start_pa - KERNEL_VMA)
|
.text (text_start_pa): AT(text_start_pa - KERNEL_VMA)
|
||||||
{
|
{
|
||||||
_text = .;
|
_text = .;
|
||||||
@ -39,6 +40,7 @@ SECTIONS
|
|||||||
*(.text.*)
|
*(.text.*)
|
||||||
|
|
||||||
_etext = .;
|
_etext = .;
|
||||||
|
__etext = .;
|
||||||
}
|
}
|
||||||
. = ALIGN(32768);
|
. = ALIGN(32768);
|
||||||
data_start_pa = .;
|
data_start_pa = .;
|
||||||
|
28
kernel/src/arch/riscv64/riscv64gc-unknown-none-elf.json
Normal file
28
kernel/src/arch/riscv64/riscv64gc-unknown-none-elf.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"arch": "riscv64",
|
||||||
|
"code-model": "medium",
|
||||||
|
"cpu": "generic-rv64",
|
||||||
|
"crt-objects-fallback": "false",
|
||||||
|
"data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
||||||
|
"eh-frame-header": false,
|
||||||
|
"emit-debug-gdb-scripts": false,
|
||||||
|
"features": "+m,+a,+f,+d,+c",
|
||||||
|
"linker": "rust-lld",
|
||||||
|
"linker-flavor": "gnu-lld",
|
||||||
|
"llvm-abiname": "lp64d",
|
||||||
|
"llvm-target": "riscv64",
|
||||||
|
"max-atomic-width": 64,
|
||||||
|
"metadata": {
|
||||||
|
"description": "Bare RISC-V (RV64IMAFDC ISA)",
|
||||||
|
"host_tools": false,
|
||||||
|
"std": false,
|
||||||
|
"tier": 2
|
||||||
|
},
|
||||||
|
"panic-strategy": "unwind",
|
||||||
|
"relocation-model": "static",
|
||||||
|
"supported-sanitizers": [
|
||||||
|
"shadow-call-stack",
|
||||||
|
"kernel-address"
|
||||||
|
],
|
||||||
|
"target-pointer-width": "64"
|
||||||
|
}
|
@ -36,7 +36,8 @@ 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!(
|
syscall_return!(
|
||||||
Syscall::handle(syscall_num, &args, frame).unwrap_or_else(|e| e.to_posix_errno() as usize),
|
Syscall::catch_handle(syscall_num, &args, frame)
|
||||||
|
.unwrap_or_else(|e| e.to_posix_errno() as usize),
|
||||||
frame,
|
frame,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
@ -26,6 +26,7 @@ SECTIONS
|
|||||||
. = ALIGN(32768);
|
. = ALIGN(32768);
|
||||||
. += KERNEL_VMA;
|
. += KERNEL_VMA;
|
||||||
text_start_pa = .;
|
text_start_pa = .;
|
||||||
|
__executable_start = .;
|
||||||
.text (text_start_pa): AT(text_start_pa - KERNEL_VMA)
|
.text (text_start_pa): AT(text_start_pa - KERNEL_VMA)
|
||||||
{
|
{
|
||||||
_text = .;
|
_text = .;
|
||||||
@ -37,6 +38,7 @@ SECTIONS
|
|||||||
*(.text.*)
|
*(.text.*)
|
||||||
|
|
||||||
_etext = .;
|
_etext = .;
|
||||||
|
__etext = .;
|
||||||
}
|
}
|
||||||
. = ALIGN(32768);
|
. = ALIGN(32768);
|
||||||
data_start_pa = .;
|
data_start_pa = .;
|
||||||
|
@ -118,8 +118,8 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
syscall_return!(
|
syscall_return!(
|
||||||
Syscall::handle(syscall_num, &args, frame).unwrap_or_else(|e| e.to_posix_errno() as usize)
|
Syscall::catch_handle(syscall_num, &args, frame)
|
||||||
as u64,
|
.unwrap_or_else(|e| e.to_posix_errno() as usize) as u64,
|
||||||
frame,
|
frame,
|
||||||
show
|
show
|
||||||
);
|
);
|
||||||
|
@ -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": "abort"
|
"panic-strategy": "unwind"
|
||||||
}
|
}
|
||||||
|
@ -94,8 +94,11 @@ extern crate wait_queue_macros;
|
|||||||
|
|
||||||
use crate::mm::allocator::kernel_allocator::KernelAllocator;
|
use crate::mm::allocator::kernel_allocator::KernelAllocator;
|
||||||
|
|
||||||
#[cfg(all(feature = "backtrace", target_arch = "x86_64"))]
|
#[cfg(feature = "backtrace")]
|
||||||
extern crate mini_backtrace;
|
use unwinding::{
|
||||||
|
abi::{UnwindContext, UnwindReasonCode, _Unwind_GetIP},
|
||||||
|
panic::UserUnwindTrace,
|
||||||
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn lookup_kallsyms(addr: u64, level: i32) -> i32;
|
fn lookup_kallsyms(addr: u64, level: i32) -> i32;
|
||||||
@ -106,12 +109,37 @@ extern "C" {
|
|||||||
pub static KERNEL_ALLOCATOR: KernelAllocator = KernelAllocator;
|
pub static KERNEL_ALLOCATOR: KernelAllocator = KernelAllocator;
|
||||||
|
|
||||||
/// 全局的panic处理函数
|
/// 全局的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")]
|
#[cfg(target_os = "none")]
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn panic(info: &PanicInfo) -> ! {
|
pub fn panic(info: &PanicInfo) -> ! {
|
||||||
use log::error;
|
use log::error;
|
||||||
use process::ProcessManager;
|
|
||||||
|
|
||||||
error!("Kernel Panic Occurred.");
|
error!("Kernel Panic Occurred.");
|
||||||
|
|
||||||
@ -129,21 +157,41 @@ pub fn panic(info: &PanicInfo) -> ! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("Message:\n\t{}", info.message());
|
println!("Message:\n\t{}", info.message());
|
||||||
|
#[cfg(feature = "backtrace")]
|
||||||
#[cfg(all(feature = "backtrace", target_arch = "x86_64"))]
|
|
||||||
{
|
{
|
||||||
unsafe {
|
let mut data = CallbackData { counter: 0 };
|
||||||
let bt = mini_backtrace::Backtrace::<16>::capture();
|
println!("Rust Panic Backtrace:");
|
||||||
println!("Rust Panic Backtrace:");
|
let res = unwinding::panic::begin_panic_with_hook::<Tracer>(
|
||||||
let mut level = 0;
|
alloc::boxed::Box::new(()),
|
||||||
for frame in bt.frames {
|
&mut data,
|
||||||
lookup_kallsyms(frame as u64, level);
|
);
|
||||||
level += 1;
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Current PCB:\n\t{:?}", (ProcessManager::current_pcb()));
|
|
||||||
|
|
||||||
ProcessManager::exit(usize::MAX);
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
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},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -10,6 +11,7 @@ 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},
|
||||||
@ -74,6 +76,19 @@ impl Syscall {
|
|||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
/// 系统调用分发器,用于分发系统调用。
|
||||||
|
///
|
||||||
|
/// 与[handle]不同,这个函数会捕获系统调用处理函数的panic,返回错误码。
|
||||||
|
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();
|
||||||
|
})
|
||||||
|
}
|
||||||
/// @brief 系统调用分发器,用于分发系统调用。
|
/// @brief 系统调用分发器,用于分发系统调用。
|
||||||
///
|
///
|
||||||
/// 这个函数内,需要根据系统调用号,调用对应的系统调用处理函数。
|
/// 这个函数内,需要根据系统调用号,调用对应的系统调用处理函数。
|
||||||
|
Loading…
x
Reference in New Issue
Block a user