Skip to content

Commit 6dcf31f

Browse files
committed
better backtrace
thanks [PR](rcore-os/rCore-Tutorial-v3#105) by Godones
1 parent 6380d07 commit 6dcf31f

File tree

11 files changed

+138
-20
lines changed

11 files changed

+138
-20
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
os/src/link_app.S
66
os/src/linker.ld
77
user/build
8+
9+
os/src/trace/kernel_symbol.S

os/Cargo.lock

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

os/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "4e
1515
easy-fs = { path = "../easy-fs" }
1616
volatile = "0.3"
1717
lose-net-stack = { git = "https://github.com/yfblock/lose-net-stack", rev = "db42380" }
18+
tracer = { git = "https://github.com/os-module/rtrace" }
19+
20+
[profile.release]
21+
debug = true

os/Makefile

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ KERNEL_ENTRY_PA := 0x80200000
3131
OBJDUMP := rust-objdump --arch-name=riscv64
3232
OBJCOPY := rust-objcopy --binary-architecture=riscv64
3333

34-
# Disassembly
35-
DISASM ?= -x
34+
# Disassembly (--disassemble-all)
35+
DISASM ?= -D
3636

3737
# Run usertests or usershell
3838
TEST ?= 0
@@ -44,7 +44,7 @@ ifneq ($(strip $(USE_DISK)),)
4444
FS_IMG := $(USE_DISK)
4545
endif
4646

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

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

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

6568
kernel:
6669
@echo Platform: $(BOARD)
70+
@touch src/trace/kernel_symbol.S && rm src/trace/kernel_symbol.S
6771
@cp src/linker-$(BOARD).ld src/linker.ld
6872
@cargo build $(MODE_ARG)
73+
@(nm -n ${KERNEL_ELF} | trace_exe > src/trace/kernel_symbol.S)
74+
@cargo build $(MODE_ARG)
6975
@rm src/linker.ld
7076

7177
clean:

os/build.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
1+
use std::{fs::File, io::Write, path::Path};
2+
13
const TARGET_PATH: &str = "../user/target/riscv64gc-unknown-none-elf/release/";
24

35
fn main() {
46
println!("cargo:rerun-if-changed=../user/src");
57
println!("cargo:rerun-if-changed={}", TARGET_PATH);
8+
println!("cargo:rerun-if-changed={}", "src");
9+
let path = Path::new("src/trace/kernel_symbol.S");
10+
if !path.exists() {
11+
let mut f = File::create(path).unwrap();
12+
writeln!(
13+
f,
14+
r#"
15+
.section .rodata
16+
.align 3
17+
.globl symbol_num
18+
.globl symbol_address
19+
.globl symbol_index
20+
.globl symbol_name
21+
symbol_num:
22+
.quad {}
23+
symbol_address:
24+
symbol_index:
25+
symbol_name:"#,
26+
0
27+
)
28+
.unwrap();
29+
}
630
}

os/src/lang_item.rs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
use core::{arch::asm, panic::PanicInfo};
1+
use core::panic::PanicInfo;
22

3-
use crate::{sbi::shutdown, task::current_kstack_top};
3+
use tracer::{FramePointTracer, Tracer};
4+
5+
use crate::sbi::shutdown;
46

57
#[panic_handler]
68
fn panic(info: &PanicInfo) -> ! {
@@ -14,23 +16,15 @@ fn panic(info: &PanicInfo) -> ! {
1416
} else {
1517
log::error!("Panicked: {}", info.message());
1618
}
17-
unsafe {
18-
backtrace();
19-
}
19+
backtrace();
2020
shutdown(true)
2121
}
2222

23-
unsafe fn backtrace() {
24-
let mut fp: usize;
25-
let stop = current_kstack_top();
26-
asm!("mv {}, s0", out(reg) fp);
23+
fn backtrace() {
2724
println!("---START BACKTRACE---");
28-
for i in 0..10 {
29-
if fp == stop {
30-
break;
31-
}
32-
println!("#{}:ra={:#x}", i, *((fp - 8) as *const usize));
33-
fp = *((fp - 16) as *const usize);
25+
let tracer = FramePointTracer::new(crate::trace::Provider);
26+
for v in tracer.trace() {
27+
println!("[{:#x}] (+{:0>4x}) {}", v.func_addr, v.bias, v.func_name);
3428
}
3529
println!("---END BACKTRACE---");
3630
}

os/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ mod sync;
2525
mod syscall;
2626
mod task;
2727
mod timer;
28+
mod trace;
2829
mod trap;
2930

3031
use core::arch::global_asm;

os/src/syscall/process.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ pub fn sys_exec(path: *const u8, mut args: *const usize) -> isize {
9898

9999
/// If there is not a child process whose pid is same as given, return -1.
100100
/// Else if there is a child process but it is still running, return -2.
101+
#[inline(never)]
101102
pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
102103
let proc = current_process();
103104
let mut inner = proc.inner_exclusive_access();

os/src/task/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ pub use manager::{add_task, pid2process, wakeup_task};
2222
pub use mem::*;
2323
pub use process::{FileMapping, MMapReserve, MapRange, ProcessControlBlock};
2424
pub use processor::{
25-
current_kstack_top, current_process, current_task, current_trap_cx, current_trap_cx_user_va,
26-
current_user_token, run_tasks, schedule, user_time_end, user_time_start,
25+
current_process, current_task, current_trap_cx, current_trap_cx_user_va, current_user_token,
26+
run_tasks, schedule, user_time_end, user_time_start,
2727
};
2828
pub use signal::{SignalFlags, MAX_SIG};
2929
pub use task::{TaskControlBlock, TaskStatus};

os/src/task/processor.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ pub fn current_trap_cx_user_va() -> usize {
9393
.trap_cx_user_va()
9494
}
9595

96+
#[allow(unused)]
9697
pub fn current_kstack_top() -> usize {
9798
if let Some(task) = current_task() {
9899
task.kstack.get_top()

0 commit comments

Comments
 (0)