Trying again with the screenshot in text of what's going on. > It happens that NuttX release 12.6.0 generates code that has SP not aligned to 4 bytes as shown below, right before triggering SVC.
``` │ 170 /* SVC with SYS_ call number and two parameters */ │ │ 171 │ │ 172 static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, │ │ 173 uintptr_t parm2) │ │ 174 { │ │ 175 register long reg0 __asm__("r0") = (long)(nbr); │ │ 176 register long reg2 __asm__("r2") = (long)(parm2); │ │ 177 register long reg1 __asm__("r1") = (long)(parm1); │ │ 178 │ │ > 179 __asm__ __volatile__ │ │ 180 ( │ │ 181 "svc %1" │ │ 182 : "=r"(reg0) │ │ 183 : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2) │ ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │B+ 0xaaf8 <up_switch_context> push {lr} │ │ 0xaafa <up_switch_context+2> ldr r2, [pc, #32] @ (0xab1c <up_switch_context+36>) │ │ 0xaafc <up_switch_context+4> mov r3, r0 │ │ 0xaafe <up_switch_context+6> ldr r0, [r2, #0] │ │ 0xab00 <up_switch_context+8> cbz r0, 0xab10 <up_switch_context+24> │ │ 0xab02 <up_switch_context+10> str.w r0, [r1, #156] @ 0x9c │ │ 0xab06 <up_switch_context+14> ldr.w r3, [r3, #156] @ 0x9c │ │ 0xab0a <up_switch_context+18> str r3, [r2, #0] │ │ 0xab0c <up_switch_context+20> ldr.w pc, [sp], #4 │ │ 0xab10 <up_switch_context+24> movs r0, #2 │ │ 0xab12 <up_switch_context+26> ldr.w r2, [r3, #156] @ 0x9c │ │ 0xab16 <up_switch_context+30> adds r1, #156 @ 0x9c │ │ >0xab18 <up_switch_context+32> svc 0 (gdb) p/x $sp $3 = 0x2000667c ``` > According to the documentation, we can distinguish this situation from xPSR[9] bit. xPSR is pushed to stack automatically. ``` │ 124 exception_common: │ │ 125 │ │ > 126 mrs r0, ipsr /* R0=exception number */ (gdb) p/x $sp $5 = 0x20006658 (gdb) x/32x 0x20006658 0x20006658: 0x00000002 0x20005c5c 0x20004f28 0x20001688 0x20006668: 0x00000001 0x00004f51 0x0000ab1a **0x01000200** <-- this is xPSR ``` > In this case, the real SP after restore should be `SP + 4`. After adjusting it manually, now GDB can unwind correctly. ``` (gdb) set $sp=$sp+4 (gdb) bt #0 up_switch_context (tcb=0x20001688 <g_idletcb>, rtcb=rtcb@entry=0x20005bc0) at common/arm_switchcontext.c:95 #1 0x00004f50 in nxsem_wait (sem=sem@entry=0x2000001c <g_uart0port+28>) at semaphore/sem_wait.c:175 #2 0x00008192 in uart_read (filep=0x20005ecc, buffer=0x200066ef "", buflen=1) at serial/serial.c:1058 #3 0x00015910 in nx_read (fd=<optimized out>, buf=buf@entry=0x200066ef, nbytes=nbytes@entry=1) at vfs/fs_read.c:140 #4 0x0001591a in read (fd=<optimized out>, buf=buf@entry=0x200066ef, nbytes=nbytes@entry=1) at vfs/fs_read.c:170 #5 0x0000b04a in readline_getc (vtbl=0x2000672c) at readline_fd.c:72 #6 0x0000d788 in readline_common (vtbl=vtbl@entry=0x2000672c, buf=buf@entry=0x20008498 "\n", buflen=buflen@entry=1000) at readline_common.c:513 #7 0x0000b08e in readline_fd (buf=buf@entry=0x20008498 "\n", buflen=buflen@entry=1000, infd=infd@entry=0, outfd=<optimized out>) at readline_fd.c:222 #8 0x0000ad9c in nsh_session (pstate=pstate@entry=0x20008210, login=login@entry=1, argc=argc@entry=1, argv=argv@entry=0x20005fc0) at nsh_session.c:228 #9 0x0000acae in nsh_consolemain (argc=argc@entry=1, argv=argv@entry=0x20005fc0) at nsh_consolemain.c:75 #10 0x0000ac6c in nsh_main (argc=1, argv=0x20005fc0) at nsh_main.c:74 #11 0x00008d60 in nxtask_startup (entrypt=0xac41 <nsh_main>, argc=1, argv=0x20005fc0) at sched/task_startup.c:70 #12 0x0000612a in nxtask_start () at task/task_start.c:114 #13 0x00000000 in ?? () (gdb) ``` Regards, Neo Xu Neo <neoxu1...@gmail.com> 于2025年1月25日周六 01:33写道: > It turns out the issue comes from the wrong SP register value getting > restored by python script. > > TLDR, If you happen to met that GDB cannot unwind correctly, try set > $sp=$sp+4 > > > The issue is that when an exception happened, armv7-m could push 4 bytes > to stack, to make sure SP is 8bytes aligned. > See > https://developer.arm.com/documentation/ddi0403/d/System-Level-Architecture/System-Level-Programmers--Model/ARMv7-M-exception-model/Stack-alignment-on-exception-entry > > It happens that NuttX release 12.6.0 generates code that has SP not > aligned to 4 bytes as shown below, right before triggering SVC. > [image: img_v3_02is_bcd2a515-ec2b-4432-a86a-cbd232cb736l.jpeg] > > According to the documentation, we can distinguish this situation from > xPSR[9] bit. xPSR is pushed to stack automatically. > [image: img_v3_02is_e29e799d-75c4-4520-b145-a2369b4b5ael.jpeg] > > In this case, the real SP after restore should be `SP + 4`. After > adjusting it manually, now GDB can unwind correctly. > [image: a8GxTXm0aT.jpeg] > > NuttX release 12.8.0 changes the sys_call to macro, which saves 4 bytes on > stack, avoiding this issue (coincidently?). The latest master branch does > not have this issue too, and I’m not sure if it’s guaranteed or not. > > Regards, > Neo >