SimpleKernel 1.17.0
Loading...
Searching...
No Matches
backtrace.cpp File Reference
#include <cpu_io.h>
#include <elf.h>
#include <array>
#include <cstdint>
#include "arch.h"
#include "basic_info.hpp"
#include "kernel.h"
#include "kernel_elf.hpp"
#include "kernel_log.hpp"
Include dependency graph for backtrace.cpp:

Go to the source code of this file.

Functions

__always_inline auto backtrace (std::array< uint64_t, kMaxFrameCount > &buffer) -> int
 
auto DumpStack () -> void
 打印调用栈
 

Function Documentation

◆ backtrace()

__always_inline auto backtrace ( std::array< uint64_t, kMaxFrameCount > &  buffer) -> int

Definition at line 17 of file backtrace.cpp.

18 {
19 auto fp_value = cpu_io::Fp::Read();
20 size_t count = 0;
21
22 // RISC-V 栈帧布局 (使用 -fno-omit-frame-pointer):
23 // fp[-1] (fp - 8): 保存的返回地址 (ra)
24 // fp[-2] (fp - 16): 保存的上一个帧指针 (saved fp)
25
26 while ((fp_value & 0x07) == 0 && count < buffer.max_size()) {
27 auto* fp = reinterpret_cast<uint64_t*>(fp_value);
28 auto ra = *(fp - 1);
29 auto saved_fp = *(fp - 2);
30
31 // 检查返回地址是否在代码段范围内
32 if (ra < reinterpret_cast<uint64_t>(__executable_start) ||
33 ra > reinterpret_cast<uint64_t>(__etext)) {
34 break;
35 }
36
37 buffer[count++] = ra;
38
39 // 如果 saved_fp 为 0 或无效,停止遍历
40 if (saved_fp == 0) {
41 break;
42 }
43 fp_value = saved_fp;
44 }
45 return static_cast<int>(count);
46}
void * __etext[]
代码段结束
void * __executable_start[]

◆ DumpStack()

auto DumpStack ( ) -> void

打印调用栈

Note
调用 backtrace 获取调用栈并解析符号后输出到日志

Definition at line 48 of file backtrace.cpp.

48 {
49 std::array<uint64_t, kMaxFrameCount> buffer{};
50
51 // 获取调用栈中的地址
52 auto num_frames = backtrace(buffer);
53
54 // 打印函数名
55 for (auto current_frame_idx = 0; current_frame_idx < num_frames;
56 current_frame_idx++) {
57 for (auto symtab : KernelElfSingleton::instance().symtab) {
58 if ((ELF64_ST_TYPE(symtab.st_info) == STT_FUNC) &&
59 (buffer[current_frame_idx] >= symtab.st_value) &&
60 (buffer[current_frame_idx] <= symtab.st_value + symtab.st_size)) {
61 klog::Err("[{}] {:#x}",
62 reinterpret_cast<const char*>(
63 KernelElfSingleton::instance().strtab + symtab.st_name),
64 buffer[current_frame_idx]);
65 }
66 }
67 }
68}
__always_inline auto backtrace(std::array< uint64_t, kMaxFrameCount > &buffer) -> int
Definition backtrace.cpp:18
etl::singleton< KernelElf > KernelElfSingleton
auto Err(etl::format_string< Args... > fmt, Args &&... args) -> void
以 ERROR 级别记录日志
Here is the call graph for this function: