包装open()进行单元测试会使gcov无法打开gcda文件

时间:2017-11-09 12:02:24

标签: c unit-testing gcc gcov

我正在实施一些C程序的测试。为此,我使用GCC的-Wl,--wrap=open来模拟stdlib的open()函数,并检查是否已使用正确的选项调用它。

当这样做时,gcov在编写.gcda文件时遇到了一些问题。我想我定义的模拟不仅用于我的测试,还用于gcov。以下是如何重现这一点的一个小例子:

#include <stdio.h>

int __wrap_open(const char *path, int flags, int mode)
{
    printf("hello from __wrap_open\n");
    return -1;
}


int main(void)
{
    return 0;
}

并使用gcc main.c -Wl,--wrap=open -fprofile-arcs -ftest-coverage -lgcov进行编译。为了保持示例简单,我使用CMocka删除了单元测试部分,以显示我遇到的错误。

运行可执行文件a.out时,我使用GCC和gcov 6.3.0获得以下输出:

$ ./a.out
hello from __wrap_open
hello from __wrap_open
profiling:/home/romain/wrap-bug/main.gcda:Cannot open

为了生成代码覆盖率数据,有没有办法模拟open()函数以便我的单元测试能够使用gcov?也许有办法告诉gcov使用__real_open()

1 个答案:

答案 0 :(得分:3)

实现这一目标的简单方法是:

  • 检查传递给open()的文件的路径是否是您的分析文件
  • 如果是,请将通话传递给__real_open()

int __real_open(const char *path, int flags, int mode);

int __wrap_open(const char *path, int flags, int mode)
{
    if (strlen(path) > 5 && !strcmp(path + strlen(path) - 5, ".gcda"))
        return __real_open(path, flags, mode);
    printf("hello from __wrap_open\n");
    return -1;
}

使用这种方式,您当然可以轻松添加更多不应被篡改的文件。