Skip to content

[Bug] qemu-virt64-aarch64运行utest项提示 klibc.rt_sprintf 运行失败 #10027

Open

Description

@kurisaW

RT-Thread Version

master

Hardware Type/Architectures

qemu-virt64-aarch64

Develop Toolchain

GCC

Describe the bug

使能 RT_USING_CI_ACTION 宏定义后,在qemu平台上运行测试用例:klibc.rt_sprintf 失败:

详见下图:

Image

相关ci链接:

Other additional context

No response

Activity

  1. self-assigned this
    on Feb 24, 2025
  2. kurisaW commented on Feb 24, 2025

    @kurisaW
    MemberAuthor

    @mysterywolf 满老师有空能否也看下这个issue

  3. removed their assignment
    on Feb 24, 2025
  4. changed the title [-][Bug] AARCH64下运行utest项提示 klibc.rt_sprintf 运行失败[/-] [+][Bug] qemu-virt64-aarch64运行utest项提示 klibc.rt_sprintf 运行失败[/+] on Feb 24, 2025
  5. Yunlk commented on Oct 30, 2026

    @Yunlk
    Contributor

    /claim

  6. Yunlk commented on Oct 30, 2026

    @Yunlk
    Contributor

    复现到了,根因也定位了,已提 PR #11953。

    复现条件

    bsp/qemu-virt64-aarch64,RT_USING_CI_ACTION=y + RT_UTEST_TC_USING_KLIBC=y,关键是要开 RT_KLIBC_USING_LIBC_VSNPRINTF=y。

    补充一点排查信息:RT_KLIBC_USING_VSNPRINTF_STANDARD 的默认值是 default y if ARCH_CPU_64BIT,但这块 BSP 保存的 .config 把它显式关成了 is not set。所以用默认配置复现不出来——我先后试了"全关""STANDARD+LONGLONG 全开"两种,6 个 klibc 用例都是 PASSED,直到打开 RT_KLIBC_USING_LIBC_VSNPRINTF 才稳定失败。

    根因

    rt_sprintf() 把一个无穷大的 size 传给 libc:

    rt_sprintf() → rt_vsprintf() → rt_vsnprintf(buf, (size_t)-1, ...)

    内置实现只用 size 决定何时停写,无害;但开了 LIBC_VSNPRINTF 后直接转发:

    int rt_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
    {
        return vsnprintf(buf, size, fmt, args);   /* size = 0xFFFFFFFFFFFFFFFF */
    }

    libc 用 buf + size 算缓冲区末尾,64 位下溢出,调用失败且一个字节都没写。

    实测对照:

    [K27] rt_snprintf size=100    ret= 2  buf="42"        ← 正常
    [K27] rt_sprintf SIZE_MAX     ret=-1  buf=0xCC ...    ← 未写入
    [K27] sizeof(size_t)=8, (size_t)-1 = 0xffffffffffffffff
    

    0xCC 是 utest 宏 SPRINTF_CHECK 里 rt_memset(buffer, 0xCC, ...) 的填充值,所以报错里的 str-b 是一串 ����:

    [E/utest] at (TC_rt_sprintf.c); func: (TC_space_flag:76); msg: (string not equal)
    [E/utest] str-a: ( 42); str-b: (����...)
    

    修复与验证

    开 LIBC_VSNPRINTF 时改用 libc 的 vsprintf()(本就无 size 参数),内置路径不动。三组结果:

    配置 改前 改后
    LIBC_VSNPRINTF=y rt_sprintf FAILED,其余 5 个 PASSED 6 个全 PASSED
    LIBC_VSNPRINTF 未开 6 个 PASSED 6 个 PASSED(回归)
    LIBC_VSNPRINTF 未开 + STANDARD/LONGLONG 全开 6 个 PASSED —

    想请你确认

    issue 里没有当时的完整 .config。如果那时 RT_KLIBC_USING_LIBC_VSNPRINTF 是关着的,那我修的就不是你碰到的那一次,需要你补一下配置(或直接贴 CI 的 .config)。

    不过从"64 位 + 你这单报的就是 rt_sprintf"来看,这条路径是比较可能的解释——因为它是 64 位下唯一会让 rt_sprintf 完全不写(而不是写错)的路径。0xCC 未写入的现象也和截图里那种整片乱码对得上。

    如果你能确认当时的配置,我可以再按那个配置交叉验证一次。

  7. github-actions commented on Oct 30, 2026

    @github-actions

    @Yunlk has claimed this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions