日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

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

發布時間:2023/12/10 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux代码工具tag,gcov-dump原理分析_Linux平台代码覆盖率测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

第 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平台代码覆盖率测试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。