分类分类
关注+2011-07-12作者:清晨
2.5 分配空间函数 gcov_allocate
代码如下。其中的注释为笔者加入。
#if ! IN_LIBGCOV
static void
gcov_allocate ( unsigned length )
{
size_t new_size = gcov_var .alloc ;
if ( ! new_size )
new_size = GCOV_BLOCK_SIZE ; /***** if new_size==0, then, new_size=1024( GCOV_BLOCK_SIZE=1024 ) */
new_size += length ; /***** if length==1, then, new_size=1025 */
new_size *= 2 ; /***** then, new_size=1025*2=2050 */
gcov_var .alloc = new_size;
gcov_var .buffer = xrealloc ( gcov_var .buffer , new_size << 2="" size="1025*4=8200">
}
#endif
实际上 gcov_var.alloc 是一个内存 block ,以 4 字节为一个单位。由代码及其注释可以看出,当 length=1 时, gcov_var.alloc=2050 ,调用 gcov_allocate 后,实际上分配了 2050*4=8200 个字节的空间给 gcov_var.buffer 。
此处,不得不介绍一下 gcov_var 。
2.6 重要数据结构 gcov_var
gcov_var 是个全局变量,其作用就是在 gcov/gcov-dump 程序运行期间保存操作的文件信息,例如,文件指针、某个 block 的 start/offset/length 、文件内容 buffer 等信息,定义如下。
/* Optimum number of gcov_unsigned_t's read from or written to disk. */
#define GCOV_BLOCK_SIZE ( 1 << 10="">
GCOV_LINKAGE struct gcov_var
{
FILE * file ;
gcov_position_t start ; /* Position of first byte of block */
unsigned offset ; /* Read/ write position within the block. */
unsigned length ; /* Read limit in the block. */
unsigned overread ; /* Number of words overread. */
int error ; /* < 0 overflow, > 0 disk error. */
int mode ; /* < 0 writing, > 0 reading */
#if IN_LIBGCOV
/* Holds one block plus 4 bytes, thus all coverage reads & writes
fit within this buffer and we always can transfer GCOV_BLOCK_SIZE
to and from the disk. libgcov never backtracks and only writes 4 or 8 byte objects. */
gcov_unsigned_t buffer [ GCOV_BLOCK_SIZE + 1 ];
#else
int endian ; /* Swap endianness. */
/* Holds a variable length block, as the compiler can write strings and needs to backtrack. */
size_t alloc ;
gcov_unsigned_t * buffer ;
#endif
} gcov_var ATTRIBUTE_HIDDEN ;
在 gcov-dump 程序中, sizeof( gcov_type )=sizeof( gcov_unsigned_t )=4 , sizeof(gcov_var) =40 。 gcov_var 的值一个例子可以参考 2.4 节,此处不再赘述。
3. 处理 tag 的 callback 分析
3.1 FUNCTION tag: tag_function() 函数
static void
tag_function ( const char * filename ATTRIBUTE_UNUSED ,
unsigned tag ATTRIBUTE_UNUSED , unsigned length ATTRIBUTE_UNUSED )
{
unsigned long pos = gcov_position ();
/***** for function, it will print ident and checksum */
printf ( " ident=%u" , gcov_read_unsigned ());
printf ( ", checksum=0x%08x" , gcov_read_unsigned ());
if ( gcov_position () - pos < length ) // 一般对于 .gcno 文件该条件才满足,才能执行该 clause
{
const char * name ;
name = gcov_read_string (); // 该函数读取 length(4 字节 ) 和 length 个 words(4*length 字节 ) ,读取函数名字
printf ( ", `%s'" , name ? name : "NULL" );
name = gcov_read_string (); // 读取源文件名字
printf ( " %s" , name ? name : "NULL" );
printf ( ":%u" , gcov_read_unsigned ()); // 读取该函数在该源文件中的行号
}
}
输出格式:
.gcda 文件输出: ident=3, checksum=0xeb65a768
.gcno 文件输出: ident=3, checksum=0xeb65a768 , `main' test.c:4
其中,划线部分分别为: 函数名 源文件名 : 行号
相关文章
更多+相同厂商
热门推荐
点击查看更多
点击查看更多
点击查看更多
说两句网友评论