java判断字符串st6_是否包含st5_第 18 章 在机器指令级调试

第 18 章 在机器指令级调试

本章介绍如何在机器指令级使用事件管理和进程控制命令、如何显示指定地址处的内存内容以及如何显示源代码行及其相应的机器指令。next 命令、step 命令、stop 命令和 trace 命令分别支持相应的机器指令级变体:nexti 命令、stepi 命令、stopi 命令和 tracei 命令。可使用 regs 命令输出多个机器寄存器的内容,也可使用 print 命令输出各个寄存器的内容。

本章由以下部分组成:

检查内存的内容

可使用地址以及 examine 或 x 命令检查内存位置的内容及打印每个地址处的汇编语言指令。使用从 adb(1)(汇编语言调试器)派生的命令,可以查询:

address,使用 =(等号)字符,或

某地址处存储的内容,使用 /(斜线)字符。

可使用 dis 命令和 listi 命令打印汇编命令。(请参见dis 命令用法和listi 命令用法。)

examine 或 x 命令用法

可使用 examine 命令或其别名 x 显示内存内容或地址。

下列语法用于以 format 格式显示始于 address 的 count 项内存内容。缺省的 address 为先前显示的最后一个地址后的下一个地址。缺省 count 为 1。缺省 format 与在先前的 examine 命令中使用的相同;如果这是给出的第一个命令,则为 X。

examine 命令的语法如下:

examine [address] [/ [count] [format]]

要以 format 格式显示 address1 到 address2(首末地址包含在内)的内存内容,请键入:

examine address1, address2 [/ [format]]

要以给定格式显示地址而不是地址内容,请键入:

examine address = [format]

要打印 examine 最后显示的地址后的下一个地址处存储的值,请键入:

examine +/ i

要打印表达式的值,请以地址形式输入表达式:

examine address=format

examine address=

地址

address 是求值结果为地址或可用作地址的任何表达式。可用 +(加号)替换 address,它以缺省格式显示下一个地址的内容。

例如,下面所示都是有效地址:

0xff99绝对地址

main函数地址

main+20与函数地址的偏移

&errno变量地址

str指向字符串的指针值变量

用于显示内存的符号地址的名称前有和号 (&)。函数名称前可以不带和号,例如,&main 等同于 main。寄存器名称前有美元符号 ($)。

格式

format 是 dbx 用来显示查询结果的地址显示格式。产生的输出取决于当前显示 format。要更改显示格式,应提供不同的 format 代码。

每个 dbx 会话开始时的缺省格式设置为 X,即以十六进制 32 位字显示地址或值。以下内存显示格式为合法格式。

i显示为汇编指令。

d显示为十进制 16 位(2 字节)。

D显示为十进制 32 位(4 字节)。

o显示为八进制 16 位(2 字节)。

O显示为八进制 32 位(4 字节)。

x显示为十六进制 16 位(2 字节)。

X显示为十六进制 32 位(4 字节)。(缺省格式)

b显示为八进制字节。

c显示为字符。

w显示为宽字符。

s显示为以空字节终止的字符串。

W显示为宽字符。

f显示为单精度浮点数。

F, g显示为双精度浮点数。

E显示为扩展精度浮点数。

ld, lD显示为十进制 32 位(4 字节)(与 D 相同)。

lo, lO显示为八进制 32 位(4 字节)(与 O 相同)。

lx, LX显示为十六进制 32 位(4 字节)(与 X 相同)。

Ld, LD显示为十进制 64 位(8 字节)。

Lo, LO显示为八进制 64 位(8 字节)。

Lx, LX显示为十六进制 64 位(8 字节)。

Count

count 为十进制重复计数。增量大小取决于内存显示格式。

使用地址的示例

下面的示例说明如何使用地址以及 count 和 format 选项来显示始于当前停止点的五个连续的反汇编指令。

对于基于 SPARC 的系统:

(dbx) stepi

stopped in main at 0x108bc

0x000108bc: main+0x000c: st %l0, [%fp - 0x14]

(dbx) x 0x108bc/5i

0x000108bc: main+0x000c: st %l0, [%fp - 0x14]

0x000108c0: main+0x0010: mov 0x1,%l0

0x000108c4: main+0x0014: or %l0,%g0, %o0

0x000108c8: main+0x0018: call 0x00020b90 [unresolved PLT 8: malloc]

0x000108cc: main+0x001c: nop

对于基于 x86 的系统:

(dbx) x &main/5i

0x08048988: main : pushl %ebp

0x08048989: main+0x0001: movl %esp,%ebp

0x0804898b: main+0x0003: subl $0x28,%esp

0x0804898e: main+0x0006: movl 0x8048ac0,%eax

0x08048993: main+0x000b: movl %eax,-8(%ebp)

dis 命令用法

dis 命令等同于以 i 作为缺省显示格式的 examine 命令。

dis 命令的语法如下。

dis [address] [address1, address2] [/count]

dis 命令:

不使用参数时显示以 + 开始的 10 个指令。

只使用 address 参数时,反汇编始于 address 的 10 个指令。

使用 address 参数和 count 时,反汇编始于 address 的 count 个指令。

使用 address1 和 address2 参数时,反汇编从 address1 到 address2 的指令。

只使用 count 时,显示始于 + 的 count 个指令。

listi 命令用法

要显示源代码行及其对应的汇编指令,请使用 listi 命令,它等同于命令 list -i。请参见打印源码列表中有关 list -i 的讨论内容。

对于基于 SPARC 的系统:

(dbx) listi 13, 14

13 i = atoi(argv[1]);

0x0001083c: main+0x0014: ld [%fp + 0x48], %l0

0x00010840: main+0x0018: add %l0, 0x4, %l0

0x00010844: main+0x001c: ld [%l0], %l0

0x00010848: main+0x0020: or %l0, %g0, %o0

0x0001084c: main+0x0024: call 0x000209e8 [unresolved PLT 7: atoi]

0x00010850: main+0x0028: nop

0x00010854: main+0x002c: or %o0, %g0, %l0

0x00010858: main+0x0030: st %l0, [%fp - 0x8]

14 j = foo(i);

0x0001085c: main+0x0034: ld [%fp - 0x8], %l0

0x00010860: main+0x0038: or %l0, %g0, %o0

0x00010864: main+0x003c: call foo

0x00010868: main+0x0040: nop

0x0001086c: main+0x0044: or %o0, %g0, %l0

0x00010870: main+0x0048: st %l0, [%fp - 0xc]

对于基于 x86 的系统:

(dbx) listi 13, 14

13 i = atoi(argv[1]);

0x080488fd: main+0x000d: movl 12(%ebp),%eax

0x08048900: main+0x0010: movl 4(%eax),%eax

0x08048903: main+0x0013: pushl %eax

0x08048904: main+0x0014: call atoi <0x8048798>

0x08048909: main+0x0019: addl $4,%esp

0x0804890c: main+0x001c: movl %eax,-8(%ebp)

14 j = foo(i);

0x0804890f: main+0x001f: movl -8(%ebp),%eax

0x08048912: main+0x0022: pushl %eax

0x08048913: main+0x0023: call foo <0x80488c0>

0x08048918: main+0x0028: addl $4,%esp

0x0804891b: main+0x002b: movl %eax,-12(%ebp)

在机器指令级单步执行和跟踪

机器指令级命令与其对应的源码级命令的功能相同,只不过它们在单步指令级而非源代码行级执行。

在机器指令级单步执行

要从一个机器指令单步执行到下一个机器指令,请使用 nexti 命令或 stepi 命令

nexti 命令和 stepi 命令与其对应的源代码级命令运行方式相同:nexti 命令步过 函数,stepi 命令步入由下一个指令调用的函数(停止于被调用函数中的第一个指令)。命令形式也相同。有关说明,请参见next 命令和step 命令。

nexti 命令和 stepi 命令的输出与其对应的源代码级命令的输出有两点不同:

输出中包含程序停止处的指令地址(而非源代码行号)。

缺省输出中包含反汇编指令,而非源代码行。

例如:

(dbx) func

hand::ungrasp

(dbx) nexti

ungrasp +0x18: call support

(dbx)

在机器指令级跟踪

机器级的跟踪技术与源代码级相同,只是要使用 tracei 命令。执行 tracei 命令时,dbx 只会在每次检查执行的地址或跟踪的变量值后,执行一个指令。tracei 命令会产生类似 stepi 的自动行为。程序一次前进一个指令来步入函数调用。

使用 tracei 命令时,它会使程序在执行每个指令后停止一会儿,这时,dbx 检查地址执行情况或跟踪的变量或表达式的值。使用 tracei 命令会显著降低执行速度。

有关跟踪及其事件规范和修饰符的更多信息,请参见跟踪执行和tracei 命令。

tracei 命令的常规语法如下:

tracei event-specification [modifier]

tracei 命令的常用形式为:

tracei step跟踪每一指令。

tracei next跟踪每一指令,但跳过调用。

tracei at address跟踪给定代码地址。

有关更多信息,请参见tracei 命令。

SPARC:

(dbx) tracei next -in main

(dbx) cont

0x00010814: main+0x0004: clr %l0

0x00010818: main+0x0008: st %l0, [%fp - 0x8]

0x0001081c: main+0x000c: call foo

0x00010820: main+0x0010: nop

0x00010824: main+0x0014: clr %l0

....

....

(dbx) (dbx) tracei step -in foo -if glob == 0

(dbx) cont

0x000107dc: foo+0x0004: mov 0x2, %l1

0x000107e0: foo+0x0008: sethi %hi(0x20800), %l0

0x000107e4: foo+0x000c: or %l0, 0x1f4, %l0 ! glob

0x000107e8: foo+0x0010: st %l1, [%l0]

0x000107ec: foo+0x0014: ba foo+0x1c

....

....

在机器指令级设置断点

要在机器指令级设置断点,应使用 stopi 命令。该命令接受任何 event specification,语法如下:

stopi event-specification [modifier]

stopi 命令的常用形式如下:

stopi [at address] [-if cond]

stopi in function [-if cond]

有关更多信息,请参见stopi 命令。

在地址处设置断点

要在特定地址设置断点,请键入:

(dbx) stopi at address

例如:

(dbx) nexti

stopped in hand::ungrasp at 0x12638

(dbx) stopi at &hand::ungrasp

(3) stopi at &hand::ungrasp

(dbx)

regs 命令用法

使用 regs 命令可以打印所有寄存器的值。

regs 命令的语法如下:

regs [-f][-F]

-f 表示包括浮点寄存器(单精度)。-F 表示包括浮点寄存器(双精度)。

有关更多信息,请参见regs 命令。

对于基于 SPARC 的系统:

dbx[13] regs -F

current thread: t@1

current frame: [1]

g0-g3 0x00000000 0x0011d000 0x00000000 0x00000000

g4-g7 0x00000000 0x00000000 0x00000000 0x00020c38

o0-o3 0x00000003 0x00000014 0xef7562b4 0xeffff420

o4-o7 0xef752f80 0x00000003 0xeffff3d8 0x000109b8

l0-l3 0x00000014 0x0000000a 0x0000000a 0x00010a88

l4-l7 0xeffff438 0x00000001 0x00000007 0xef74df54

i0-i3 0x00000001 0xeffff4a4 0xeffff4ac 0x00020c00

i4-i7 0x00000001 0x00000000 0xeffff440 0x000108c4

y 0x00000000

psr 0x40400086

pc 0x000109c0:main+0x4 mov 0x5, %l0

npc 0x000109c4:main+0x8 st %l0, [%fp - 0x8]

f0f1 +0.00000000000000e+00

f2f3 +0.00000000000000e+00

f4f5 +0.00000000000000e+00

f6f7 +0.00000000000000e+00

...

对于基于 x64 的系统:

(dbx) regs

current frame: [1]

r15 0x0000000000000000

r14 0x0000000000000000

r13 0x0000000000000000

r12 0x0000000000000000

r11 0x0000000000401b58

r10 0x0000000000000000

r9 0x0000000000401c30

r8 0x0000000000416cf0

rdi 0x0000000000416cf0

rsi 0x0000000000401c18

rbp 0xfffffd7fffdff820

rbx 0xfffffd7fff3fb190

rdx 0x0000000000401b50

rcx 0x0000000000401b54

rax 0x0000000000416cf0

trapno 0x0000000000000003

err 0x0000000000000000

rip 0x0000000000401709:main+0xf9 movl $0x0000000000000000,0xfffffffffffffffc(%rbp)

cs 0x000000000000004b

eflags 0x0000000000000206

rsp 0xfffffd7fffdff7b0

ss 0x0000000000000043

fs 0x00000000000001bb

gs 0x0000000000000000

es 0x0000000000000000

ds 0x0000000000000000

fsbase 0xfffffd7fff3a2000

gsbase 0xffffffff80000000

(dbx) regs -F

current frame: [1]

r15 0x0000000000000000

r14 0x0000000000000000

r13 0x0000000000000000

r12 0x0000000000000000

r11 0x0000000000401b58

r10 0x0000000000000000

r9 0x0000000000401c30

r8 0x0000000000416cf0

rdi 0x0000000000416cf0

rsi 0x0000000000401c18

rbp 0xfffffd7fffdff820

rbx 0xfffffd7fff3fb190

rdx 0x0000000000401b50

rcx 0x0000000000401b54

rax 0x0000000000416cf0

trapno 0x0000000000000003

err 0x0000000000000000

rip 0x0000000000401709:main+0xf9 movl $0x0000000000000000,0xfffffffffffffffc(%rbp)

cs 0x000000000000004b

eflags 0x0000000000000206

rsp 0xfffffd7fffdff7b0

ss 0x0000000000000043

fs 0x00000000000001bb

gs 0x0000000000000000

es 0x0000000000000000

ds 0x0000000000000000

fsbase 0xfffffd7fff3a2000

gsbase 0xffffffff80000000

st0 +0.00000000000000000000e+00

st1 +0.00000000000000000000e+00

st2 +0.00000000000000000000e+00

st3 +0.00000000000000000000e+00

st4 +0.00000000000000000000e+00

st5 +0.00000000000000000000e+00

st6 +0.00000000000000000000e+00

st7 +NaN

xmm0a-xmm0d 0x00000000 0xfff80000 0x00000000 0x00000000

xmm1a-xmm1d 0x00000000 0x00000000 0x00000000 0x00000000

xmm2a-xmm2d 0x00000000 0x00000000 0x00000000 0x00000000

xmm3a-xmm3d 0x00000000 0x00000000 0x00000000 0x00000000

xmm4a-xmm4d 0x00000000 0x00000000 0x00000000 0x00000000

xmm5a-xmm5d 0x00000000 0x00000000 0x00000000 0x00000000

xmm6a-xmm6d 0x00000000 0x00000000 0x00000000 0x00000000

xmm7a-xmm7d 0x00000000 0x00000000 0x00000000 0x00000000

xmm8a-xmm8d 0x00000000 0x00000000 0x00000000 0x00000000

xmm9a-xmm9d 0x00000000 0x00000000 0x00000000 0x00000000

xmm10a-xmm10d 0x00000000 0x00000000 0x00000000 0x00000000

xmm11a-xmm11d 0x00000000 0x00000000 0x00000000 0x00000000

xmm12a-xmm12d 0x00000000 0x00000000 0x00000000 0x00000000

xmm13a-xmm13d 0x00000000 0x00000000 0x00000000 0x00000000

xmm14a-xmm14d 0x00000000 0x00000000 0x00000000 0x00000000

xmm15a-xmm15d 0x00000000 0x00000000 0x00000000 0x00000000

fcw-fsw 0x137f 0x0000

fctw-fop 0x0000 0x0000

frip 0x0000000000000000

frdp 0x0000000000000000

mxcsr 0x00001f80

mxcr_mask 0x0000ffff

(dbx)

平台特定寄存器

以下各表列出了可在表达式中使用的 SPARC、x86 和 AMD64 体系结构的平台特定寄存器名称。

SPARC 寄存器信息

下面的寄存器信息适用于 [Please define the SPARCsans text entity] 体系结构。

寄存器说明

$g0 到 $g7全局寄存器

$o0 到 $o7“外部”寄存器

$l0 到 $l7“本地”寄存器

$i0 到 $i7“内部”寄存器

$fp帧指针,等同于寄存器 $i6

$sp栈指针,等同于寄存器 $o6

$yY 寄存器

$psr处理器状态寄存器

$wim窗口无效屏蔽寄存器

$tbr捕获基址寄存器

$pc程序计数器

$npc下一程序计数器

$f0 到 $f31FPU "f" 寄存器

$fsrFPU 状态寄存器

$fqFPU 队列

$f0f1 $f2f3 ... $f30f31 对浮点型寄存器视为 C 的“双精度”类型(通常 $fN 寄存器视为 C 的“浮点”类型)。这些对也可称为 $d0 ... $d30.

SPARC V9 和 V8+ 硬件上另外还提供了以下这些寄存器:

$g0g1 through $g6g7

$o0o1 through $o6o7

$xfsr $tstate $gsr

$f32f33 $f34f35 through $f62f63 ($d32 ... $$d62)

有关 SPARC 寄存器和寻址的更多信息,请参见《SPARC 体系结构参考手册》和《SPARC 汇编语言参考手册》。

x86 寄存器信息

下面的寄存器信息适用于 x86 体系结构。

寄存器说明

$gs交替数据段寄存器

$fs交替数据段寄存器

$es交替数据段寄存器

$ds数据段寄存器

$edi目标索引寄存器

$esi源索引寄存器

$ebp帧指针

$esp栈指针

$ebx通用寄存器

$edx通用寄存器

$ecx通用寄存器

$eax通用寄存器

$trapno异常向量数

$err异常错误代码

$eip指令指针

$cs代码段寄存器

$eflags标志

$uesp用户栈指针

$ss堆栈段寄存器

常用寄存器也使用其机器无关名称作为别名。

寄存器说明

$SP栈指针,等同于 $uesp

$pc程序计数器,等同于 $eip

$fp帧指针,等同于 $ebp

80386 下半部(16 位)寄存器为:

寄存器说明

$ax通用寄存器

$cx通用寄存器

$dx通用寄存器

$bx通用寄存器

$si源索引寄存器

$di目标索引寄存器

$ip指令指针,下 16 位

$flags标志,下 16 位

80386 的前四个 16 位寄存器可分为多个 8 位部分:

寄存器说明

$al寄存器 $ax 的(右)下半部分

$ah寄存器 $ax 的(左)上半部分

$cl寄存器 $cx 的(右)下半部分

$ch寄存器 $cx 的(左)上半部分

$dl寄存器 $dx 的(右)下半部分

$dh寄存器 $dx 的(左)上半部分

$bl寄存器 $bx 的(右)下半部分

$bh寄存器 $bx 的(左)上半部分

80387 的寄存器为:

寄存器说明

$fctrl控制寄存器

$fstat状态寄存器

$ftag标记寄存器

$fip指令指针偏移

$fcs代码段选择符

$fopoff操作数指针偏移

$fopsel操作数指针选择符

$st0 到 $st7数据寄存器

AMD64 寄存器信息

下面的寄存器信息适用于 AMD64 体系结构:

寄存器说明

rax通用寄存器-为函数调用传递参数

rbx通用寄存器-被调用方保存

rcx通用寄存器-为函数调用传递参数

rdx通用寄存器-为函数调用传递参数

rbp通用寄存器-栈管理/帧指针

rsi通用寄存器-为函数调用传递参数

rdi通用寄存器-为函数调用传递参数

rsp通用寄存器-栈管理/栈指针

r8通用寄存器-为函数调用传递参数

r9通用寄存器-为函数调用传递参数

r10通用寄存器-临时

r11通用寄存器-临时

r12通用寄存器-被调用方保存

r13通用寄存器-被调用方保存

r14通用寄存器-被调用方保存

r15通用寄存器-被调用方保存

rflags标志寄存器

rip指令指针

mmx0/st064 位媒体和浮点寄存器

mmx1/st164 位媒体和浮点寄存器

mmx2/st264 位媒体和浮点寄存器

mmx3/st364 位媒体和浮点寄存器

mmx4/st464 位媒体和浮点寄存器

mmx5/st564 位媒体和浮点寄存器

mmx6/st664 位媒体和浮点寄存器

mmx7/st764 位媒体和浮点寄存器

xmm0128 位媒体寄存器

xmm1128 位媒体寄存器

xmm2128 位媒体寄存器

xmm3128 位媒体寄存器

xmm4128 位媒体寄存器

xmm5128 位媒体寄存器

xmm6128 位媒体寄存器

xmm7128 位媒体寄存器

xmm8128 位媒体寄存器

xmm9128 位媒体寄存器

xmm10128 位媒体寄存器

xmm11128 位媒体寄存器

xmm12128 位媒体寄存器

xmm13128 位媒体寄存器

xmm14128 位媒体寄存器

xmm15128 位媒体寄存器

cs段寄存器

os段寄存器

es段寄存器

fs段寄存器

gs段寄存器

ss段寄存器

fcwfxsave 和 fxstor 内存映像控制字

fswfxsave 和 fxstor 内存映像状态字

ftwfxsave 和 fxstor 内存映像标记字

fopfxsave 和 fxstor 内存映像最后一个 x87 op 代码

fripfxsave 和 fxstor 内存映像 64 位代码段偏移

frdpfxsave 和 fxstor 内存映像 64 位日期段偏移

mxcsrfxsave 和 fxstor 内存映像 128 位媒体指令控制和状态寄存器

mxcsr_maskmxcsr_mask 中的设置位指示 mxcsr 中支持的特征位

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值