XCode 5.1 单元测试覆盖率分析在使用块的文件上失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22343725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 04:44:54  来源:igfitidea点击:

XCode 5.1 Unit Test Coverage Analysis Fails On Files Using Blocks

xcodegcovlcovxcode5.1test-coverage

提问by LeffelMania

Today I was tasked with adding unit test coverage analysis to our code base. Today is also the day iOS 7.1 is released along with XCode 5.1. From the release notes:

今天,我的任务是将单元测试覆盖率分析添加到我们的代码库中。今天也是 iOS 7.1 与 XCode 5.1 一起发布的日子。从发行说明:

The gcov tool for code coverage testing has been reimplemented. The new version uses the llvm-cov tool from the LLVM project. It is functionally equivalent to the old version for all significant features. The location of gcov within Xcode has also moved, use xcrun to invoke it. If you find problems, please file bug reports. For this release, you can still use the old version of gcov from GCC, which is available as gcov-4.2. 11919694 updated

重新实现了用于代码覆盖率测试的 gcov 工具。新版本使用了 LLVM 项目中的 llvm-cov 工具。对于所有重要功能,它在功能上等同于旧版本。gcov 在 Xcode 中的位置也移动了,使用 xcrun 调用它。如果您发现问题,请提交错误报告。对于此版本,您仍然可以使用来自 GCC 的旧版本 gcov,该版本可作为 gcov-4.2 使用。11919694 更新

I realized this only after following several instructionalblogposts, getting my environment set up properly - generating .gcda/.gcno files in the simulator's build folders upon testing - and having the report generating tools heretry to parse them into a report. (that is a ./getcov script which gathers your environment variables to pass to lcov-1.10 scripts to generate the report)

我是在遵循几篇教学博客文章,正确设置我的环境 - 在测试时在模拟器的构建文件夹中生成 .gcda/.gcno 文件之后才意识到这一点的- 并在此处使用报告生成工具尝试将它们解析为报告。(这是一个 ./getcov 脚本,它收集您的环境变量以传递给 lcov-1.10 脚本以生成报告)

The first hurdle was that the new bundled gcovprogram doesn't support the -vargument to get the version, which is the first step of lcov's initialization. Seemed like a non-starter already, but reading the release notes above I modified the lcovscript to use the old gcov-4.2version and got that solved.

第一个障碍是新的捆绑gcov程序不支持-v获取版本的参数,这是lcov初始化的第一步。看起来已经不是初学者了,但是阅读上面的发行说明我修改了lcov脚本以使用旧gcov-4.2版本并解决了这个问题。

However, lcoverrored out very early in processing my coverage data files. This generated a report with maybe the first 10 or so files alphabetically in my project. Not particularly useful. The error output was minimal and unhelpful as well:

但是,lcov在处理我的覆盖数据文件时很早就出错了。这生成了一个报告,其中可能包含我项目中按字母顺序排列的前 10 个左右的文件。不是特别有用。错误输出很小,也无济于事:

geninfo: ERROR: GCOV failed for (build_artifacts)/(class_that_errored).gcda!

geninfo: 错误: (build_artifacts)/(class_that_errored).gcda 的 GCOV 失败!

