gcov不会生成头文件的覆盖率信息

我第一次使用gcov,并且遇到类似于此线程中报告的问题。 但是,在该主题中的评论之后,我无法解决我的问题。

我正在测试KMyMoney-4.6.4中具体测试用例的覆盖率,即测试文件“mymoneyaccounttest.cpp”中的“testConstructor”。 该测试用例使用以下方法,该方法位于头文件“mymoneyaccount.h”中,并具有可执行代码:

 const QString& institutionId(void) const {
    return m_institution;
  }

因此,我构建了程序和测试,然后执行:gcov mymoneyaccount.cpp

在显示的覆盖范围信息中,我获得:

...文件'mymoneyaccount.cpp'执行的行数:393的8.91%创建'mymoneyaccount.cpp.gcov'

文件'mymoneyaccount.h'执行的行:创建'mymoneyaccount.h.gcov'的25.00%...

“mymoneyaccount.cpp.gcov”中的覆盖范围信息是可以的。 相反,“mymoneyaccount.h.gcov”显示:

    6:   81:class KMM_MYMONEY_EXPORT MyMoneyAccount : public MyMoneyObject, public MyMoneyKeyValueContainer
    ...
    -:  192:  const QString& institutionId(void) const {
    -:  193:    return m_institution;
    -:  194:  }
    ...
    -:  272:  int accountCount(void) const {
#####:  273:    return m_accountList.count();
    -:  274:  };

也许我错了,但这个结果意味着gcov不考虑“返回m_institution” 作为可执行代码,同时考虑将“返回m_accountList.count()”作为可执行代码。 此外,它在类声明的行中显示“6”,因此该文件具有覆盖信息,但不是我所期望的。

我不得不说,也许这个问题与文件和目录的名称有关:

1-目标文件在以“.cpp.o”结尾的“CMakefiles / kmm_mymoney.dir”中创建,例如mymoneyaccount.cpp.o。 因此,使用名称“mymoneyaccount.cpp.gcno”和“mymoneyaccount.cpp.gcda”(当然,在“CMakefiles / kmm_mymoney.dir”目录中)创建“gcno”和“gcda”文件。

2-当我执行时:gcov -o CMakeFiles / kmm_mymoney.dir mymoneyaccount.cpp gcov给出以下错误:

mymoneyaccount.gcno:无法打开笔记文件

所以我必须重新命名这些文件:mv mymoneyaccount.cpp.gcno mymoneyaccount.gcno mv mymoneyaccount.cpp.gcda mymoneyaccount.gcda

最后,我还有一个问题。 当我在包含测试用例的文件中执行gcov时,我的意思是,“gcov mymoneyaccounttest.cpp”而不是“gcov mymoneyaccount.cpp”,我也获得了“mymoneyaccount.h.gcov”文件,但覆盖率信息更差:

#####:   81:class KMM_MYMONEY_EXPORT MyMoneyAccount : public MyMoneyObject, public MyMoneyKeyValueContainer

无论如何,问题是:我应该在实现文件“mymoneyaccount.cpp”还是在测试文件“mymoneyaccounttest.cpp”中执行“gcov”?

抱歉的长度。 谢谢。


非常感谢Tony! 该链接有解决方案。 我只是将优化从-O2更改为-O0,现在结果是:

1: 192: const QString& institutionId(void) const { 
1: 193:     return m_institution; 
-: 194: } 

我必须注意,要获得“mymoneyaccount.cpp.gcov”,我执行“gcov mymoneyaccount.cpp”,但要获得“mymoneyaccount.h.gcov”,我必须执行“gcov mymoneyaccounttest.cpp”。 你知道为什么吗? 这两个文件都包含“mymoneyaccount.h”。


有覆盖范围信息,但不是我所期望的。

这可能是一个XY问题,因为你认为你的程序以你相信的方式执行,但它完全不同。

我会告诉你一个非常简单的程序:

class Example
{
    private:
        int value;

    public:
        Example(const Example& in): value(in.value)
        {
            std::cout << "Here we copy" << std::endl;
        }

        Example(int _value): value(_value)
        {
            std::cout << "Runs with default" << std::endl;
        }

        Example( Example&& in): value( in.value)
        {
            std::cout << "Moved away" << std::endl;
        }

        void show()
        {
            std::cout << "value " <<  value << std::endl;
        }
};

Example GetIt()
{
    return Example(2);
}

int main()
{
    Example ex(Example(1));
    ex.show();

    std::cout << "----------------" << std::endl;

    Example ex2( GetIt());
    ex2.show();
}

输出是:

Runs with default
value 1
Runs with default 
value 2

正如你所看到的,没有你期望的拷贝构造函数被调用,并且也没有调用构造函数。 建设简直没有了! 那么你期望gcov打印出什么? 它只是用int参数打印调用直接调用构造函数。 没有其他的!

你说:

我需要获得完整的覆盖信息...

根本没有办法获得更多的信息作为事实!

如果您的期望与您从分析工具中获得的结果完全不同,请检查您的假设是否正确。 对于我的期望,gcov和gprof工具非常好,代码的工具几乎完美。 但是将被优化掉的代码将不会生成任何调试/分析/覆盖信息。 调试并不总是如此,因为新版本的gcc会生成一些元信息,这些元信息可以链接到原始源代码,如果代码不再存在于可执行文件中,也可以设置断点。 但对于遗漏的构造函数,在调试时没有任何东西存在,因为程序流程只是简单地改变了! 没有cout ,没有调用构造函数,也没有进一步的分析/覆盖信息。 该代码根本不被执行,并且根本没有被使用。 正如你所看到的, cout不叫! 这只是告诉你,代码被“修改”,以其他方式进行操作,就像你已经编码了一样!

我的例子只显示了优化的一个方面! 这只是消除! 还有很多其他优化步骤和策略,还有O0 ! 注意我的代码是用O0编译的,拷贝结构被移走了!

提示:

  • 如果您的调试/覆盖/分析看起来与您的期望不同:请查看程序集以找出真正执行的内容以及涉及哪些源代码行。 你可以调用objdump来获得混合的源代码和汇编器!

  • 如果你缩减你的优化器,请记住你的程序只是运行不同的代码。 没有一个“智能”的解释,结果是不可能的。 这需要一些如何处理这些数据的经验。

  • 如果您确实需要“完整”信息,请问为什么!

  • 如果您认为程序执行路径上没有足够的信息,您应该很高兴! 通常这正好告诉你,通过优化你的执行会缩短一点。

  • 如果你没有在单行/方法中获取分析信息:只需查看使用/调用此功能的块即可。 大部分时间消耗很短,以至于进一步的调查毫无用处。


  • 我想完成我给@Klaus的答案。

    “-O2 -g”和“-O2”这两种组合都给出了该方法的以下覆盖范围信息(我插入的信息仅用于确保方法在测试中执行):

    -:  192:  const QString& institutionId(void) const {
    1:  193:    std::cout << "Inside institutionIdn";
    -:  194:    return m_institution;
    -:  195:  }
    

    这意味着行192和194不被视为可执行文件,但仅限于cout。 标志-g不影响结果(至少在这种情况下)。

    如果我使用“-O0”构建程序,结果是:

    1:  192:  const QString& institutionId(void) const {
    1:  193:    std::cout << "Inside institutionIdn";
    1:  194:    return m_institution;
    -:  195:  }
    
    链接地址: http://www.djcxy.com/p/51011.html

    上一篇: gcov is not generating coverage information for header files

    下一篇: How can I use GDB with GCOV?