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

Reply via email to