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

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

commit 589255498412a0a8ac328e4fdeaff96bbc3f77f5
Author: yinshengkai <[email protected]>
AuthorDate: Mon Dec 1 19:43:23 2025 +0800

    arch/arm64: fix backtrace return address precision
    
    The return address stored in the frame should point to the instruction
    after the call. To get the actual call site, we need to subtract the
    instruction size (sizeof(void *)) from the saved return address.
    
    This ensures that backtrace addresses correctly point to the calling
    instruction rather than the next instruction.
    
    Signed-off-by: yinshengkai <[email protected]>
---
 arch/arm64/src/common/arm64_backtrace.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/src/common/arm64_backtrace.c 
b/arch/arm64/src/common/arm64_backtrace.c
index 828a16aecd5..4d642ef4446 100644
--- a/arch/arm64/src/common/arm64_backtrace.c
+++ b/arch/arm64/src/common/arm64_backtrace.c
@@ -44,6 +44,19 @@
  * Description:
  *  backtrace() parsing the return address through frame pointer
  *
+ * Note:
+ *
+ *  The stack layout is as follows:
+ *
+ *    Stack (grows downward):
+ *                +--------------------+
+ *    high addr   |  locals of A       |
+ *                +--------------------+
+ *                | prev_fp(A)=0       | ← FP of A (first frame)
+ *                | saved_lr(A)        |
+ *                +--------------------+
+ *                | locals of B        |
+ *
  ****************************************************************************/
 
 nosanitize_address
@@ -57,7 +70,7 @@ static int backtrace(uintptr_t *base, uintptr_t *limit,
     {
       if ((*skip)-- <= 0)
         {
-          buffer[i++] = pc;
+          buffer[i++] = (void *)((uintptr_t)pc - sizeof(void *));
         }
     }
 
@@ -70,7 +83,7 @@ static int backtrace(uintptr_t *base, uintptr_t *limit,
 
       if ((*skip)-- <= 0)
         {
-          buffer[i++] = (void *)*(fp + 1);
+          buffer[i++] = (void *)(*(fp + 1) - sizeof(void *));
         }
     }
 

Reply via email to