本博客(http://blog.csdn.net/livelylittlefish)贴出作者(阿波)相关研究、学习内容所做的笔记,欢迎广大朋友指正!
Content
0. 序
1.编译gcov/gcov-dump
2. 额外的话
3. gcov-dump程序的一个bug
3.1 bug描述
3.2 bug分析与修复
3.3 正确的输出
3.4 gcov-dump的打印开关
3.5一个问题:上面红色的0是什么?谁打印出来的?
4. 总结
0.序
某些版本的Gcc在默认情况下编译,可能不会产生gcov-dump程序,或者不会安装到/usr/bin。但gcov-dump程序在做覆盖率测试时dump相关文件(.gcda/.gcno)内容时非常必要和好用。
Gcc的编译耗时又繁琐,如果某些配置不正确,会导致编译过程中各种莫名其妙的错误。因此,本文主要讲述在不重新编译整个Gcc项目的情况下,如何获得gcov-dump程序。
本文在Linux平台上实验,以gcc-4.1.2为例,且gcc源代码在/usr/src/gcc-4.1.2目录。以下若不做特别说明,.表示gcc源代码目录,即/usr/src/gcc-4.1.2。
1.编译gcov/gcov-dump
Gcov-dump.c位于./gcc目录下,因此,可以通过./gcc的makefile文件编译生成gcov-dump。gcc目录下configure程序即可生成该makefile。
makefile文件中的gcov-dump如下,由./gcc/build下的Makefile文件中抽取出来。
exeext =
CPPLIB = ../libcpp/libcpp.a
LIBIBERTY = ../libiberty/libiberty.a
# Internationalization library.
LIBINTL =
LIBINTL_DEP =
# Character encoding conversion library.
LIBICONV =
LIBICONV_DEP =
LIBS = $(CPPLIB) $(LIBINTL) $(LIBICONV) $(LIBIBERTY)
gcov.o: gcov.c gcov-io.c $(GCOV_IO_H) intl.h $(SYSTEM_H) coretypes.h $(TM_H) /
$(CONFIG_H) version.h
gcov-dump.o: gcov-dump.c gcov-io.c $(GCOV_IO_H) $(SYSTEM_H) coretypes.h /
$(TM_H) $(CONFIG_H)
GCOV_OBJS = gcov.o intl.o version.o errors.o
gcov$(exeext): $(GCOV_OBJS) $(LIBDEPS)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) $(GCOV_OBJS) $(LIBS) -o $@
GCOV_DUMP_OBJS = gcov-dump.o version.o errors.o
gcov-dump$(exeext): $(GCOV_DUMP_OBJS) $(LIBDEPS)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) $(GCOV_DUMP_OBJS) $(LIBS) -o $@
至于其他的定义,非本文重点,不予解释。
# cd /usr/src/gcc-4.1.2/gcc/build
# make clean
# make gcov-dump
...
make: *** No rule to make target `../build-i686-pc-linux-gnu/libiberty/libiberty.a', needed by `build/genmodes'. Stop.
# make gcov
...
make: *** No rule to make target `../build-i686-pc-linux-gnu/libiberty/libiberty.a', needed by `build/genmodes'. Stop.
程序提示在../build-i686-pc-linux-gnu/libiberty目录下没有找到genmodes所需的静态库libiberty.a。
从makefile文件中也了解到,gcov/gcov-dump实际所需的静态库是libcpp.a和libiberty.a。实际上,只需在gcc目录下的makefile文件中指定好这两个静态库的路径(绝对路径和相对路径均可)即可解决问题。例如:/usr/bin/libiberty.a。
2.额外的话
不得不指出的一点:事实上,对libcpp.a的依赖几乎为0,且对libiberty.a的依赖也仅限于以下函数。
FILE *fopen_unlocked (const char *, const char *);
void unlock_std_streams (void);
这两个函数的声明在./include/libiberty.h中。
因此,了解这些之后,就可以将gcov/gcov-dump相关的文件抽取出来,单独成为一个独立的项目,来编译出gcov/gcov-dump,以方便对gcov/gcov-dump源代码和原理的学习、调试。
——将另文讨论。
3. gcov-dump程序的一个bug
3.1 bug描述
用上述生成的gcov-dump程序dump出某个.gcda文件的内容,如下。
# cd /home/zubo/gcc/test
#/usr/src/gcc-4.1.2/gcc/build/gcov-dump test.gcda
test.gcda:data:magic `gcda':version `401p'
test.gcda:stamp 1427241144
test.gcda: 01000000: 2:FUNCTION ident=3, checksum=0xeb65a768
test.gcda: 01a10000: 10:COUNTERS arcs 5 counts
test.gcda: 0 10 0 1 0 1
test.gcda: a1000000: 9:OBJECT_SUMMARY checksum=0x00000000
test.gcda: counts=5, runs=1, sum_all=12, run_max=10, sum_max=10
test.gcda: counts