I modified the lcovscript to print the error it was getting (which only yielded 11unfortunately, couldn't find any reference in the gcov(-io).c code) and to continue operation instead of quitting, so I was left with a lot more files in the report, but still probably 85% of my source files had errored out as above.

我修改了lcov脚本以打印它得到的错误(11不幸的是它只产生了,在 gcov(-io).c 代码中找不到任何引用)并继续操作而不是退出,所以我留下了更多报告中的文件,但仍然可能有 85% 的源文件如上所述出错。

The only pattern I could discern between the files that successfully wound up in the report and the ones that threw an error was that any file that used an in-line block declaration failed. None of the files that passed used blocks in any fashion, and all the files I've checked that failed contain blocks. Strange.

我能在报告中成功结束的文件和抛出错误的文件之间辨别的唯一模式是任何使用内嵌块声明的文件都失败了。没有一个文件以任何方式通过使用块,我检查过的所有文件都包含块。奇怪的。

Then I figured out I could open the individual .gcda files in CoverStory, including the ones that had errored in the lcovscript. In the message window beneath the coverage report, all the files that had errored had the warning messages:

然后我发现我可以在CoverStory 中打开单个 .gcda 文件,包括那些在lcov脚本中出错的文件。在覆盖率报告下方的消息窗口中,所有出错的文件都有警告消息:

(class_that_errored).gcno:no lines for '__copy_helper_block_'

(class_that_errored).gcno:no lines for '__destroy_helper_block_'

(class_that_errored).gcno:没有“__copy_helper_block_”行

(class_that_errored).gcno:没有“__destroy_helper_block_”行

My best hypothesis at this point is that the new XCode 5.1 is generating .gcda files that the old gcov-4.2program isn't equipped to deal with regarding block declarations.

在这一点上,我最好的假设是新的 XCode 5.1 正在生成 .gcda 文件,旧gcov-4.2程序不具备处理有关块声明的能力。

But I've exhausted everything I can think to try, so I'm here to ask if anybody has a piece of knowledge that I've missed, or has any ideas to further the debugging effort. Or if anyone is successfully measuring test coverage since today's XCode 5.1 update with the new gcov, I'd love to hear about any changes you had to make as well.

但是我已经用尽了所有我能想到的尝试,所以我在这里询问是否有人有我遗漏的知识,或者有任何想法来进一步调试工作。或者,如果自今天使用新的 XCode 5.1 更新以来,有人成功地测量了测试覆盖率gcov,我也很想知道您必须做出的任何更改。

回答by Endersstocker

The problem is in the LCOV 1.10 geninfoscript. It tests for the current version of gcov. It does this by parsing the version string. Since gcov now points to llvm-cov, the version string is parsed incorrectly.

问题出在 LCOV 1.10 geninfo脚本中。它测试当前版本的 gcov。它通过解析版本字符串来做到这一点。由于 gcov 现在指向 llvm-cov,因此版本字符串解析不正确。

The solution is to modify geninfo's get_gcov_version() subroutine. In line 1868, change -vto --version. Then replace line 1874with:

解决方法是修改geninfo的 get_gcov_version() 子程序。在第1868行中,更改-v--version。然后将第1874行替换为:

if ($version_string =~ m/LLVM/)
{
    info("Found llvm-cov\n");
    $result = 0x40201;
}
elsif ($version_string =~ /(\d+)\.(\d+)(\.(\d+))?/)

 

 

The modified subroutine should look like this:

修改后的子程序应如下所示:

sub get_gcov_version()
{
    local *HANDLE;
    my $version_string;
    my $result;

    open(GCOV_PIPE, "-|", "$gcov_tool --version")
        or die("ERROR: cannot retrieve gcov version!\n");
    $version_string = <GCOV_PIPE>;
    close(GCOV_PIPE);

    $result = 0;
    if ($version_string =~ m/LLVM/)
    {
        info("Found llvm-cov\n");
        $result = 0x40201;
    }
    elsif ($version_string =~ /(\d+)\.(\d+)(\.(\d+))?/)
    {
        if (defined())
        {
            info("Found gcov version: ..\n");
            $result =  << 16 |  << 8 | ;
        }
        else
        {
            info("Found gcov version: .\n");
            $result =  << 16 |  << 8;
        }
    }
    return ($result, $version_string);
}

 

 

NOTE:Make sure --gcov-toolis notset to gcov-4.2.

注意:确保选中--gcov-tool不是设置为gcov-4.2

回答by Neil Gall

Rather than modifying geninfoI created an llvm-cov-wrapperscript and used lcov's --gcov-toolcommand line option:

geninfo我没有修改我创建了一个llvm-cov-wrapper脚本并使用了 lcov 的--gcov-tool命令行选项:

#!/bin/bash
# llvm-cov wrapper to make it behave more like gcov

if [ "" = "-v" ]; then
    echo "llvm-cov-wrapper 4.2.1"
    exit 0
else
    /usr/bin/gcov $*
fi

回答by Yiwei

Actually I noticed that lcov is invoking gcov with -b option and gcov-4.2 will crash on this option (raise segmentation fault). If I remove the -b option from getinfo, then even though it still shows some error info, the gcov file can still be generated.

实际上我注意到 lcov 正在使用 -b 选项调用 gcov 并且 gcov-4.2 将在此选项上崩溃(引发分段错误)。如果我从 getinfo 中删除 -b 选项,那么即使它仍然显示一些错误信息,仍然可以生成 gcov 文件。

That is probably why coverstory can still give coverage output. So I guess the workaround is to remove -b option from lcov. And also as you suggested, ignore the error in getinfo

这可能就是coverstory仍然可以提供覆盖输出的原因。所以我想解决方法是从 lcov 中删除 -b 选项。而且正如你所建议的,忽略 getinfo 中的错误

回答by Daniel Wabyick

For anyone new to this thread, note that lcov-1.11 is out. This eliminates the issue with gcov -vcompatibility. However, I am using XCode 6.1 and still getting errors on some files.

对于此线程的新手,请注意 lcov-1.11 已发布。这消除了gcov -v兼容性问题。但是,我使用的是 XCode 6.1 并且仍然在某些文件上出错。

geninfo: WARNING: /Users/XXX/MyFile.gcno: found unrecognized record format - skipping

geninfo: WARNING: /Users/XXX/MyFile.gcno: found unrecognized record format - skipping

Note that you can add --ignore-errors graphto skip over these errors, but the problem isn't really solved.

请注意,您可以添加--ignore-errors graph跳过这些错误,但问题并没有真正解决。