Linux 体系中有许多的东西可用于 ELF 文件的二进制调试,常用的东西在 GNU binutils 包中可以找到,留意你或许需求这些东西的 x86 版别和 arm 版别,以便在调试环境中可以调试 x86 ELF 文件和 arm ELF 文件——与穿插编译器 arm-linux-gcc 相似,咱们需求所谓的“穿插调试东西”,你可以经过互联网下载他人现已编译好的 crosstool ,或许自己从头编译( configure 时指 ——target=arm-linux )。
GNU binutils 包在 GNU 的官方网站供给下载: http://www.gnu.org/software/binutils/ ,特别的,更多跟 arm 相关的信息和东西可以看看 gnu arm 网站: http://www.gnuarm.org/ .咱们将常用的 ELF 调试东西概括介绍如下。因为这些东西的 x86 版别和 arm 版别运用起来根本没有差异,这儿也不作区别。读者在运用的时分请依据运用方针的类型(用 FILE 指令检查)自行区别。? AR用来树立、修正、提取静态库文件。静态库文件包括多个可重定位方针文件,其结构确保了可以康复原始方针文件内容。比方:$ gcc –c file1.c file2.c $ ar rcs libxx.a file1.o file2.o这儿咱们先用 gcc 编译得到 file1.o file2.o 两个方针文件,然后用 ar 指令生成静态库 libxx.a .当你期望检查静态库中包括了哪些方针文件时,可以用选项 -x 解开静态库文件:$ ar x libxx.a
? NM列出方针文件的符号表中界说的符号。常见的链接或许运行时产生的 unresolved symbol 类型的过错可以用 NM 来辅佐调试。比方用 NM 结合 GREP 来检查变量或函数是否被界说或引证:$ nm [xx.o, or yy.a, or zz.so] | grep [your symbol]关于 C++ 程序,可以运用选项 -C 来进行所谓的 demangle —— C++ 编译器一般会将变量名或函数名进行润饰 (mangle) ,加上类信息、参数信息等,变成比较难以辨认的符号,而 -C 选项的 demangle 则可将其康复为比较正常的符号。比方下面很简单的 C++ 程序:#include
int main()
{ std::coutHello World!
U std::basic_ostream
U std::ios_base::Init::Init[in-charge]()
U std::ios_base::Init::~Init [in-charge]()
U std::cout U std::basic_ostream
00000000 b std::__ioinit U std::basic_ostream
U __cxa_atexit U __dso_handle U __gxx_personality_v0 0000007c t __tcf_0 00000000 T main -C 选项在其他一些二进制调试东西中也有供给,运用 C++ 开发的读者可以多加留意,究竟 demangle 之后的符号可读性要强许多。
? OBJDUMP objdump 是一切二进制东西之母,可以显现一个方针文件中一切的信息,一般咱们用它来反汇编 .text 节中的二进制指令。
比方对上面的 hello.o 反汇编的成果如下:# objdump -d hello.o
hello.o: file format elf32-i386
Disassembly of section .text:
00000000