mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
The previous up_backtrace() relied entirely on host_backtrace() (a thin wrapper around glibc's backtrace()), which can only unwind the host thread that calls it. As a result, when assert / dump_tasks() walked the task list and called sched_dumpstack() for every task, every task other than the currently-running one returned a zero-length backtrace, and the output was silently dropped. In practice this meant that on sim only the crashing task ever produced a usable trace. Fix this by walking the frame-pointer chain ourselves whenever the target tcb is not the running task. Because sim's setjmp/longjmp is provided by NuttX itself (libs/libc/machine/sim/arch_setjmp_*.S) and not by host libc, the rbp/rsp/rip (or arm fp/sp/pc) saved in tcb->xcp.regs are plain unmangled pointers, identical across Linux, macOS and Windows hosts. The frame layout ([fp]=prev fp, [fp+1]=return address) is also shared by every host ABI sim supports (x86, x86_64, ARM, ARM64). The walker validates that fp lies inside the task's stack and is properly aligned, and stops when fp[0] is NULL, so a corrupted stack cannot make us read out of bounds. The running-task path is unchanged and still uses host_backtrace() so DWARF unwinding through host libraries continues to work. Requires CONFIG_FRAME_POINTER=y so the compiler emits a usable fp link. Signed-off-by: Lingao Meng <menglingao@xiaomi.com> |
||
|---|---|---|
| .. | ||
| arm | ||
| arm64 | ||
| avr | ||
| ceva | ||
| dummy | ||
| hc | ||
| mips | ||
| misoc | ||
| or1k | ||
| renesas | ||
| risc-v | ||
| sim | ||
| sparc | ||
| tricore | ||
| x86 | ||
| x86_64 | ||
| xtensa | ||
| z16 | ||
| z80 | ||
| CMakeLists.txt | ||
| Kconfig | ||