Content
0. 序
1. 如何编译
1.1 未加入覆盖率测试选项
1.2 加入覆盖率测试选项
1.3 分析
2. 未加入覆盖率测试选项的汇编代码分析
3. 加入覆盖率测试选项的汇编代码分析
3.1 计数桩代码分析
3.2 构造函数桩代码分析
3.3 数据结构分析
3.4 构造函数桩代码小结
4. 说明
5. 小结
0. 序
1. 如何编译
1.1 未加入覆盖率测试选项
# cpp test.c -o test.i //预处理:生成test.i文件,或者"cpp test.c > test.i"
或者
# gcc -E test.c -o test.i
# gcc -S test.i //编译:生成test.s文件(未加入覆盖率测试选项)
# as -o test.o test.s //汇编:生成test.o文件,或者"gcc -c test.s -o test.o"
# gcc -o test test.o //链接:生成可执行文件test
查看test.o文件中的符号
# nm test.o
00000000 T main
U puts
1.2 加入覆盖率测试选项
# cpp test.c -o test.i //预处理:生成test.i文件
# gcc -fprofile-arcs -ftest-coverage -S test.i //编译:生成test.s文件(加入覆盖率测试选项)
# as -o test.o test.s //汇编:生成test.o文件
# gcc -o test test.o //链接:生成可执行文件test
查看test.o文件中的符号
# nm test.o
000000eb t _GLOBAL__I_0_main
U __gcov_init
U __gcov_merge_add
00000000 T main
U puts
1.3 分析
从上面nm命令的结果可以看出,加入覆盖率测试选项后的test.o文件,多了3个符号,如上。其中,_GLOBAL__I_0_main就是插入的部分桩代码。section2和section3将对比分析插桩前后汇编代码的变化,section3重点分析插入的桩代码。
2. 未加入覆盖率测试选项的汇编代码分析
采用"# gcc -S test.i"命令得到的test.s汇编代码如下。#后面的注释为笔者所加。
注:$9表示常量9,即立即数(Immediate Operand)。-8(%ebp)即为total,-12(%ebp)即是循环变量i。
3. 加入覆盖率测试选项的汇编代码分析
采用"# gcc -fprofile-arcs -ftest-coverage -S test.i"命令得到的test.s汇编代码如下。前面的蓝色部分及后面的.LC2, .LC3, .LPBX0, _GLOBAL__I_0_main等均为插入的桩代码。#后面的注释为笔者所加。