本博客http://blog.csdn.net/livelylittlefish 贴出作者(三二一@小鱼)相关研究、学习内容所做的笔记,欢迎广大朋友指正!
Content
1. 使用 od 命令 dump 文件内容
2. 文件内容解析
(1) file magic
(2) version
(3) time stamp
(4) FUNCTION tag
(5) COUNTER tag
(6) OBJECT SUMMARY tag
(7) PROGRAM SUMMARY tag
(8) file end
3. 文件读取函数及其调用过程
3.1 读取 / 写入相关调用
3.2 程序退出点
Appendix: gcov 文件格式定义
本文仍以 Linux 平台代码覆盖率测试工具 GCOV 简介 一文的例子为例,分析 gcda/gcno 的文件格式和读取 / 写入方法。
1. 使用 od 命令 dump 文件内容
# od -t x4 -w16 test.gcda
0000000 67636461 34303170 4e8eb3f0 01000000 //magic version stamp tag
0000020 00000002 00000003 eb65a768 01a10000 //length func_ident checksum tag
0000040 0000000a 0000000a 00000000 00000000 //length
0000060 00000000 00000001 00000000 00000000
0000100 00000000 00000001 00000000 a1000000 //0xa1000000 is GCOV_TAG_OBJECT_SUMMARY
0000120 00000009 00000000 00000005 00000001 //length
0000140 0000000c 00000000 0000000a 00000000
0000160 0000000a 00000000 a3000000 00000009 //0xa3000000 is GCOV_TAG_PROGRAM_SUMMARY
0000200 51924f98 00000005 00000001 0000000c //checksum number runs
0000220 00000000 0000000a 00000000 0000000a
0000240 00000000 00000000
0000250
od 命令的使用方法可参考其 manual 页。
2. 文件内容解析
(1) file magic
0x67636461 is file magic, that is, "gcda".
0x67636461 是怎么来的呢?细心的读者一定会发现,实际上就是 'g','c','d','a' 字符的 ASCII 码组成的,即 0x67,0x63,0x64,0x61 。即采用字符的 ASCII 码作为文件 magic 。可参考附录的解释。
defined as the following.
/* File suffixes. */
#define GCOV_DATA_SUFFIX ".gcda"
#define GCOV_NOTE_SUFFIX ".gcno"
/* File magic. Must not be palindromes. */
#define GCOV_DATA_MAGIC ((gcov_unsigned_t)0x67636461 ) /* "gcda" */
#define GCOV_NOTE_MAGIC ((gcov_unsigned_t)0x67636e6f ) /* "gcno" */
(2) version
0x34303170 is the GCOV_VERSION, that is, 401p, 即 4.1.2p
该版本常量在 gcov_iov.h 文件中定义,如下。
/* Generated automatically by the program `./gcov-iov'
from `4.1.2 (4 1) and p (p)'. */
#define GCOV_VERSION ((gcov_unsigned_t)0x34303170 ) /* 401p */
然而,这个文件是在编译 GCC 时自动产生的;文件的内容,是有 gcov_iov 程序产生,该程序由 gcov_iov.c 编译得来, 我们可以直接在 gcc 源代码下的 gcc 目录编译该文件,例如。
# cd /home/abo/gcc-4.1.2/gcc
# gcc -g -o gcov-iov gcov-iov.c
# ./gcov-iov 4.1.2 p
/* Generated automatically by the program `./gcov-iov'
from `4.1.2 (4 1) and p (p)'. */
#define GCOV_VERSION ((gcov_unsigned_t)0x34303170) /* 401p */
# ./gcov-iov 4.1 p
/* Generated automatically by the program `./gcov-iov'
from `4.1 (4 1) and p (p)'. */
#define GCOV_VERSION ((gcov_unsigned_t)0x34303170) /* 401p */
同样的道理, 0x34303170 即为字符 '4','0','1','p' 的 ASCII 码组成。 'p' 代表 prerelease ,请参考附录。
(3) time stamp
0x4e8eb3f0=1317975024 is the time stamp from GreenWich, it will be read and discarded.
可以使用 date 名验证这个时间,如下。不过,数值上好像有些差异,至于原因,本文不再研究。
# date -d @1317975024 +"%F %T %z"
2011-10-07 16:10:24 +0800
# date --date='2011-04-13 11:13:07' +%s
1302664387
(4) FUNCTION tag
0x01000000 is a FUNCTION tag, defined as follows.
/* The record tags. Values [1..3f] are for tags which may be in either
file. Values [41..9f] for those in the note file and [a1..ff] for
the data file. The tag value zero is used as an explicit end of
file marker -- it is not required to be present. */
# define GCOV_TAG_FUNCTION ((gcov_unsigned_t) 0x01000000 )
# define GCOV_TAG_FUNCTION_LENGTH ( 2 )
# define GCOV_TAG_BLOCKS ((gcov_unsigned_t) 0x01410000 )
# define GCOV_TAG_BLOCKS_LENGTH(NUM) (NUM)
# define GCOV_TAG_BLOCKS_NUM(LENGTH) (LENGTH)
# define GCOV_TAG_ARCS ((gcov_unsigned_t) 0x01430000 )
# define GCOV_TAG_ARCS_LENGTH(NUM) ( 1 + (NUM) * 2 )