Skip to content

system/uorb: bump listener stack when float print extension is on - #3763

Open
FelipeMdeO wants to merge 1 commit into
apache:masterfrom
FelipeMdeO:fix/uorb-listener-stack-overflow
Open

system/uorb: bump listener stack when float print extension is on#3763
FelipeMdeO wants to merge 1 commit into
apache:masterfrom
FelipeMdeO:fix/uorb-listener-stack-overflow

Conversation

@FelipeMdeO

@FelipeMdeO FelipeMdeO commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Summary

uorb_listener's %pB debug printing (orb_info() -> lib_bsprintf()) performs real floating-point-to-string conversion synchronously, inside the listener's own task -- it is not a lightweight pointer dump. With CONFIG_LIBC_PRINT_EXTENSION off, %pB just prints a raw pointer and the default CONFIG_UORB_STACKSIZE (DEFAULT_TASK_STACKSIZE, 2048 on most configs) is plenty. With it on, decoding a topic's float fields through this path silently overflows a 2048-byte stack.

Confirmed on real hardware (ESP32-S3, two subscribed float topics pushing every ~10-20ms): uorb_listener hangs completely after printing only a partial topic name -- no panic, no stack dump, nothing -- because CONFIG_SCHED_STACKGUARD/CONFIG_STACK_COLORATION aren't on by default either, so there's no guard to catch the overflow before it corrupts adjacent memory.

Raising the default only when CONFIG_LIBC_PRINT_EXTENSION is set (not unconditionally, and not keyed off CONFIG_DEBUG_UORB specifically, since anything else that selects the same libc extension hits the same path) keeps the common case -- raw pointer output, small stack -- exactly as before, and only pays for the extra stack when the feature that needs it is actually enabled.

Impact

CONFIG_UORB_STACKSIZE default changes from DEFAULT_TASK_STACKSIZE to 4096 only for configs with CONFIG_LIBC_PRINT_EXTENSION=y. No change for any other config. Users who already have an explicit CONFIG_UORB_STACKSIZE recorded in their .config are unaffected by this default either way (see note below).

Testing

Host: Ubuntu 24.04.4 LTS. xtensa-esp-elf-gcc (crosstool-NG esp-14.2.0_20241119) 14.2.0. checkpatch.sh (style + -m commit message) clean.

On hardware -- Seeed XIAO ESP32-S3, CONFIG_LIBC_PRINT_EXTENSION=y, uorb_listener subscribed to two float-based topics streaming continuously:

  • CONFIG_UORB_STACKSIZE=2048 (the old default): reproduces the hang every time, output cuts off mid topic-name print, console never responds again.

  • CONFIG_UORB_STACKSIZE=4096 (this PR's new default): runs cleanly, verified repeatedly across multiple fresh boots for 10+ seconds continuous, fully decoded output, e.g.:

    sensor_gyro(now:20410000):timestamp:20410000,x:0.008399,y:-0.041386,z:0.017409,temperature:31.000000
    sensor_accel(now:20390000):timestamp:20390000,x:-6.385280,y:0.358925,z:-7.318485,temperature:31.000000
    
  • End-to-end with the actual Kconfig default mechanism (not a manual override): starting from a .config where CONFIG_UORB_STACKSIZE was never set, enabling CONFIG_LIBC_PRINT_EXTENSION and running make olddefconfig resolves CONFIG_UORB_STACKSIZE to 4096 automatically; the resulting build was flashed and validated live on the bench with the same clean, continuous decoded output as above.

uorb_listener's %pB debug printing (orb_info() -> lib_bsprintf()) does
real floating-point-to-string conversion synchronously, in the
listener's own task -- not a lightweight pointer dump. With
CONFIG_LIBC_PRINT_EXTENSION off, %pB just prints a raw pointer and the
default CONFIG_UORB_STACKSIZE (DEFAULT_TASK_STACKSIZE, 2048 on most
configs) is plenty. With it on, decoding a topic's float fields through
this path silently overflows a 2048-byte stack -- confirmed on real
hardware (ESP32-S3, one push every ~10-20ms from two subscribed
topics): uorb_listener hangs completely after printing only a partial
topic name, no panic, no stack dump, nothing -- because
CONFIG_SCHED_STACKGUARD/CONFIG_STACK_COLORATION aren't on by default
either, so there's no guard to catch the overflow before it corrupts
adjacent memory.

Raising the default only when CONFIG_LIBC_PRINT_EXTENSION is set (not
unconditionally, and not keyed off CONFIG_DEBUG_UORB specifically,
since anything else that selects the same libc extension hits the same
path) keeps the common case -- raw pointer output, small stack --
exactly as before, and only pays for the extra stack when the feature
that needs it is actually enabled.

4096 was verified sufficient (tested against 2048, which reproduces
the hang, and 8192, which also works but wastes RAM); reproduced
cleanly across multiple fresh boots.

Note: this default only applies when CONFIG_UORB_STACKSIZE has never
been explicitly recorded in .config. Like any Kconfig int default,
flipping CONFIG_LIBC_PRINT_EXTENSION on in an existing .config that
already has an explicit CONFIG_UORB_STACKSIZE value won't retroactively
raise it; the value has to be re-picked (e.g. via a fresh olddefconfig
after removing the stale line, or manually).

Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants