我们会常用的
ELF
调试工具总结如下。因为这些工具
x86
版本和
arm
版本使用基本没有区别,这里也没有区别。读者使用时,请根据使用对象的类型(使用)
FILE
命令查看)自行区分。
51Testing软件测试网@/tY@id?sk
AR\%}WS1z/\4P0
静态库文件用于建立、修改和提取。静态库文件包含多个可重定位的目标文件,其结构保证了原始目标文件的恢复。
51Testing软件测试网D T;U;e{v4f$ gcc –c file1.c file2.c
51Testing软件测试网2K9z.xj6Q
$ ar rcs libxx.a file1.o file2.o0dB
U,n8|!_ E:I'^B\0
我们先在这里使用
gcc
编译得到
file1.o file2.o
然后使用两个目标文件
ar
命令生成静态库
libxx.a
。6WV
a1A"W1i6u"M l/ei0
当您想查看静态库中包含的目标文件时,可以使用选项
-x
解开静态库文件:c#Z(_(Dp'w6u^a0$ ar x libxx.a
51Testing软件测试网"to6GX;V7FA9|
2\&H|!{%M(aL0
NMD%h T3|!op Jj?
列出目标文件符号表中定义的符号。在运行过程中发生的常见链接或
unresolved symbol
类型的错误可以用
NM
辅助调试。例如使用
NM
结合
GREP
查看变量或函数是定义还是引用:}U:X3Nf-Llvr,g,`0$ nm [xx.o, or yy.a, or zz.so] | grep [your symbol]
51Testing软件测试网oI$l'Ar`l
对于
C
选项可用于程序
-C
所谓
demangle
——
C
编译器一般会将变量名或函数名进行修饰
(mangle)
,加上类信息、参数信息等,成为难以辨认的符号,而
-C
选项的
demangle
它可以恢复为更正常的符号。例如,以下是非常简单的
C
程序:
51Testing软件测试网3~0_j.YLn#include 8p(G4vA^@8y&W0
lg?BY-X8Y;P;G0
int main()
51Testing软件测试网P5F,K}0bJ"@
{
51Testing软件测试网hr;Ids.W3m
std::cout<
51Testing软件测试网j9\6RK*I
XBLq
}RNY&RO[y0
编译之后用
nm
来查看:
51Testing软件测试网y8Et#q{E[pk$ g -c hello.cpp
51Testing软件测试网~pmWtw&m
$ nm hello.oy~'EW'sW0
00000094 t _GLOBAL__I_mainxtM-Z)FA0
0000003e t _Z41__static_initialization_and_destruction_0iii"]1ou'^sn0
U _ZNSolsEPFRSoS_E3jY9`$F"j0EwU"g;l0
U _ZNSt8ios_base4InitC1Ev
51Testing软件测试网!G-b @{G2c2u
U _ZNSt8ios_base4InitD1Evw\:R!P$_%zXw-_0
U _ZSt4cout
51Testing软件测试网eX"z;\\p4_e
U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
51Testing软件测试网4q@H/I.EQ e
00000000 b _ZSt8__ioinitL\y3LV:R$]r0
U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKcG#EFDD _Ja?0
U __cxa_atexit1@&\8a{&x!jN/n$j/j0
U __dso_handle4EoH)z?,L I0
U __gxx_personality_v0
51Testing软件测试网C8]:IH5J
0000007c
t __tcf_0
51Testing软件测试网HI8T v\7Sn6Bix
00000000 T main
51Testing软件测试网#X!c`&OR
T?l
这时这些
mangle
之后的
C
如果使用符号,很难识别符号
nm –C
进行
demangle
就好多了:4Pnk.}5?!va,C0$ nm -C hello.o|#cYU$RR2|g1uG/b0
00000094 t _GLOBAL__I_main
51Testing软件测试网6]nd,X/S{bs#pQX
O
0000003e t __static_initialization_and_destruction_0(int, int)EQ?az^Z0
U
std::basic_ostream
>::operator<
std::char_traits >& (*)(std::basic_ostream
std::char_traits >&))
51Testing软件测试网$e_A:w"bv.`&n9Z
U std::ios_base::Init::Init[in-charge]()
51Testing软件测试网z ic)n5}$Z\
U std::ios_base::Init::~Init [in-charge]()"s Qx8~K)P-p!U0
U std::coute
L9~!Z#w9a0
U
std::basic_ostream >&
std::endl
>(std::basic_ostream >&)dq{]1kf;Ge0
00000000 b std::__ioinit~ t,C{_0
U
std::basic_ostream >&
std::operator<< <:char_traits>
>(std::basic_ostream
>&, char const*)1KFO`7ag0
U __cxa_atexit
51Testing软件测试网Ju$Ch:v
U __dso_handle
51Testing软件测试网I)LfO%g,Q|f2p]
U __gxx_personality_v0
51Testing软件测试网` I)e b o-Bj~
0000007c
t __tcf_0?0`HFP0
00000000 T main)Ep"?XV|Ky0
-C
还提供了其他二进制调试工具中的选项
C
读者可以者可以多加注意,毕竟
demangle
之后符号的可读性要强得多。{m;\#i-D7Z*k*|Nq%X0
51Testing软件测试网V1E r1l
OBJDUMP
S6t#V-T4m;BAl0
objdump
它是所有二进制工具的母亲,可以显示目标文件中的所有信息。通常,我们用它来汇编
.text
节中二进制指令。[UHq4r3m0
比如上面的
hello.o
结果如下:V WwH0_V0# objdump -d hello.o
51Testing软件测试网[*j0X%Q(dm}
s-j_[;q#`.]aqj%[I0
hello.o:
file format elf32-i386
51Testing软件测试网)N;gIjlCc ^
8NJPx8OWn'td0
Disassembly of section .text:
51Testing软件测试网4m X d3s6eI,[
51Testing软件测试网'\5}9b@j!jn
00000000 :&R5G#s0k_J;P0
0:
55
push
%ebp
51Testing软件测试网6~!c X}Z0i/L
1:
89 e5
mov
%esp,%ebp%[],dh2\*n6?'D0
3:
83 ec 08
sub
$0x8,%esp
51Testing软件测试网%{dZ2I,Mg
6:
83 e4 f0
and
$0xfffffff0,%esp
51Testing软件测试网;_1L,Q^GH?P8L)Y6F
9:
b8 00 00 00 00
mov
$0x0,%eaxZ%l`6s#}(Z:JI0
e:
29 c4
sub
%eax,%esp
51Testing软件测试网2\Jj.s[,lNL7N!v
10:
83 ec 08
sub
$0x8,%esp(z ~]$u:PK0
13:
68 00 00 00 00
push
$0x0'XSuf*p9nt{0
18:
83 ec 0c
sub
$0xc,%esp
51Testing软件测试网z3\m)@p$fS^
1b:
68 00 00 00 00
push
$0x0
51Testing软件测试网5f4D_W$ep2S)E5s
20:
68 00 00 00 00
push
$0x0
51Testing软件测试网:hl,R6x;}
25:
e8 fc ff ff ff
call
26 H"Fc&Z{0
2a:
83 c4 14
add
$0x14,%esp
51Testing软件测试网H.NQ+V#|2@clU
2d:
50
push
%eax
51Testing软件测试网]\ Z0a%~7\
2e:
e8 fc ff ff ff
call
2f O/C7Ayi&F4k0
33:
83 c4 10
add
$0x10,%esp
51Testing软件测试网[? kfI
36:
b8 00 00 00 00
mov
$0x0,%eax$c;maPSg4Ah0
3b:
c9
leave
51Testing软件测试网nK0bv@^|
3c:
c3
retx YJa(x8X0
3d:
90
nop
51Testing软件测试网'pPV0D6fR0H|^
...3DA.ZZ/N+{
L0
注意这里用的目标文件
hello.o
和工具
objdump
都是
x86
版本的,生成的反汇编代码是
Unix
系统上传统的
AT&T
汇编,而不是多数人更熟悉的
Intel
汇编。/x.F@b"[&|_/E&hg.?0
如果你用
ARM
格式的
hello.o
,及针对
ARM
的交叉调试工具
arm-linux-objdump
,得到的则是
ARM
汇编:S4bD{+c3M0$ arm-linux-objdump -d hello.o
51Testing软件测试网`
E9}+Ly&C
7OGJ-zM0
hello.o:
file format elf32-littlearm/L*t,r&ud7T0
51Testing软件测试网a,tW2~ E5J%wc
B#e
Disassembly of section .text:eo&a
p^h AS^#sD0
…
51Testing软件测试网*` }YiS7m] i"i0mV
00000180 :
51Testing软件测试网r*?N`#[v7X#J'T
180:
e1a0c00d
mov
ip, sp0{)q@YV E:XU0
184:
e92dd800
stmdb
sp!, {fp, ip, lr, pc},o#WTVO~0
188:
e24cb004
sub
fp, ip, #4
; 0x4
51Testing软件测试网0B@v6ndHAe
18c:
e59f0014
ldr
r0, [pc, #20]
; 1a8 <.text>
51Testing软件测试网u^$V2C]RK3p^
190:
e59f1014
ldr
r1, [pc, #20]
; 1ac <.text>n2o3pZZM'C0
194:
ebfffffe
bl
194 S g6u)iF*G0
198:
e59f1010
ldr
r1, [pc, #16]
; 1b0 <.text>
51Testing软件测试网,AR-nU)Cl9ipaCH
19c:
ebfffffe
bl
19c
51Testing软件测试网J^KO6m)}H0a
1a0:
e3a00000
mov
r0, #0
; 0x01p#WtF0dc9J,a0
1a4:
e89da800
ldmia
sp, {fp, sp, pc}
51Testing软件测试网lPJ~;X7^
...
51Testing软件测试网k2F)L*Kx:W,OQ\
在主机的模拟环境中进行调试时,你可以用
AT&T
汇编来作为参考,但涉及到与
CPU
体系结构有关的代码时,最好还是反汇编得到
ARM
汇编格式的代码,这样更为准确一些。
51Testing软件测试网Wdkk`h9|+}4t