第 10 页 COUNTER tag: tag_counters() 函数 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 相关文件分析 " 。