| 15 | #include "kernel_log.hpp" |
| 16 | |
| 17 | __always_inline auto backtrace(std::array<uint64_t, kMaxFrameCount>& buffer) |
| 18 | -> int { |
| 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 | } |
| 47 | |
| 48 | auto DumpStack() -> void { |
| 49 | std::array<uint64_t, kMaxFrameCount> buffer{}; |