覆盖率数据中出现意外的分支计数
Unexpected branch count in coverage data
我生成覆盖率数据,并使用在线服务进行可视化和CI。然而,我有奇怪的"部分"(如果分支没有完全覆盖)。从gcov数据来看,似乎检测到了过多的分支。
一个例子:
function _ZNK5World8AdjustBQE5PointItEh15BuildingQuality called 415 returned 100% blocks executed 76%
415: 377:BuildingQuality World::AdjustBQ(const MapPoint pt, unsigned char player, BuildingQuality nodeBQ) const
-: 378:{
415: 379: if(nodeBQ == BQ_NOTHING || GetNode(pt).owner != player + 1 || !IsPlayerTerritory(pt))
branch 0 taken 95% (fallthrough)
branch 1 taken 5%
call 2 returned 100%
call 3 returned 100%
branch 4 taken 100% (fallthrough)
branch 5 taken 0% (throw)
branch 6 taken 85% (fallthrough)
branch 7 taken 15%
call 8 returned 100%
call 9 returned 100%
branch 10 taken 100% (fallthrough)
branch 11 taken 0% (throw)
branch 12 taken 17% (fallthrough)
branch 13 taken 83%
branch 14 taken 80% (fallthrough)
branch 15 taken 20%
branch 16 taken 95% (fallthrough)
branch 17 taken 5%
branch 18 taken 33% (fallthrough)
branch 19 taken 67%
branch 20 never executed
branch 21 never executed
branch 22 never executed
branch 23 never executed
call 24 never executed
尽管我已经在使用-g -O0 --coverage -fno-default-inline -fno-inline
进行编译,但函数似乎仍然被内联和计数。我该怎么办,这样我只得到"有意义的全部"数据,并且内联函数在其定义中被正确地归因?
我使用g++-4.8和gcov-4.8
编辑:如果我把If分成它的调用,我会得到这个:
415: 379: unsigned char owner = GetNode(pt).owner;
call 0 returned 100%
call 1 returned 100%
branch 2 taken 100% (fallthrough)
branch 3 taken 0% (throw)
call 4 never executed
415: 380: bool isPlayerTer = IsPlayerTerritory(pt);
call 0 returned 100%
call 1 returned 100%
branch 2 taken 100% (fallthrough)
branch 3 taken 0% (throw)
call 4 never executed
415: 381: if(nodeBQ == BQ_NOTHING || owner != player + 1 || !isPlayerTer)
branch 0 taken 95% (fallthrough)
branch 1 taken 5%
branch 2 taken 85% (fallthrough)
branch 3 taken 15%
branch 4 taken 17% (fallthrough)
branch 5 taken 83%
所以问题实际上在于电话。我该怎么做才能使这些呼叫(及其分支(???))不添加到覆盖范围数据中?
刚刚在asm代码中发现了一个人工分支,它只检查一个寄存器并执行nop(除了gcov计数器增量)WTF?
0x0000000000d967de <World::AdjustBQ(Point<unsigned short>, unsigned char, BuildingQuality) const+340>: test %bl,%bl
0x0000000000d967e0 <World::AdjustBQ(Point<unsigned short>, unsigned char, BuildingQuality) const+342>: je 0xd967f5 <World::AdjustBQ(Point<unsigned short>, unsigned char, BuildingQuality) const+363>
0x0000000000d967e2 <World::AdjustBQ(Point<unsigned short>, unsigned char, BuildingQuality) const+344>: nop
0x0000000000d967e3 <World::AdjustBQ(Point<unsigned short>, unsigned char, BuildingQuality) const+345>: mov 0x1206c9e(%rip),%rax # 0x1f9d488 <__gcov0._ZNK5World8AdjustBQE5PointItEh15BuildingQuality+72>
0x0000000000d967ea <World::AdjustBQ(Point<unsigned short>, unsigned char, BuildingQuality) const+352>: add $0x1,%rax
0x0000000000d967ee <World::AdjustBQ(Point<unsigned short>, unsigned char, BuildingQuality) const+356>: mov %rax,0x1206c93(%rip) # 0x1f9d488 <__gcov0._ZNK5World8AdjustBQE5PointItEh15BuildingQuality+72>
0x0000000000d967f5 <World::AdjustBQ(Point<unsigned short>, unsigned char, BuildingQuality) const+363>: test %dl,%dl
我切换到clang++和llvm-cov gcov
,并得到了正确的结果(只有6个分支)。然而,我在其他地方也得到了一些假阳性。其中最令人不安的一个似乎是在一行的函数中间的"函数__cxx_global_array_tor调用",而类似的行(仅更改整数参数)没有这个调用。因此,我目前的解决方案是在没有分支数据的情况下使用gcov-4.8,因为它完全不可靠。
可能在可能发生异常的点上有额外的分支,例如在函数调用点。
例如,我们在我们的(而不是noexcept)空虚拟析构函数中观察到一个带有gcov的分支,我们的测试无法覆盖它。
相关文章:
- IPC使用多个管道和分支进程来运行Python程序
- 在C++中对T*类型执行std::move的意外行为
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 如何删除peer if else分支中的冗长句子
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 处理除以零会导致<csignal>意外行为
- vscode下的Arduino代码出现意外编译错误
- 使用++运算符会导致意外的结果
- 套接字读取后,我在缓冲区中看到意外输入
- 更改.cpp程序的输入文件中数据的位置会意外更改输出
- 如何正确地将分支添加到已存在的树中
- 使用vscode调试时,GDB意外退出
- 如何将分支添加到已存在的TTree:ROOT
- 此测试()中发生了什么意外过程?为什么总是覆盖 ch[0 1 2..]?
- 尝试将字符串/字符转换为整数会产生意外结果
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- C++标头错误 C2238 意外标记";"
- C++中意外的多头值
- std::shared_ptr vs std::make_shared:意外的缓存未命中和分支预测
- 覆盖率数据中出现意外的分支计数