This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 16a4ab53facb0bddf562373fb954c0cae7d0a609 Author: liang.huang <[email protected]> AuthorDate: Wed Jul 15 12:12:57 2026 +0800 arch/risc-v: fix stale ustkptr used for backtrace in kernel stack mode xcp.ustkptr is only assigned once in up_initial_state() when a task is created and, since the syscall fast path was optimized in e6973c764c, is never updated afterwards. up_backtrace() used "ustkptr != NULL" to decide whether a task is currently blocked inside a syscall, and *(ustkptr + 1) as the frame pointer to resume tracing from. Since ustkptr is now a dead value fixed at task creation time, the check is always true and the "frame pointer" it derives points at stale data near the initial stack top, unrelated to where the task is actually blocked. Use rtcb->flags & TCB_FLAG_SYSCALL together with xcp.sregs, which dispatch_syscall() maintains precisely across the entire syscall execution window (including any nested context switches caused by blocking), to locate the frame pointer/return address saved at syscall entry instead. Signed-off-by: liang.huang <[email protected]> --- arch/risc-v/src/common/riscv_backtrace.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/risc-v/src/common/riscv_backtrace.c b/arch/risc-v/src/common/riscv_backtrace.c index 947a7f9dbde..052aea9dfd7 100644 --- a/arch/risc-v/src/common/riscv_backtrace.c +++ b/arch/risc-v/src/common/riscv_backtrace.c @@ -180,12 +180,13 @@ int up_backtrace(struct tcb_s *tcb, void **buffer, int size, int skip) else { #ifdef CONFIG_ARCH_KERNEL_STACK - if (rtcb->xcp.ustkptr != NULL) + if ((rtcb->flags & TCB_FLAG_SYSCALL) != 0) { ret = backtrace(rtcb->stack_base_ptr, (uintptr_t *) ((uintptr_t)rtcb->stack_base_ptr + rtcb->adj_stack_size), - (void *)*(rtcb->xcp.ustkptr + 1), NULL, + (void *)rtcb->xcp.sregs[REG_FP], + (void *)rtcb->xcp.sregs[REG_EPC], buffer, size, &skip); } else @@ -201,12 +202,13 @@ int up_backtrace(struct tcb_s *tcb, void **buffer, int size, int skip) else { #ifdef CONFIG_ARCH_KERNEL_STACK - if (tcb->xcp.ustkptr != NULL) + if ((tcb->flags & TCB_FLAG_SYSCALL) != 0) { ret = backtrace(tcb->stack_base_ptr, (uintptr_t *)((uintptr_t)tcb->stack_base_ptr + tcb->adj_stack_size), - (void *)*(tcb->xcp.ustkptr + 1), NULL, + (void *)tcb->xcp.sregs[REG_FP], + (void *)tcb->xcp.sregs[REG_EPC], buffer, size, &skip); } else
