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
>

Reply via email to