移植交叉工具包的时候,发现这是很多工具的集合包;以及写makefile的时候,也需要了解下这些工具的作用及用法,这里总结记录一下常见的工具及相关用法。
- g++
C++编译器,用于编译C++源代码文件,这个很常见,不多介绍 - gcc
C编译器,用于编译C源文件 - gdb
调试器,命令行调试工具,用于调试C/C++程序 - ar
用于创建、修改和提取归档文件的工具(指打包静态库)。归档文件(一般指静态库)通常包含多个目标文件,可以用ar将其打包成一个文件,如:
bash
ar rcs lib.a file1.o file2.o
- ld ldd
ld链接器,用于将目标文件和库文件链接在一起,生成可执行文件或者库文件;
如:
bash
ld -o a.out file1.o file2.o
ldd显示可执行文件或者库文件依赖的动态库有哪些,防止因为动态库拷贝少了导致的运行问题,但是这个不检查动态库版本之类的信息,需要自己小心。
- readelf elfedit
readelf读elf信息,包括elf文件头、程序头、符号表、动态库链接信息等;elfedit用来修改elf header信息,包括header显示的版本、编译平台、执行平台等
如:
- execstack
用于设置或者清除elf可执行文件的栈执行权限,这个在现代操作系统上一般没有,因为现代操作系统上禁用栈执行权限。禁用栈执行权限可以避免栈溢出攻击;现代操作系统的一般有栈保护机制,如栈金丝雀 - c++filt
用于解码符号名;编译器会对函数名和变量名进行修饰,c++filt可以将修饰后的变量或者函数名还原成原本的名字;这个一般在gdb调试、或查看符号表的时候可以用。
- as
汇编器,将汇编语言编译成机器目标语言,编译过程 预处理-编译-汇编-链接过程中的汇编起始就是as实现的,单独使用as:
bash
as -o output.o output.s
- addr2line
将程序地址转换成文件名和行号,比如linux上程序core dump掉以后,可以设置打印寄存器,pc寄存器一般就是当前执行的位置,根据这个地址,使用addr2line可以获取到文件和行号,当然这要求程序的符号表还存在,没有被strip掉
bash
addr2line -e a.out 0x4005d6
- nm strip strings
nm用于显示目标文件、可执行文件或者库文件中的符号表;strip用于从目标文件、可执行文件或者库文件中去掉符号表、调试信息等;strings用于从二进制文件中提取字符串,一般是程序文本段的const字符、符号表等
- randlib
用于生成静态库的索引表,便于连接器快速找到库中的符号,按理说是可以加快使用静态库的时候的程序执行速度的。
bash
ranlib lib.a
- gcov
代码覆盖率分析工具,编译的时候需要添加选项-fprofile-arcs -ftest-coverage -lgcov
,这样,在执行完程序以后,会生成代码覆盖率的文件,使用gcov对代码覆盖率生成报告文件 - gprof
性能分析工具,编译的时候需要添加-pg
选项,执行以后会生成.out文件,使用gprof对分析文件.out和可执行文件一起分析得到一个函数耗时和执行次数的统计预报文件 - cpp
C文件的预处理器,展开#include #define等预处理信息
bash
cpp main.c -o main.i
-
objcopy objdump
objcopy用于复制和转换目标文件的格式,用来提取段信息、修改头信息等;objdump用于显示目标文件的详细信息,包括反汇编代码、符号表、节头表等。
-
prelink
预链接共享库,减少程序执行时间。将执行时的符号解析提前到链接阶段,以减少程序运行时的动态链接开销。
bash
prelink a.out