加入收藏 | 设为首页 | 会员中心 | 我要投稿 南通站长网 (https://www.0513zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Linux平台代码覆盖率测试-编译过程自动化及对链接的介绍

发布时间:2021-11-25 21:47:23 所属栏目:教程 来源:互联网
导读:Content 0. 序 1. 生成各个文件的步骤 1.1 未加入覆盖率测试选项 1.1.1 编译步骤 1.1.2 目标文件的符号表 1.2 加入覆盖率测试选项 1.2.1 编译步骤 1.2.2 目标文件的符号表 1.3 gcc verbose选项 2. 编译自动化 2.1 使用collect2的makefile 2.2 不使用collect2

Content
 
0. 序
 
1. 生成各个文件的步骤
 
1.1 未加入覆盖率测试选项
 
1.1.1 编译步骤
 
1.1.2 目标文件的符号表
 
1.2 加入覆盖率测试选项
 
1.2.1 编译步骤
 
1.2.2 目标文件的符号表
 
1.3 gcc verbose选项
 
2. 编译自动化
 
2.1 使用collect2的makefile
 
2.2 不使用collect2的makefile
 
3. 关于链接的讨论
 
3.1 链接顺序讨论
 
3.2 错误链接顺序的例子
 
4. 额外的话
 
5. 小结
 
 
 
 
 
0. 序
 
 
 
"Linux平台代码覆盖率测试-GCC插桩前后汇编代码对比分析"一文中的编译过程能否自动化?能否使用makefile的方式进行?其链接过程使用ld或者collect2如何?
 
 
 
——这将是本文讨论的重点。本文gcc版本为gcc-4.1.2。
 
 
 
1. 生成各个文件的步骤
 
 
 
1.1 未加入覆盖率测试选项
 
 
 
1.1.1 编译步骤
 
 
 
(1) 预处理:生成test.i文件
 
 
 
# cpp test.c -o test.i    //或者
 
# cpp test.c > test.i     //或者
 
# gcc -E test.c -o test.i
 
 
 
(2) 编译:生成test.s文件
 
 
 
# gcc -S test.i
 
 
 
(3) 汇编:生成test.o文件
 
 
 
# as -o test.o test.s     //或者
 
# gcc -c test.s -o test.o
 
 
 
(4) 链接:生成可执行文件test
 
 
 
# gcc -o test test.o
 
 
 
或者,
 
# /usr/libexec/gcc/i386-RedHat-linux/4.1.2/collect2 --eh-frame-hdr --build-id -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crt1.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2/crtbegin.o -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2/../../.. -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i386-redhat-linux/4.1.2/crtend.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crtn.o test.o -o test
 
因/usr/lib/gcc/i386-redhat-linux/4.1.2/../../..就是/usr/lib,因此,也可以简写为。
 
/usr/libexec/gcc/i386-redhat-linux/4.1.2/collect2 --eh-frame-hdr --build-id -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2/crtbegin.o -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i386-redhat-linux/4.1.2/crtend.o /usr/lib/crtn.o test.o -o test
 
1.1.2 目标文件的符号表
 
 
 
可通过如下命令查看test.o中的符号表。//后是笔者加入的注释。
 
# objdump -t test.o
 
 
 
test.o:     file format elf32-i386
 
 
 
SYMBOL TABLE:
 
00000000 l    df *ABS*  00000000 test.c
 
00000000 l    d  .text  00000000 .text
 
00000000 l    d  .data  00000000 .data
 
00000000 l    d  .bss   00000000 .bss
 
00000000 l    d  .rodata        00000000 .rodata
 
00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack
 
00000000 l    d  .comment       00000000 .comment
 
00000000 g     F .text  0000005f main
 
00000000         *UND*  00000000 puts    //就是undefined,故需要连接其他的目标文件
 
 
 
# nm test.o
 
00000000 T main    //T即为text symbol,大写表示global
 
         U puts    //就是undefined,故需要连接其他的目标文件
 
 
 
1.2 加入覆盖率测试选项
 
 
 
1.2.1 编译步骤
 
 
 
步骤同上,只是在编译生成test.s文件时加上"-fprofile-arcs -ftest-coverage"覆盖率测试选项即可。
 
 
 
另外,使用collect2的链接步骤稍有不同,需要链接gcov静态库(libgcov.a)。如下。
 
# /usr/libexec/gcc/i386-redhat-linux/4.1.2/collect2 --eh-frame-hdr --build-id -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crt1.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2/crtbegin.o test.o -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2/../../.. -lgcov -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i386-redhat-linux/4.1.2/crtend.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crtn.o -o test
 
或者简写为。
 
/usr/libexec/gcc/i386-redhat-linux/4.1.2/collect2 --eh-frame-hdr --build-id -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2/crtbegin.o test.o -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib -lgcov -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i386-redhat-linux/4.1.2/crtend.o /usr/lib/crtn.o -o test
 
当然,命令亦会完成链接并生成可执行文件。
 
# gcc -o test test.o -lgcov
 
 
 
libgcov.a位于/usr/lib/gcc/i386-redhat-linux/4.1.2目录。
 
 
 
1.2.2 目标文件的符号表
 
 
 
看看加入覆盖率测试选项后的目标文件test.o中的符号表。
 
# objdump -t test.o
 
 
 
test.o:     file format elf32-i386
 
 
 
SYMBOL TABLE:
 
00000000 l    df *ABS*  00000000 test.c
 
00000000 l    d  .text  00000000 .text
 
00000000 l    d  .data  00000000 .data
 
00000000 l    d  .bss   00000000 .bss
 
00000000 l    d  .rodata        00000000 .rodata
 
000000eb l     F .text  00000014 _GLOBAL__I_0_main
 
00000000 l    d  .ctors 00000000 .ctors
 
00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack
 
00000000 l    d  .comment       00000000 .comment
 
00000000 g     F .text  000000eb main
 
00000000         *UND*  00000000 puts              //就是undefined,故需要连接其他的目标文件,下同
 
00000000         *UND*  00000000 __gcov_merge_add
 
00000000         *UND*  00000000 __gcov_init
 
 
 
# nm test.o
 
000000eb t _GLOBAL__I_0_main    //t即为text symbol,小写表示local
 
         U __gcov_init          //就是undefined,故需要连接其他的目标文件,下同
 
         U __gcov_merge_add
 
00000000 T main
 
         U puts
 
1.3 gcc verbose选项
 
 
 
这是如何知道的呢?——gcc命令-v选项即可。
 
# gcc -v test.c [-o test]
 
# gcc -fprofile-arcs -ftest-coverage -v test.c [-o test]
 
[]表示出现0次或1次。
 
-v,即verbose选项,以下是中的解释,原文更贴切,此处不翻译。
 
The '-v' option can also be used to display detailed information about the exact sequence of commands used to compile and link a program.

(编辑:南通站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读