第 16 页 LINES tag: tag_lines() 函数

3.4 LINES tag: tag_lines() 函数static void

tag_lines ( const char * filename ATTRIBUTE_UNUSED ,

unsigned tag ATTRIBUTE_UNUSED , unsigned length ATTRIBUTE_UNUSED )

{

if ( flag_dump_contents )

{

unsigned blockno = gcov_read_unsigned ();

char const * sep = NULL ;

while ( 1 )

{

gcov_position_t position = gcov_position ();

const char * source = NULL ;

unsigned lineno = gcov_read_unsigned ();

if ( ! lineno )//lineno=0 时才会执行该 clause ,因此 lineno=0 即为以后的新的文件的标志

{

source = gcov_read_string ();// 该函数读取 length(4 字节 ) 和 length 个 words(4*length 字节 )

if ( ! source )//source 即为文件名,没有源文件了,就退出

break ;

sep = NULL ;

}

if ( ! sep )//sep=NULL 才会执行该 clause ,那么什么时候会为 NULL 呢?——就是新的文件开始,实际上就是 lineno=0

{

printf ( "/n" );

print_prefix ( filename , 0 , position );

printf ( "/tblock %u:" , blockno );

sep = "" ;

}

if ( lineno )

{

printf ( "%s%u" , sep , lineno );

sep = ", " ;

}

else

{

printf ( "%s`%s'" , sep , source );//lineno=0 时,输出该文件名,之后 sep= " : "

sep = ":" ;

}

}

}

}

输出格式:

block blockno:'filename':lineno1, lineno2, ...

例如: block 1:'test.c':4, 7, 9

其中,前面的 block 为提示信息。同上,需要注意前导符或者输出位置。

3.5 COUNTER tag: tag_counters() 函数static void

tag_counters ( const char * filename ATTRIBUTE_UNUSED ,

unsigned tag ATTRIBUTE_UNUSED , unsigned length ATTRIBUTE_UNUSED )

{

static const char *const counter_names [] = GCOV_COUNTER_NAMES ;

unsigned n_counts = GCOV_TAG_COUNTER_NUM ( length );

printf ( " %s %u counts" ,

counter_names [ GCOV_COUNTER_FOR_TAG ( tag )], n_counts );

if ( flag_dump_contents )

{

unsigned ix ;

for ( ix = 0 ; ix != n_counts ; ix ++ )

{

gcov_type count ;

if ( ! ( ix & 7 ))// 如果 counter 较多,则每 8 个 1 行输出,且按 0 , 8 , 16 , ... 输出序号

{

printf ( "/n" );

print_prefix ( filename , 0 , gcov_position ());

printf ( "/t/t%u" , ix );// 输出序号

}

count = gcov_read_counter ();// 读取该 counter ,读取 8 字节,但返回 4 字节

printf ( " " );

printf ( HOST_WIDEST_INT_PRINT_DEC , count );

}

}

}

关于 GCOV_TAG_COUNTER_NUM 和 GCOV_COUNTER_FOR_TAG ,请参考源代码。

counter 的名字定义如下。/* A list of human readable names of the counters */

#define GCOV_COUNTER_NAMES         {"arcs ", "interval", "pow2", "single", "delta"}

输出格式:

arcs n counts //arcs 即为 counter 的名字,如上

0 counter0 counter1 ... counter7// 每 8 个 1 行输出,前面的 0 表示序号

8 counter8 counter9 ... counter15// 前面的 8 表示序号

...

同上,需要注意前导符或者输出位置。

3.6 OBJECT/PROGRAM SUMMARY tag: tag_summary() 函数static void

tag_summary ( const char * filename ATTRIBUTE_UNUSED ,

unsigned tag ATTRIBUTE_UNUSED , unsigned length ATTRIBUTE_UNUSED )

