代码之家  ›  专栏  ›  技术社区  ›  jchl

如何告诉GCOV忽略C++代码的未命中行?

  •  41
  • jchl  · 技术社区  · 14 年前

    我使用GCOV来测量我的C++代码中的覆盖率。我希望得到100%的覆盖率,但由于有些代码行理论上是不可攻击的(需要实现但从未调用的方法,默认分支 switch 陈述等)。每个分支都包含一个 assert( false ); 声明,但GCOV仍将其标记为未命中。

    我想告诉GCOV忽略这些分支。有没有办法给gcov这些信息——通过注释源代码,或者通过任何其他机制?

    4 回复  |  直到 7 年前
        1
  •  33
  •   Torsten Scheck    14 年前

    请使用LCOV。它隐藏了gcov的复杂性,产生了很好的输出,允许每个测试的详细输出,具有简单的文件过滤和已审查行的-ta taa-行标记:

    来自geninfo(1):

    geninfo识别以下标记:

    • 大鳞线
      • 包含此标记的行将被排除。
    • 拉科夫斯克劳斯启动
      • 标记排除的节的开头。当前行是此节的一部分。
    • 拉科夫停止
      • 标记排除的节的结尾。当前行不属于此节。
        2
  •  2
  •   Simon Pickup    7 年前

    被称为工具 gcovr 可用于总结GCOV的输出,以及( from at least version 3.4 )它支持与LCOV相同的排除标记。

    this answer :

    geninfo识别以下标记:

    • 大鳞线
      • 包含此标记的行将被排除。
    • 拉科夫斯克劳斯启动
      • 标记排除的节的开头。当前行是此节的一部分。
    • 拉科夫停止
      • 标记排除的节的结尾。当前行不属于此节。

    您也可以替换 'LCOV' 以上 'GCOV' 'GCOVR' . 他们都工作。

        3
  •  1
  •   Steve Jessop    14 年前

    你能介绍相关函数的单元测试吗?这些测试仅仅是为了通过直接攻击理论上不可匹配的代码路径来关闭gcov?因为它们是单元测试,所以它们可能会忽略情况的“不可能”。它们可以调用从未调用的函数,传递无效的枚举值以捕获默认分支等。

    然后,要么只在用ndebug编译的代码版本上运行这些测试,要么在触发断言的测试工具中运行它们——无论测试框架支持什么。

    不过,我觉得规范说代码必须存在有点奇怪,而不是包含代码功能需求的规范。特别是,它意味着您的测试并没有测试那些需求,这是保持需求正常运行的一个很好的理由。就我个人而言,我想修改规范说,“如果用无效的枚举值调用,函数将失败 assert . 在释放模式下,调用方不能调用枚举值无效的函数”。或者一些这样的。

    大概它目前所说的是“所有switch语句都必须有一个默认情况”。但这意味着编码标准通过引入死代码来干扰可观测行为(至少在GCOV下是可观测的)。编码标准不应该这样做,所以如果可能的话,功能规范应该考虑编码标准。

    如果失败,您可能会将不可编辑的代码包装在 #if !GCOV_BUILD 并为GCOV的利益进行单独的构建。这个构建将失败一些需求,但前提是您对代码的分析是正确的,它让您确信您希望测试套件测试其他所有东西。

    编辑:你说你在使用一个不可靠的代码生成器,但你也在通过注释源代码来寻求解决方案。如果您要更改源代码,在许多情况下,您可以删除死代码吗?不是说改变生成的源是理想的,而是需要…

        4
  •  0
  •   doron    14 年前

    我不相信这是可能的。gcov依赖gcc生成额外的代码来生成覆盖率输出。gcov本身只是解析数据。这意味着gcov无法比gcc更好地分析代码(我假设您使用了-wall并删除了报告为不可访问的代码)。

    记住,可重定位函数可以从任何地方调用,甚至可能是外部DLL或可执行文件,因此编译器无法知道哪些可重定位函数不会被调用,或者这些函数可能有哪些输入。

    您可能需要使用一些facy静态分析工具来获取所需的信息。

    推荐文章