Mar*_*ton 7 xcode objective-c llvm gcov
我正在尝试理解gcov工具的输出.没有选项运行它是有道理的,但我想尝试理解分支覆盖选项.不幸的是,很难理解分支机构的作用以及为什么不采用它们.下面是方法的输出(使用最新的LLVM/Clang构建进行编译).
function -[TestCoverageAppDelegate loopThroughArray:] called 5 returned 100% blocks executed 88%
5: 30:- (NSInteger)loopThroughArray:(NSArray *)array {
5: 31: NSInteger i = 0;
22: 32: for (NSString *string in array) {
branch 0 taken 0
branch 1 taken 7
-: 33:
22: 34: }
branch 0 taken 4
branch 1 taken 3
branch 2 taken 0
branch 3 taken 3
5: 35: return i;
-: 36:}
Run Code Online (Sandbox Code Playgroud)
我通过这个运行5次测试,传入nil,一个空数组,一个包含1个对象的数组,一个包含2个对象的数组和一个包含4个对象的数组.我可以猜测,在第一种情况下,分支1意味着"进入循环",但我不知道分支0是什么.在第二种情况下,分支0似乎再次循环,分支1似乎结束循环,分支3继续/退出循环,但我不知道分支2是什么或为什么/什么时候执行它.
如果有人知道如何破译分支信息,或者知道任何有关这一切的详细文档,我会很感激帮助.
Gcov 的工作原理是检测(在编译时)机器命令的每个基本块(您可以考虑汇编程序)。基本块是指代码的线性部分,内部没有分支,内部没有标签。因此,当且仅当您开始运行基本块时,您才会到达基本块的末尾。基本块以 CFG(控制流图,将其视为有向图)组织,它显示了基本块之间的关系(从 V1 到 V2 的边是 V1 调用 V2;V2 被 V1 调用)。因此,profile-arcs编译器和 gcov 模式希望获取每一行的执行计数,并通过计算基本块执行来实现这一点。CFG 中的一些边被检测,一些则没有,因为图中的基本块之间存在代数关系。
您的 ObjC 构造(for..in)被降低(在早期编译中转换)为几个基本块。因此,gcov 会看到 4 个分支,因为它只看到降低的 BB。它对这种降低一无所知,但它知道哪一行对应于每个汇编器指令(这是调试信息)。因此,分支是 CFG 的边缘。
如果您想查看基本块,您应该对已编译程序进行汇编程序转储或反汇编二进制文件或从编译器转储 CFG。您可以对模态profile-arcs和非profile-arcs模态执行此操作并比较它们。
profile-arcs模式将有很多调用和增量,例如“__llvm_gcov_ctr”或“__llvm_gcda_edge” - 它是基本块的实际检测。
| 归档时间: |
|
| 查看次数: |
2964 次 |
| 最近记录: |