{

struct gcov_summary summary ;

unsigned ix ;

/***** initialize all members with 0 *****/

memset( & summary , 0 , sizeof ( summary ));

unsigned count = gcov_read_summary ( & summary );// 读取该 summary

printf ( " checksum=0x%08x" , summary .checksum );

/* for (ix = 0; ix ! = GCOV_COUNTERS; ix++) *//* 原来的代码 */

for ( ix = 0 ; ix < count ; ix ++ )/* 应该如此修改 */

{

printf ( "/n" );

print_prefix ( filename , 0 , 0 );

printf ( "/t/tcounts=%u, runs=%u" , summary .ctrs [ ix ] .num , summary .ctrs [ ix ] .runs );

printf ( ", sum_all=" HOST_WIDEST_INT_PRINT_DEC , ( HOST_WIDEST_INT ) summary .ctrs [ ix ] .sum_all );

printf ( ", run_max=" HOST_WIDEST_INT_PRINT_DEC , ( HOST_WIDEST_INT ) summary .ctrs [ ix ] .run_max );

printf ( ", sum_max=" HOST_WIDEST_INT_PRINT_DEC , ( HOST_WIDEST_INT ) summary .ctrs [ ix ] .sum_max );

}

}

输出格式:

checksum=0x51924f98

counts=5, runs=1, sum_all=12, run_max=10, sum_max=10

同上,也需要注意前导符或者输出位置。

其中, gcov_read_summary 函数是修改后的函数,在 " Linux 平台代码覆盖率测试 -GCC 如何编译生成 gcov/gcov-dump 程序及其 bug 分析 " 一文没有列出该修改后的函数,其实这篇文章中的 bug 与该函数有关。此处列出其代码。GCOV_LINKAGE unsigned

gcov_read_summary ( struct gcov_summary * summary )

{

unsigned ix ;

struct gcov_ctr_summary * csum ;

summary - >checksum = gcov_read_unsigned (); /***** checksum is a words (4Bytes) *****/

/***** that is, a summry is 32Bytes (sizeof(gcov_type)=4) or 20Bytes (sizeof(gcov_type)=8) *****/

for ( csum = summary - >ctrs , ix = GCOV_COUNTERS_SUMMABLE ; ix -- ; csum ++ )

{

csum - >num = gcov_read_unsigned (); /***** 4Bytes *****/

csum - >runs = gcov_read_unsigned (); /***** 4Bytes *****/

csum - >sum_all = gcov_read_counter (); /***** 8Bytes , but return 4Bytes *****/

csum - >run_max = gcov_read_counter (); /***** 8Bytes , but return 4Bytes *****/

csum - >sum_max = gcov_read_counter (); /***** 8Bytes , but return 4Bytes *****/

}

return GCOV_COUNTERS_SUMMABLE ; /* zubo modified to return the nubmer */

}

gcov_summary 及 gcov_ctr_summary 结构的定义可参考源代码或者 " Linux 平台代码覆盖率测试工具 GCOV 相关文件分析 " 。

4. 小结

本文详细叙述了 gcov-dump 程序的结构和实现原理。也从中学习了其处理各种 tag 用到的 callback 方法,如果你想深入跟踪或学习 gcc 源码,请注意 callback 的使用,因为 gcc 源码中大量地使用了 callback 。

