You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用cmocka框架Mock/Wrap被测非静态函数调用的静态函数遇运行问题

我之前也碰到过一模一样的问题!别着急,咱们一步步排查,大概率是这几个环节出了问题:

问题根源与解决办法

1. 静态函数的文件内作用域限制

静态函数默认是文件级私有的,如果被测函数和静态函数在同一个.c文件里,编译器很可能会直接将静态函数内联到被测函数中,或者直接做内部调用优化,完全跳过链接器的符号解析环节——这时候--wrap标志根本没机会生效。

解决办法:

  • 如果代码架构允许,把静态函数拆分到单独的.c文件中,让链接器能处理它的符号。
  • 给被测文件的编译添加-fno-inline和-fno-builtin选项,强制编译器禁止内联和内置优化,保留静态函数的外部符号入口。

2. Wrap函数的定义必须严格符合要求

Wrap函数的签名和命名规则不能出错:

  • 函数名必须是__wrap_原静态函数名,比如原函数是static void hw_write(int val),Wrap函数就得是void __wrap_hw_write(int val)。
  • Wrap函数不能是静态的,必须是全局可见的,否则链接器找不到它。
  • 参数类型、返回值必须和原函数完全一致,哪怕是const修饰符都不能少。

3. 链接器标志的位置要正确

很多人会把--wrap=xxx加到编译选项里,但这是链接器专属选项,必须确保它被传给链接器:

  • 用GCC编译时,要写成-Wl,--wrap=xxx(-Wl,是把后续参数传递给链接器的标志)。
  • 如果用CMake构建,要把选项加到target_link_options或LINK_FLAGS里,不能放在compile_options中。

4. 编译优化等级过高导致内联

如果测试代码开启了-O2及以上的优化,编译器会自动内联静态函数,让Wrap失效。解决办法:

  • 测试代码的编译优化等级设为-O0。
  • 针对被测文件单独添加-fno-inline选项,强制保留静态函数的独立调用入口。

5. 验证符号是否被正确替换

可以用nm命令检查测试可执行文件的符号表,确认原静态函数是否被Wrap函数替换:

nm test_executable | grep 原静态函数名

如果看到原函数的符号是小写t(本地符号),说明链接器没替换成功;如果出现__wrap_xxx的大写T(全局符号),才说明替换生效了。

示例代码与编译命令

举个完整的例子,帮你快速验证:

被测文件hw.c

// 静态硬件交互函数
static void hw_send(int data) {
    // 真实硬件操作
}

// 被测非静态函数
void process_input(int input) {
    hw_send(input * 2);
}

测试文件test_hw.c

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>

// Wrap函数,全局可见
void __wrap_hw_send(int data) {
    check_expected(data); // 验证传入参数是否符合预期
}

static void test_process_input(void **state) {
    expect_value(__wrap_hw_send, data, 4); // 预期传入4
    process_input(2);
}

int main(void) {
    const struct CMUnitTest tests[] = {
        cmocka_unit_test(test_process_input),
    };
    return cmocka_run_group_tests(tests, NULL, NULL);
}

编译命令

# 编译被测文件,禁用内联和优化
gcc -c hw.c -o hw.o -O0 -fno-inline
# 编译测试文件
gcc -c test_hw.c -o test_hw.o -O0 -I/path/to/cmocka/include
# 链接时添加Wrap标志和cmocka库
gcc -o test_hw test_hw.o hw.o -L/path/to/cmocka/lib -lcmocka -Wl,--wrap=hw_send

如果还是不行,可以试试在被测文件中给静态函数添加__attribute__((noinline))属性,强制编译器不内联它。

内容的提问来源于stack exchange,提问作者Iniesta8

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:39:59