在Xcode 5中运行代码覆盖率时,出现了数十个"profiling:invalid arc tag"错误。

47
在 Xcode 5 中启用代码覆盖率并运行我的测试目标时,构建输出会出现数十条以下消息:
profiling:invalid arc tag (0x...)

似乎这不会影响测试,因为测试已经成功完成了,并且GCDA覆盖文件也如预期生成。

不知道这条消息是什么意思,或者如何禁止这些消息/解决问题,因为它们会混淆构建输出并使查找测试结果变得困难。


你有关于这个问题的其他发现吗?唯一提供的答案对我没有帮助,因为我没有配置自定义的gcov测试观察器(而且我猜想你也没有,因为你没有接受)。 - Dov
7个回答

51

很可能这是由于构建工具无法将当前结果合并到现有的 .gcda 覆盖文件中导致的。正如 Dave Meehan 在这里指出的那样,有一种强制的方法是通过清理产品构建文件夹来处理,但一种较不过激的方法是在生成它们的目标(对我而言,只是测试目标)作为构建过程的一部分删除 .gcda 文件。 Dave 包含了一个脚本示例可作为构建阶段包含,或手动放置到项目根目录中:

find . -name "*.gcda" -print0 | xargs -0 rm

1
这是正确的答案。Xcode 5.1使运行__gcov_flush来清除GCDA文件变得不必要,但这个问题仍然存在,因此明显不是__gcov_flush引发了这个问题。在“编译源代码”之前添加一个清除.gcda文件的构建阶段(应用程序和测试目标都包括在内)可以解决这个问题。我同意jstevenco的看法,即将当前结果合并到现有的.gcda文件中可能是一个问题。 - jasonjwwilliams
13
或者简单地执行以下命令: $ find . -name '*.gcda' -delete 该命令会查找当前目录及其子目录中所有扩展名为 .gcda 的文件,并将它们删除。 - bigkm
在Xcode7中它并没有帮助我。在测试运行结束时,我仍然有很多类似的信息。它不仅指向ObjectiveC.gcda文件,还指向其他一些文件,如CoreLocation.gcda。 - Rustam Iuzmukhametov

32

对于Xcode 7用户,你可能会想知道为什么你的单元测试在收到像这样的消息后崩溃了。我发现的解决办法是,确保构建流程中涉及的所有可能目标(包括所有库)都将这两个构建设置设置为NO:

GCC_GENERATE_TEST_COVERAGE_FILES = NO;
GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = NO;

如果您在构建设置中搜索“代码生成”部分,您将找到以下选项:“生成测试覆盖文件”和“检测程序流程”。

更多信息请参见https://developer.apple.com/library/ios/qa/qa1514/_index.html


3
关闭名为“Instrument Program Flow”的GCC_INSTRUMENT_PROGRAM_FLOW_ARCS选项可以解决问题,但这会关闭代码覆盖率。看起来这是Xcode 7的一个bug(我们现在使用的是beta 5版本)。希望苹果能尽快修复。 - n8tr
在Xcode 7中禁用GCC_INSTRUMENT_PROGRAM_FLOW_ARCS并不会禁用代码覆盖率。 - quellish
@quellish 是的,没错,但是如果不启用它,就无法生成GCDA文件。 - jstevenco
@jstevenco 代码覆盖率有多种格式。Xcode 7工具使用基于clang的仪器化分析生成代码覆盖信息。随着Swift的引入,GCov支持已被弃用,因为它是遗留GCC支持的一部分。GCov文件仍然可以生成(即使将GCC_INSTRUMENT_PROGRAM_FLOW_ARCS设置为NO,也可以使用等效的链接器标志),但可能会有所不同。 - quellish

4

虽然这是一个老问题,但现在Xcode 7 GM已经发布,这种行为没有改变。我认为问题出在测试应用程序目标的代码覆盖率与主目标的代码覆盖率发生冲突。

假设您实际上并不关心测试目标的代码覆盖率,这些设置可以避免出现错误,而无需额外的脚本或删除文件:

在您的主要目标(无论是框架还是应用程序)中设置:

 Enable Code Coverage Support to YES
 Generage Legacy Test Coverage Files to YES
 Instrument Program Flow to YES

为了我的目的,我只在调试构建中进行了此操作,但您的需求可能有所不同。