linux代码工具tag,gcov-dump原理分析_Linux平台代码覆盖率测试相关推荐

  1. Linux平台代码覆盖率测试工具GCOV的前端工具LCOV简介

    本博客 http://blog.csdn.net/livelylittlefish 贴出作者(三二一@小鱼)相关研究.学习内容所做的笔记,欢迎广大朋友指正! Content 1. Lcov是什么? 2 ...

  2. Linux平台代码覆盖率测试工具GCOV简介

    本博客 http://blog.csdn.net/livelylittlefish 贴出作者(三二一@小鱼)相关研究.学习内容所做的笔记,欢迎广大朋友指正! Content 1. gcov是什么? 2 ...

  3. java heap分析工具_Java Heap dump文件分析工具jhat简介

    [开发.应用中老是会遇到OutOfMemory异常,而且常常是过一段时间内存才被吃光,这里可以利用java heap dump出jvm内存镜像,然后再对其进行分析来查找问题.<java heap ...

  4. 汉诺塔python代码解释_Python-汉诺塔原理分析

    最近在"廖雪峰的官方网站"学习Python,遇到汉诺塔递归问题百思不得其解,先是百度了汉诺塔原理,然后查看了别人的写的文章,通过整理汇总,希望能够帮助其他人理解. 汉诺塔原理:(来 ...

  5. linux算法设计,红黑树的原理分析和算法设计

    红黑树是60年代中期计算机科学界找寻一种算法复杂度稳定,容易实现的数据存储算法的产物.在优先级队列.字典等实用领域都有广泛地应用,更是70年代提出的关系数据库模型--B树的鼻祖.在Linux kern ...

  6. linux 网站流量日志系统,网站日志分析_linux network的技术博客_51CTO博客

    1.查看TCP连接状态 netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn netstat -n | awk '/^tcp/ {++S[$NF]} ...

  7. 实体机跑gtest单体测试,Linux平台代码覆盖率测试

    PC机是Linux系统,实体机是Android系统,利用gtest进行UT测试生成覆盖率报告(HTML格式). 本文主要是利用U盘将PC机中编译生成文件拷贝到真机上,再生成gcda文件,拷贝回PC机g ...

  8. 常用工具说明--搭建基于rietveld的CodeReview平台(未测试)

    为什么要codereview . 整个团队的编码风格是统一的. . 有高手能对自己的代码指点一二,从而提高编码水平. . 减少低级错误的出现 . 约束自己写高质量的代码,因为是要给人看的. 我们对co ...

  9. 辗转相除法求最大公约数原理分析(附代码实现)

    辗转相除法求最大公约数原理分析(附代码实现) 前言 解释 原理分析 代码 结语 前言 辗转相除法用起来很简单,但是其原理却自己想不明白.于是乎看了几篇有关辗转相除法原理的分析,在这里自己写下自己的理解 ...

最新文章

  1. javascript音频管理方案:SoundManager2
  2. SSM 返回静态页面HTML Controller 被递归调用引起的StackOverflowError
  3. Android Treble 计划技术文档
  4. hbase启动的时候报错java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
  5. iofd:文件描述符_文字很重要:谈论设计时18个有意义的描述符
  6. 精读linux源码,Linux基础入门的操作精读.doc
  7. php 筛选搜索,筛选——搜索
  8. 【李宏毅2020 ML/DL】P75 Generative Adversarial Network | Conditional GAN
  9. 项目开发经常使用PHP功能
  10. masm32基础使用(win10+cmd)
  11. 从百草园到三味书屋 鲁迅
  12. uva 509 RAID!(磁盘数据)
  13. 一个php+ajax的在线匿名聊天室,PHP任意环境都可用,无需复杂配置,移动端电脑端互通流畅,随时随地聊个痛快~
  14. if scl.shape = avg.shape: AttributeError: ‘float‘ object has no attribute ‘shape‘
  15. 使用文本排版大师(TxtEdit/TEditer)在记事本文件中绘制表格。
  16. 曹汛:计算摄像学研究 | VALSE2017之十六
  17. SAP_常用BADI清单
  18. 最新的SpringCloud(H版Alibaba)技术(11-12初级部分,网关【Gateway】)
  19. WMI常见问题及解决方法
  20. 使用Markup解析xml字符串

热门文章

  1. 7时过2小时是几时_2017最北师大版二年级下册数学第七单元《时、分、秒》过关检测卷...
  2. MAYA建模桌面一角_maya怎么建模逼真的学生书桌书桌桌面?
  3. Python处理csv文件
  4. 用FFmpeg从视频截取任意一帧图片的解决办法~
  5. 如何给虚拟机上的linux系统添加虚拟硬盘
  6. [Linux C]递归遍历指定目录,以目录树形式展示
  7. gcc -fPIC选项
  8. 微软面试题:有100万个数字(1到9),其中只有1个数字重复2次,如何快速找出该数字
  9. Windows PowerShell安装指定版本vue/cli脚手架失效解决办法;vue : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\vue
  10. ant design datepicker处理日期范围操作