移植交叉工具包的時候,發現這是很多工具的集合包;以及寫makefile的時候,也需要了解下這些工具的作用及用法,這里總結記錄一下常見的工具及相關用法。
- g++
C++編譯器,用于編譯C++源代碼文件,這個很常見,不多介紹 - gcc
C編譯器,用于編譯C源文件 - gdb
調試器,命令行調試工具,用于調試C/C++程序 - ar
用于創建、修改和提取歸檔文件的工具(指打包靜態庫)。歸檔文件(一般指靜態庫)通常包含多個目標文件,可以用ar將其打包成一個文件,如:
ar rcs lib.a file1.o file2.o
- ld ldd
ld鏈接器,用于將目標文件和庫文件鏈接在一起,生成可執行文件或者庫文件;
如:
ld -o a.out file1.o file2.o
ldd顯示可執行文件或者庫文件依賴的動態庫有哪些,防止因為動態庫拷貝少了導致的運行問題,但是這個不檢查動態庫版本之類的信息,需要自己小心。
6. readelf elfedit
readelf讀elf信息,包括elf文件頭、程序頭、符號表、動態庫鏈接信息等;elfedit用來修改elf header信息,包括header顯示的版本、編譯平臺、執行平臺等
如:
- execstack
用于設置或者清除elf可執行文件的棧執行權限,這個在現代操作系統上一般沒有,因為現代操作系統上禁用棧執行權限。禁用棧執行權限可以避免棧溢出攻擊;現代操作系統的一般有棧保護機制,如棧金絲雀 - c++filt
用于解碼符號名;編譯器會對函數名和變量名進行修飾,c++filt可以將修飾后的變量或者函數名還原成原本的名字;這個一般在gdb調試、或查看符號表的時候可以用。
- as
匯編器,將匯編語言編譯成機器目標語言,編譯過程 預處理-編譯-匯編-鏈接過程中的匯編起始就是as實現的,單獨使用as:
as -o output.o output.s
- addr2line
將程序地址轉換成文件名和行號,比如linux上程序core dump掉以后,可以設置打印寄存器,pc寄存器一般就是當前執行的位置,根據這個地址,使用addr2line可以獲取到文件和行號,當然這要求程序的符號表還存在,沒有被strip掉
addr2line -e a.out 0x4005d6
- nm strip strings
nm用于顯示目標文件、可執行文件或者庫文件中的符號表;strip用于從目標文件、可執行文件或者庫文件中去掉符號表、調試信息等;strings用于從二進制文件中提取字符串,一般是程序文本段的const字符、符號表等
- randlib
用于生成靜態庫的索引表,便于連接器快速找到庫中的符號,按理說是可以加快使用靜態庫的時候的程序執行速度的。
ranlib lib.a
- gcov
代碼覆蓋率分析工具,編譯的時候需要添加選項-fprofile-arcs -ftest-coverage -lgcov
,這樣,在執行完程序以后,會生成代碼覆蓋率的文件,使用gcov對代碼覆蓋率生成報告文件 - gprof
性能分析工具,編譯的時候需要添加-pg
選項,執行以后會生成.out文件,使用gprof對分析文件.out和可執行文件一起分析得到一個函數耗時和執行次數的統計預報文件 - cpp
C文件的預處理器,展開#include #define等預處理信息
cpp main.c -o main.i
-
objcopy objdump
objcopy用于復制和轉換目標文件的格式,用來提取段信息、修改頭信息等;objdump用于顯示目標文件的詳細信息,包括反匯編代碼、符號表、節頭表等。 -
prelink
預鏈接共享庫,減少程序執行時間。將執行時的符號解析提前到鏈接階段,以減少程序運行時的動態鏈接開銷。
prelink a.out