Skip to content

Commit

Permalink
better backtrace
Browse files Browse the repository at this point in the history
thanks [PR](rcore-os/rCore-Tutorial-v3#105) by Godones
  • Loading branch information
lythesia committed Dec 13, 2024
1 parent 6380d07 commit 6dcf31f
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 20 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
os/src/link_app.S
os/src/linker.ld
user/build

os/src/trace/kernel_symbol.S
17 changes: 17 additions & 0 deletions os/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions os/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "4e
easy-fs = { path = "../easy-fs" }
volatile = "0.3"
lose-net-stack = { git = "https://github.com/yfblock/lose-net-stack", rev = "db42380" }
tracer = { git = "https://github.com/os-module/rtrace" }

[profile.release]
debug = true
12 changes: 9 additions & 3 deletions os/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ KERNEL_ENTRY_PA := 0x80200000
OBJDUMP := rust-objdump --arch-name=riscv64
OBJCOPY := rust-objcopy --binary-architecture=riscv64

# Disassembly
DISASM ?= -x
# Disassembly (--disassemble-all)
DISASM ?= -D

# Run usertests or usershell
TEST ?= 0
Expand All @@ -44,7 +44,7 @@ ifneq ($(strip $(USE_DISK)),)
FS_IMG := $(USE_DISK)
endif

build: env $(KERNEL_BIN) $(if $(strip $(USE_DISK)), ,fs-img)
build: env stack_trace $(KERNEL_BIN) $(if $(strip $(USE_DISK)), ,fs-img)

env:
(rustup target list | grep "riscv64gc-unknown-none-elf (installed)") || rustup target add $(TARGET)
Expand All @@ -61,11 +61,17 @@ fs-img: $(APPS)
@cd ../easy-fs-fuse && cargo run --release -- -s ../user/src/bin -t ../user/target/$(TARGET)/$(MODE)/

$(APPS):
# install trace_exe to generate elf symbol info
stack_trace:
(cargo install --list | awk '/^\w/ {print $1}' | grep "cargo-binutils") || cargo install --git https://github.com/os-module/elfinfo

kernel:
@echo Platform: $(BOARD)
@touch src/trace/kernel_symbol.S && rm src/trace/kernel_symbol.S
@cp src/linker-$(BOARD).ld src/linker.ld
@cargo build $(MODE_ARG)
@(nm -n ${KERNEL_ELF} | trace_exe > src/trace/kernel_symbol.S)
@cargo build $(MODE_ARG)
@rm src/linker.ld

clean:
Expand Down
24 changes: 24 additions & 0 deletions os/build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
use std::{fs::File, io::Write, path::Path};

const TARGET_PATH: &str = "../user/target/riscv64gc-unknown-none-elf/release/";

fn main() {
println!("cargo:rerun-if-changed=../user/src");
println!("cargo:rerun-if-changed={}", TARGET_PATH);
println!("cargo:rerun-if-changed={}", "src");
let path = Path::new("src/trace/kernel_symbol.S");
if !path.exists() {
let mut f = File::create(path).unwrap();
writeln!(
f,
r#"
.section .rodata
.align 3
.globl symbol_num
.globl symbol_address
.globl symbol_index
.globl symbol_name
symbol_num:
.quad {}
symbol_address:
symbol_index:
symbol_name:"#,
0
)
.unwrap();
}
}
24 changes: 9 additions & 15 deletions os/src/lang_item.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use core::{arch::asm, panic::PanicInfo};
use core::panic::PanicInfo;

use crate::{sbi::shutdown, task::current_kstack_top};
use tracer::{FramePointTracer, Tracer};

use crate::sbi::shutdown;

#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
Expand All @@ -14,23 +16,15 @@ fn panic(info: &PanicInfo) -> ! {
} else {
log::error!("Panicked: {}", info.message());
}
unsafe {
backtrace();
}
backtrace();
shutdown(true)
}