然后在您的测试目标中设置:

 Enable Code Coverage Support to NO
 Generage Legacy Test Coverage Files to NO
 Instrument Program Flow to NO

这样做解决了错误信息,同时仍然允许适当地创建代码覆盖率文件。

虽然这个问题早已存在,但由于在XCode 7中仍然出现错误,我发现这种解决方案比使用特殊脚本删除文件更好。


3
这对我的情况没有帮助。 - Goles
1
为了使其工作,我必须将所有内容都设置为NO,包括我的主目标。Xcode 7.2.1。 - Gabe
将测试覆盖率的“仪器程序流”设置为NO。 - Tim007

2
我遇到了同样的问题。在我的appDelegate中,在applicationWillTerminate:下,我有__gcov_flush();。将其注释掉可以消除构建输出中的invalid arc tag消息。
我正在进一步研究为什么会出现这种情况。我知道,如果我完全清理我的项目并删除DerivedData目录,这些消息将在我的测试运行几次后停止。 编辑:我似乎已经为自己解决了这个问题。在我的appDelegate中,我有以下内容:
#ifdef DEBUG
+ (void)initialize {
    [[NSUserDefaults standardUserDefaults] setValue:@"XCTestLog,GcovTestObserver"
                                         forKey:@"XCTestObserverClass"];
    [super initialize];
}
#endif

我把GcovTestObserver拼错了,纠正后消息就停止显示了。请确保在测试目标中还有XCTestObserver的子类,覆盖stopObserving方法并添加以下内容:

- (void) stopObserving
{
    [super stopObserving];
    UIApplication* application = [UIApplication sharedApplication];
    [application.delegate applicationWillTerminate:application];
}

删除派生数据对我有用,至少在我再次运行测试的前两次中有效。 - Josh Brown
在Xcode 5.1中,您不再需要__gcov_flush()解决方法:http://qualitycoding.org/xcode51-code-coverage/。然而,我仍然看到这个问题。 - jasonjwwilliams

0

你可能想要清除 所有 派生数据文件夹。特别是如果你升级了 Xcode 或使用多个 Xcode 版本。

有一次我在我们的集成服务器上将 Xcode 从 6.2 升级到 6.3 后就遇到了这个问题,我们在日志中看到了这些消息,以及由 frankencover.it 生成的覆盖率报告中缺少的类。删除集成服务器内部的 DerivedData 文件夹可以解决这个问题。

find /Library/Developer/XcodeServer -name DerivedData -print0 | xargs -0 rm -rf

-2
为了解决控制台中出现“无法合并先前的GCDA文件:损坏的弧标记”消息的问题,可以通过在目标设置中将“启用模块(C和Objective-C)”设置为“否”,避免生成ObjectiveC.gcda文件。这样做可以有效地解决该问题。

将“启用模块(C 和 Objective-C)”设置为“是”,以便导入UIKit。 - Tim007

-2

我花了一些时间试图找出如何摆脱那些丑陋和烦人的消息:

profiling: /Users/appfactory/Desktop/WORK/App/trunk/ObjectiveC.gcda: cannot merge previous GCDA file: corrupt arc tag (0x00000000)

这似乎是Xcode 7的问题,在当前的Xcode 7.1 beta 2中没有得到解决。

问题是由于未能将现有的.gcda覆盖率文件与当前结果合并而引起的。

我尝试过:

  1. 使用RunScript删除那些.gcda文件-在我的情况下无效

echo "Delete .gcda files" echo "${OBJECT_FILE_DIR_normal}/${CURRENT_ARCH}"

注意:ObjectiveC.gcda文件可能位于不同的位置!

  1. 将以下构建设置设置为YES-也没有帮助

    • 启用代码覆盖支持为YES

    • 生成传统测试覆盖文件为YES

    • 仪器程序流程为YES

  2. 我的解决方案:

为主要目标设置以下构建设置

  • 启用代码覆盖支持为 YES

  • 生成传统测试覆盖率文件为 YES

  • 不对程序流进行仪器测量

为测试目标(以及任何其他目标)设置以下构建设置

  • 启用代码覆盖支持为 NO

  • 生成传统测试覆盖率文件为 NO

  • 不对程序流进行仪器测量

希望有所帮助!


我们需要将“仪器程序流”设置为NO以进行测试覆盖。 - Tim007

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接