【问题标题】:Override gcov functions to get executed code lines覆盖 gcov 函数以获取执行的代码行
【发布时间】:2012-12-23 11:39:40
【问题描述】:

我想使用 gcov 获取项目的所有已执行代码行。例如像这样的代码:

int main()
{
   int i=0;
   for(i=0;i<3;i++)printf("Hello");
   return 0;
}

结果会是这样的:

1)int i=0;
2)for(i=0;i<3;i++)
3)printf("Hello");
4)for(i=0;i<3;i++)
5)printf("Hello");
6)for(i=0;i<3;i++)
7)printf("Hello");
8)for(i=0;i<3;i++)
9)return 0;

主要思想是通过重写libgcov来实现自己的gcov函数。之后结合使用它 gcc -fprofile-arcs -ftest-coverage test.c -o test -lanothergcov

那么,做这样的事情是否正确,否则它将不起作用,还有任何人使用 gcov 的源代码从它获取所需的信息,它不提供吗?

【问题讨论】:

    标签: c linux gcc gcov


    【解决方案1】:

    简单地重写 libgcov 是不可能的。您必须重写相应的 gcc 代码,在每行之间注入计数器递增指令。

    检测后,您的代码将基本上执行为:

     crt0: 
         __gcov_init(main_locals);
         main();
         __gcov_exit(); // dump the counters to files
    
     int main() {
         static GcovStruct_t local;
         local.Counter[0]++;
         for (i=0;i<3;i++) {
         local.Counter[1]++;
         printf("Hello");
         local.Counter[2]++;
         }
         local.Counter[3]++;
     }
    

    也许还有一些事情要做,因为您可以使用
    &lt;prompt&gt; gcc -S -fprofile-arcs -ftest-coverage 来获取中间 .s 文件:

        movq    .LPBX1(%rip), %rax
        addq    $1, %rax
        movq    %rax, .LPBX1(%rip)
    

    通过搜索和替换来修改这几乎是微不足道的:

        movq    .LPBX1(%rip), %rax   -> leaq    .LPBX1(%rip), %rax
        addq     $1, %rax            -> pushq %rax
                                        call     __init_add_line_number_to_list
        movq    %rax, .LPBX1(%rip)   -> -- remove this --
    

    然后您需要新引入的例程来递增 qword 指针并将该地址插入到一些额外的结构中,这些结构将由您接下来要修改的 gcov 工具处理。

    【讨论】:

    • 感谢您的回答。主要思想是编译器不应该被触及,只使用它的参数,修改的库(例如可以在 gcc3 和 gcc4 中工作)获取此信息。所以据我了解,它只能由 modyfieng gcc 编译器完成,对吗?
    • 基本上它需要 gcc 修改,但正如我稍后展示的那样,存在一个简单的 1:1 映射来修改 gcc .s 输出(至少在 x64 架构中),重新编译后应该可以工作:gcc file.s -lmygcov
    • 好的,(没有任何代码,只是想法,可能是错误的):gcov 将其执行次数作为每行代码的输出,因此它知道确定的行执行了多少 - gcov 可以解析该信息,使其知道线路和信息。
    • 这几乎涵盖了它。为此,gcov 读取运行时创建的文件 source_code.gcda 和编译时生成的文件 source_code.gcdo。
    猜你喜欢
    • 2011-05-11
    • 1970-01-01
    • 2012-11-03
    • 2012-11-22
    • 2016-05-09
    • 2011-02-26
    • 1970-01-01
    • 2018-10-10
    • 2015-09-29
    相关资源
    最近更新 更多