unsafe fn backtrace() {
let mut fp: usize;
let stop = current_kstack_top();
asm!("mv {}, s0", out(reg) fp);
fn backtrace() {
println!("---START BACKTRACE---");
for i in 0..10 {
if fp == stop {
break;
}
println!("#{}:ra={:#x}", i, *((fp - 8) as *const usize));
fp = *((fp - 16) as *const usize);
let tracer = FramePointTracer::new(crate::trace::Provider);
for v in tracer.trace() {
println!("[{:#x}] (+{:0>4x}) {}", v.func_addr, v.bias, v.func_name);
}
println!("---END BACKTRACE---");
}
1 change: 1 addition & 0 deletions os/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ mod sync;
mod syscall;
mod task;
mod timer;
mod trace;
mod trap;

use core::arch::global_asm;
Expand Down
1 change: 1 addition & 0 deletions os/src/syscall/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ pub fn sys_exec(path: *const u8, mut args: *const usize) -> isize {

/// If there is not a child process whose pid is same as given, return -1.
/// Else if there is a child process but it is still running, return -2.
#[inline(never)]
pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
let proc = current_process();
let mut inner = proc.inner_exclusive_access();
Expand Down
4 changes: 2 additions & 2 deletions os/src/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ pub use manager::{add_task, pid2process, wakeup_task};
pub use mem::*;
pub use process::{FileMapping, MMapReserve, MapRange, ProcessControlBlock};
pub use processor::{
current_kstack_top, current_process, current_task, current_trap_cx, current_trap_cx_user_va,
current_user_token, run_tasks, schedule, user_time_end, user_time_start,
current_process, current_task, current_trap_cx, current_trap_cx_user_va, current_user_token,
run_tasks, schedule, user_time_end, user_time_start,
};
pub use signal::{SignalFlags, MAX_SIG};
pub use task::{TaskControlBlock, TaskStatus};
Expand Down
1 change: 1 addition & 0 deletions os/src/task/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ pub fn current_trap_cx_user_va() -> usize {
.trap_cx_user_va()
}

#[allow(unused)]
pub fn current_kstack_top() -> usize {
if let Some(task) = current_task() {
task.kstack.get_top()
Expand Down
68 changes: 68 additions & 0 deletions os/src/trace/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use core::arch::global_asm;

use tracer::TracerProvider;

global_asm!(include_str!("kernel_symbol.S"));

extern "C" {
fn symbol_num();
fn symbol_address();
fn symbol_index();
fn symbol_name();
}

pub struct Provider;

impl TracerProvider for Provider {
fn address2symbol(&self, addr: usize) -> Option<(usize, &'static str)> {
find_symbol_with_addr(addr)
}
}

pub fn find_symbol_with_addr(addr: usize) -> Option<(usize, &'static str)> {
// println!("find_sym_w/addr {:#x}", addr);
let symbol_num_addr = symbol_num as usize as *const usize;
// println!("symbol_num_addr {:#x}", symbol_num_addr as usize);
let symbol_num = unsafe { symbol_num_addr.read_volatile() };
// println!("num = {}", symbol_num);
if symbol_num == 0 {
return None;
}
let symbol_addr = symbol_address as usize as *const usize; // 符号地址存储区域
let addr_data = unsafe { core::slice::from_raw_parts(symbol_addr, symbol_num) };
// find the symbol with the nearest address
let mut index = -1isize;
for i in 0..symbol_num - 1 {
if addr >= addr_data[i] && addr < addr_data[i + 1] {
index = i as isize;
break;
}
}
if addr == addr_data[symbol_num - 1] {
index = (symbol_num - 1) as isize;
}
// println!("nearest addr to index = {}", index);
if index == -1 {
return None;
}
let index = index as usize;
let symbol_index = symbol_index as usize as *const usize; // 符号字符串的起始位置
let index_data = unsafe { core::slice::from_raw_parts(symbol_index, symbol_num) };
let symbol_name = symbol_name as usize as *const u8; // 符号字符串
let mut last = 0;
unsafe {
for i in index_data[index].. {
let c = symbol_name.add(i);
if *c == 0 {
last = i;
break;
}
}
}
let name = unsafe {
core::slice::from_raw_parts(symbol_name.add(index_data[index]), last - index_data[index])
};
let name = core::str::from_utf8(name).unwrap();
// println!("symbol = {}", name);
Some((addr_data[index], name))
}

0 comments on commit 6dcf31f

Please sign in to comment.