On Fri, Mar 13, 2026 at 2:03 PM Peter Barada <[email protected]> wrote:
> I've run across a crash on a few different STM32 Nucleo boards (h743zi2,
> f767zi, and f446re) caused by the Idlestack not being8-byte aligned due
> to syslog messages at startup (with timestamps enabled) that passes a
> uintmax_t parameter to vsprinf_internal().
>
> I originally found this on nucleo-h743zi2:jumbo while trying to fix the
> "Missing logic" warning in stm32_irq.c:152 I've been able to apply my
> same changes to nucleo-f446re and nucleo-f767zi and exhibit the issue.
> Even w/o my changes, forcing the .bss section to not be 8-byte aligned
> in size causes the same issue.
>
> The underlying issue occurs due to calling stm32_dumpnvic from the
> idletask with SYSLOG_TIMESTAMP enabled, but only when the Idlestak is
> not aligned to an 8-byte bvoundary. The issue is due to invoking "x =
> va_arg(ap, unsigned long long);" in vsprintf_internal
> (lib_libvsprintf.c:1061) which aligns ap before accessing the long long:
>
> Breakpoint 5, vsprintf_internal (stream=stream@entry=0x20005390,
> arglist=0x0,
> numargs=0, fmt=0x8018bf2 ".%06ld] [%6s] %s: ",
> fmt@entry=0x8005817 <lib_sprintf_internal+22> "...",
> ap=..., ap@entry=..., numargs=0, arglist=0x0)
> at stream/lib_libvsprintf.c:1061
> 1061 x = va_arg(ap, unsigned long long);
> p ap
> $18 = {__ap =*0x2000536c*}
> (gdb) x/5i $pc
> => 0x800563a <vsprintf_internal+782>: add.w r9, r9, #7
> 0x800563e <vsprintf_internal+786>:*bic.w r9, r9, #7 # align ap*
> 0x8005642 <vsprintf_internal+790>: mov r7, r9
> 0x8005644 <vsprintf_internal+792>: ldr.w r1, [r9, #4]
> 0x8005648 <vsprintf_internal+796>: ldr.w r0, [r7], #8
> (gdb) p/x $r9
> $19 = 0x2000536c
> (gdb) s
> 1108 flags &= ~(FL_PLUS | FL_SPACE);
> (gdb) p ap
> $20 = {__ap =*0x20005378*}
> (gdb) p/x $r7
> $21 = 0x20005378
> (gdb)
>
> This works fine if the stack is aligned on an 8-byte boundary (which all
> other task/user stacks currently are due to MM_DEFAULT_ALIGNMENT being
> 8). But if the idletask stack is not aligned, ap ends up incremented by
> 12 causing access to any following vararg in vsprintf_internal to be
> offset by 4 bytes resulting in potential exceptions.
>
> A fix is to increase the alignment in the .bss section to 8 in the
> linker description file (since the idlestack immediately follows .bss
> starting at _ebss). I've tested this fix on nucleo-743zi2 (based on
> stm32h7), nucleo-h767zi (based on stm32f7), and nucleo-f446re (based on
> stm32), all with success.
>
> I can provide a PR, but my question is whether this alignment should be
> applied to all ARM?
>
> --
> Peter Barada
> [email protected]
>
Hi Peter,
Good catch!!
A PR would be very much appreciated.
As for whether the alignment fix should be applied to all ARM, I don't know
the answer off the top of my head, but I think it would be safe to do so.
NuttX supports multiple ARM platforms, including:
armv6-m
armv7-a
armv7-m
armv7-r
armv8-m
armv8-r
arm64
The STM32H7 and STM32F7 both have a armv7-m core; without checking, I don't
know which cores the other STM32 parts have.
Since you caught this issue on armc7-m, I think it's safe to assume
that armv7-a
through arm64 probably require the stack aligned to 8 bytes.
I don't know about armv6-m but I think it can be updated to 8-byte
alignment as well, for consistency across the ARM platforms.
In other words, Someone (tm) could go ahead and do the research to
determine what the alignment requirements are for each of the cores listed
above, or the alignment could just be updated to 8-byte whether it's needed
or not.
Thoughts?
Nathan