gpt4 book ai didi

c - 为什么 gcov 生成 gcda 文件时只设置了可执行位?

转载 作者:太空宇宙 更新时间:2023-11-04 03:33:05 25 4
gpt4 key购买 nike

我手头有一个带有 cmocka 测试的 C 项目,它是使用 CMake 构建的。现在我尝试使用 gcov 来确定测试覆盖率并使用此 CMake 模块:https://github.com/bilke/cmake-modules/blob/master/CodeCoverage.cmake该模块提供了一个 make 目标,该目标运行测试目标可执行文件(即运行 gcov),然后运行 ​​lcov 和 genhtml 以生成报告。

现在,问题是,当执行测试目标时,它创建的 .gcda 文件只设置了所有者的可执行位,即。 e.读取位丢失。随后,lcov 无法读取这些文件并生成覆盖率为 0% 的报告。当我之后手动 chmod u+r gcda 文件并手动运行测试后 lcov 命令时,报告已成功生成(显示实际上已覆盖的内容)。因此 gcda 文件已创建且有效,但它们设置了不合适的权限。

问题似乎源于包装(使用 ld --wrap)用于捕获测试用例中返回的文件描述符的 open 函数。这是一个最小的编译示例:

/* wrapped_open.c */

int main(void)
{
return 0;
}

int __wrap_open(const char *filename, int flags)
{
return __real_open(filename, flags);
}


# CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(gcov-mvce C)

add_executable(wrapped_open wrapped_open.c)
target_link_libraries(wrapped_open
-Wl,--wrap=open
)

set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake")
include(CodeCoverage)

set_target_properties(wrapped_open PROPERTIES
COMPILE_FLAGS "-g -O0 --coverage -fprofile-arcs -ftest-coverage"
LINK_FLAGS "-lgcov --coverage")

setup_target_for_coverage(wrapped_open_coverage wrapped_open "coverage")


# build like this:

cmake . -DCMAKE_BUILD_TYPE=Debug # in-source build
make
# receive coverage report like this
make wrapped_open_coverage

# simple gcc command line for compiling (no cmake required)
gcc -g -O0 --coverage -fprofile-arcs -ftest-coverage -lgcov -Wl,--wrap=open -o wrapped_open wrapped_open.c

当 open 的包装和包装函数定义分别从链接器标志和代码中删除时,它就可以工作。但是对于上面的文件,文件 wrapped_open.c.gcda 是使用访问掩码 0100 创建的,lcov 报告了以下内容:

(bulid-directory)/CMakeFiles/wrapped_open.dir/wrapped_open.c.gcda:cannot open data file, assuming not executed

...导致覆盖 0/4 行和 0/2 函数。

为什么打开函数像上面那样包装时访问位是错误的,即使每个路径仍然使用未修改的参数调用原始函数(至少这是它打算做的)?一个明显的解决方法是修改 cmake 模块来为我执行 chmod,但我更想了解包装 open 时出了什么问题。

请在评论中告诉我是否需要以及需要​​哪些额外信息来回答这个问题。

最佳答案

正如评论中所指出的,open() 是一个具有可变参数的函数。如果创建了文件,则第三个参数是文件的模式。在我的 __wrap_open 实现中,我省略了第三个参数,因为我没有想到除了被测代码之外的其他代码也会调用 open()。当然,gcov 最终会创建它的 gcda 文件,并且由于我没有指定 __real_open 的第三个参数,因此该模式中有一些未定义的内容。

因此,解决方案是始终在包装函数中包含所有可能的参数。

关于c - 为什么 gcov 生成 gcda 文件时只设置了可执行位?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34622179/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com