Repository navigation
Conversation
rt_vsprintf() passed (size_t)-1 as the buffer size to rt_vsnprintf(). That is
harmless for the built-in implementation, which only uses the size to stop
writing, but with RT_KLIBC_USING_LIBC_VSNPRINTF the call is forwarded to libc:
rt_sprintf() -> rt_vsprintf() -> rt_vsnprintf(buf, SIZE_MAX, ...) -> vsnprintf()
libc derives the end of the buffer from buf + size, and 0xFFFFFFFFFFFFFFFF
overflows on 64-bit targets, so the call fails without writing a single byte:
rt_snprintf(buf, 100, "%d", 42) -> ret=2 buf="42"
rt_sprintf(buf, "%d", 42) -> ret=-1 buf=0xCC (untouched)
This is what makes core.klibc.rt_sprintf fail on qemu-virt64-aarch64 when
RT_KLIBC_USING_LIBC_VSNPRINTF is enabled: every SPRINTF_CHECK() compares the
0xCC filled buffer against the expected string.
Delegate to libc's vsprintf() instead, which takes no size argument and is the
exact counterpart of what rt_vsprintf() has to do.
Verified on bsp/qemu-virt64-aarch64 with RT_UTEST_TC_USING_KLIBC + CI_ACTION:
RT_KLIBC_USING_LIBC_VSNPRINTF=y
before: core.klibc.rt_sprintf FAILED, 5 other klibc cases passed
after : all 6 klibc cases PASSED
RT_KLIBC_USING_LIBC_VSNPRINTF not set (built-in rt_vsnprintf path)
after : all 6 klibc cases PASSED
Refs RT-Thread#10027
|
👋 感谢您对 RT-Thread 的贡献!Thank you for your contribution to RT-Thread! 为确保代码符合 RT-Thread 的编码规范,请在你的仓库中执行以下步骤运行代码格式化工作流(如果格式化CI运行失败)。 🛠 操作步骤 | Steps
完成后,提交将自动更新至 如有问题欢迎联系我们,再次感谢您的贡献!💐 |
📌 Code Review Assignment🏷️ Tag: kernelReviewers: @GorrayLi @ReviewSun @hamburger-os @lianux-mm @wdfk-prog @xu18838022837 Changed Files (Click to expand)
📊 Current Review Status (Last Updated: 2026-10-30 11:57 CST)
📝 Review Instructions
|
|
拉取/合并请求描述:(PR description)
[
为什么提交这份PR (why to submit this PR)
修复 #10027:
qemu-virt64-aarch64上开RT_USING_CI_ACTION后klibc.rt_sprintf失败。根因
rt_sprintf()的调用链把无穷大的 size 交给了 libc:这在内置实现下无害——它只用 size 决定何时停止写。但启用
RT_KLIBC_USING_LIBC_VSNPRINTF后,rt_vsnprintf()直接转发给 libc:libc 用
buf + size计算缓冲区末尾,64 位下直接溢出,于是调用失败且一个字节都没写。实测(
bsp/qemu-virt64-aarch64,RT_KLIBC_USING_LIBC_VSNPRINTF=y):0xCC正是测试宏SPRINTF_CHECK里rt_memset(buffer, 0xCC, ...)的填充值,所以 utest 报出来的str-b是一串����:你的解决方案是什么 (what is your solution)
启用 libc 委托时改用 libc 的
vsprintf()——它本来就不需要 size 参数,正是rt_vsprintf()该对应的接口:内置路径完全不动。
请提供验证的bsp和config (provide the config and bsp)
bsp/qemu-virt64-aarch64RT_USING_CI_ACTION=y(选中RT_UTEST_USING_AUTO_RUN)、RT_UTEST_TC_USING_KLIBC=y,其余为 BSP 默认1c801efa三组结果:
RT_KLIBC_USING_LIBC_VSNPRINTF=ycore.klibc.rt_sprintfFAILED,其余 5 个 PASSEDLIBC_VSNPRINTF未开(内置 vsnprintf)LIBC_VSNPRINTF未开 +VSNPRINTF_STANDARD/LONGLONG全开第三组是排查时顺带跑的:
RT_KLIBC_USING_VSNPRINTF_STANDARD的默认值是default y if ARCH_CPU_64BIT,而这块 BSP 保存的.config把它显式关掉了,所以默认配置下并不会看到这个失败——必须显式打开RT_KLIBC_USING_LIBC_VSNPRINTF才复现。一点说明
issue 里没有给出当时的完整
.config,我只能从"64 位 + CI"这两个条件反推。如果原作者当时的配置里RT_KLIBC_USING_LIBC_VSNPRINTF是关的,那这里修的可能不是他遇到的那一次,需要他确认。不过无论原场景如何,上面这条路径的缺陷本身是确定的,且可以用一行改动修掉。]
当前拉取/合并请求的状态 Intent for your PR
必须选择一项 Choose one (Mandatory):
代码质量 Code Quality:
我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:
#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up