This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 7c75dbae2be880c62e84e642b243d35113ae3b77
Author: liang.huang <[email protected]>
AuthorDate: Sat Jul 18 08:12:10 2026 +0800

    arch/risc-v: preserve ra in up_idle() for fp-chain backtrace
    
    up_idle() is a leaf function; with frame pointers enabled the compiler
    skips spilling ra, corrupting the fp chain.  Clobber "ra" in the WFI
    inline asm so backtrace can walk past the idle frame correctly.
    
    Assisted-by: Claude Code:claude-sonnet-5
    Signed-off-by: liang.huang <[email protected]>
---
 arch/risc-v/src/common/riscv_idle.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/risc-v/src/common/riscv_idle.c 
b/arch/risc-v/src/common/riscv_idle.c
index d6f0d02dcbf..6953a38bdca 100644
--- a/arch/risc-v/src/common/riscv_idle.c
+++ b/arch/risc-v/src/common/riscv_idle.c
@@ -71,7 +71,18 @@ void up_idle(void)
    * sleep in a reduced power mode until an interrupt occurs to save power
    */
 
-  asm("WFI");
+  /* up_idle() never calls another function, so with frame pointers
+   * enabled the compiler has no need to spill ra and skips it, leaving
+   * its slot in the fp-chain holding whatever was on the stack before.
+   * Clobbering "ra" forces it to be spilled/reloaded around WFI so the
+   * fp-chain backtrace sched_backtrace() relies on can find it.
+   */
+
+#if defined(CONFIG_FRAME_POINTER) && defined(CONFIG_SCHED_BACKTRACE)
+  asm volatile ("WFI" : : : "ra");
+#else
+  asm volatile ("WFI");
+#endif
 
 #endif
 }

Reply via email to