了解gcov文件中的分支 [英] Understanding branches in gcov files

查看:222
本文介绍了了解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:}

我对此进行了5次测试,传入了nil,一个空数组,一个包含1个对象的数组,包含2个对象的数组和包含4个对象的数组.我可以猜测在第一种情况下,分支1的意思是进入循环",但是我不知道分支0是什么.在第二种情况下,分支0似乎再次循环,分支1似乎结束循环,分支3继续/退出循环,但是我不知道分支2是什么或为什么/何时执行. /p>

如果有人知道如何解密分支信息,或者知道任何有关其含义的详细文档,我将不胜感激.

解决方案

Gcov通过检测(编译时)机器命令的每个基本块(您可以考虑使用汇编程序)来工作. 基本块表示代码的线性部分,其中没有分支,也没有标签.因此,当且仅当您开始运行基本块时,您才会到达基本块的末尾.基本块以CFG(控制流程图,将其视为有向图)进行组织,该图显示了基本块之间的关系(从V1到V2的边是V1称为V2;而V2则由V1调用).因此,编译器和gcov的profile-arcs模式希望获取每一行的执行计数,并通过对基本块执行进行计数来实现. CFG中的某些边缘是有仪器的,而有些则没有,因为图中基本块之间存在代数关系.

您的ObjC构造(for..in)被降低(在早期编译中转换为)几个基本块.因此,gcov看到4个分支,因为它仅看到降低的BB.它对此降低一无所知,但知道每条汇编程序指令对应哪一行(这是调试信息).因此,分支是CFG的边缘.

如果要查看基本块,则应执行已编译程序的汇编程序转储,或反汇编二进制文件或从编译器转储CFG.您可以同时在profile-arcs和非profile-arcs模式下进行此操作并进行比较.

profile-arcs模式将有很多调用,并带有诸如"__llvm_gcov_ctr"或"__llvm_gcda_edge"之类的增量-这是对基本块的实际检测.

I'm trying to understand the output of the gcov tool. Running it with no options makes sense, but I'm wanting to try and understand the branch coverage options. Unfortunately it's hard to make sense of what the branches do and why they aren't taken. Below is the output for a method (compile using the latest LLVM/Clang build).

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:}

I've run 5 test through this, passing in nil, an empty array, an array with 1 object, and array with 2 objects and an array with 4 objects. I can guess that in the first case, branch 1 means "go into the loop" but I haven't a clue what branch 0 is. In the second case branch 0 seems to be loop through again, branch 1 seems to be end the loop and branch 3 is continue/exit the loop, but I have no idea what branch 2 is or why/when it would be executed.

If anyone knows how to decipher the branch info, or knows of any detailed documentation on what it all means, I'd appreciate the help.

解决方案

Gcov works by instrumenting (while compiling) every basic block of machine commands (you can think about assembler). Basic block means a linear section of code, which have no branches inside it and no lables inside it. So, If and only if you start running a basic block, you will reach end of basic block. Basic blocks are organized in CFG (Control flow graph, think about it as directed graph), which shows relations between basicblocks (edge from V1 to V2 is V1 calls V2; and V2 is called by V1). So, profile-arcs mode of compiler and gcov want to get execution count for every line and do this via counting basic block executions. Some of edges in CFG are instrumented and some are not, because there are algebraic relations between basic blocks in graph.

Your ObjC construction (for..in) is lowered (converted in early compilation) to several basic blocks. So, gcov sees 4 branches, because it sees only lowered BBs. It knows nothing about this lowering, but it knows which line corresponds to every assembler instruction (this is debug info). So, branches are edges of CFG.

If you want to see basic blocks, you should do an assembler dump of compiled program or disassemble a binary or dump CFG from compiler. You can do this both for profile-arcs and non-profile-arcs modes and compare them.

profile-arcs mode will have a lot calls and increments of something like "__llvm_gcov_ctr" or "__llvm_gcda_edge" - it is an actual instrumentation of basic blocks.

这篇关于了解gcov文件中的分支的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