Oracle Solaris Studio 12.2: dbx コマンドによるデバッグ

第 18 章 機械命令レベルでのデバッグ

この章は、イベント管理コマンドやプロセス制御コマンドを機械命令レベルで使用する方法と、特定のアドレスにおけるメモリーの内容を表示する方法、対応する機械命令とともにソース行を表示する方法を説明します。 コマンド nextstepstoptrace のそれぞれに、対応する機械命令レベルのコマンド nextistepistopitracei が用意されています。regs コマンドは、機械語レジスタを出力するために使用できます。また、print コマンドは、個々のレジスタを出力するために使用できます。

この章の内容は次のとおりです。

メモリーの内容を調べる

アドレスと examine または x コマンドを使用して、メモリーロケーションの内容を調べたり、各アドレスでアセンブリ言語命令を出力したりすることができます。アセンブリ言語のデバッガである adb(1) から派生したコマンドを使用して、次の項目について問い合わせることができます。

dislisti コマンドを使用して、アセンブリ命令とメモリーの内容を調べることができます (dis コマンドの使用」listi コマンドの使用」を参照)。

examine または x コマンドの使用

examine コマンドまたはその別名 x を使用すると、メモリーの内容やアドレスを表示することができます。

あるメモリーの内容を表示するには、書式 formatcount 項目の address で表される次の構文を使用します。デフォルトの address は、前に表示された最後のアドレスの次のアドレスになります。デフォルトの count は 1 です。デフォルトの format は、前の examine または X コマンドで使用されたものと同じです (これが最初に入力されたコマンドの場合)。

examine コマンドの構文は次のとおりです。


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

address1 から address2 までのメモリー内容を書式 format で表示するには、次のように入力します。


examine address1, address2 [/ [format]]

アドレスの内容ではなくアドレスを指定の書式で表示するには、次のように入力します。


examine address = [format]

examine によって最後に表示されたアドレスの次のアドレスに格納された値を出力するには、次のように入力します。


examine +/ i

式の値を出力するには、式をアドレスとして入力します。


examine address=format
examine address=

アドレスを使用する

address はアドレスの絶対値、またはアドレスとして使用できる任意の式です。+ (プラス記号) はデフォルトの address の次のアドレスを表します。

たとえば、次のアドレスは有効です。

0xff99

絶対アドレス 

main

関数のアドレス 

main+20

関数アドレス + オフセット 

&errno

変数のアドレス 

str

文字列を指すポインタ変数 

メモリーを表示するためのアドレス表現は、名前の前にアンパサンド & を付けて指定します。関数名はアンパサンドなしで使用できます。&mainmain と同じです。レジスタは、名前の前にドル記号 $ を付けることによって表します。

書式を使用する

format は、dbx がアドレスの問い合わせ結果を表示するときの書式です。生成される出力は、現在の表示書式 format によって異なります。表示書式を変更する場合は、異なる format コードを使用してください。

dbx セッションの初めに設定されるデフォルトの書式は X です。このとき、16 進表記のアドレスと値が 1 ワード (32 ビット) で表示されます。次の表は、表示書式の一覧です。

アセンブラ命令として表示 

10 進表記の 16 ビット (2 バイト) で表示 

10 進表記の 32 ビット (4 バイト) で表示 

8 進表記の 16 ビット (2 バイト) で表示 

8 進表記の 32 ビット (4 バイト) で表示 

16 進表記の 16 ビット (2 バイト) で表示 

16 進表記の 32 ビット (4 バイト) で表示 (デフォルト書式) 

8 進表記のバイトで表示 

1 バイトの文字で表示 

ワイド文字列で表示 

-s 

NULL バイトで終わる文字列で表示 

ワイド文字列で表示 

単精度浮動小数点数として表示 

F, g 

倍精度浮動小数点数として表示 

拡張精度浮動小数点数として表示 

ld, lD 

10 進数として 32 ビット (4 バイト) で表示 (D と同じ) 

lo, lO 

8 進数として 32 ビット (4 バイト) で表示 (O と同じ) 

lx, LX 

16 進数として 32 ビット (4 バイト) で表示 (X と同じ) 

Ld, LD 

10 進数として 64 ビット (8 バイト) で表示 

Lo, LO 

8 進数として 64 ビット (8 バイト) で表示 

Lx, LX 

16 進数として 64 ビット (8 バイト) で表示 

カウントを使用する

count は、10 進法での反復カウントを示します。増分サイズは、メモリーの表示書式によって異なります。

アドレスの使用例

次の例は、count および format の各オプションを付けてアドレスを使用して、現在の停止点から始まる 5 つの連続する分解された命令を表示する方法を示しています。

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 コマンドは、examine コマンド (デフォルト表示書式を i として指定) と同じです。

dis コマンドの構文は次のようになります。


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

dis コマンドの動作は次のとおりです。

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)

機械命令レベルでのステップ実行とトレース

機械命令レベルの各コマンドは、対応するソースレベルのコマンドと同じように動作します。ただし、動作の単位はソース行ではなく、単一の命令です。

機械命令レベルでステップ実行する

ある機械命令から次の機械命令に 1 つだけステップ実行するには、nexti コマンドまたは stepi コマンドを使用します。

nexti コマンドと stepi コマンドは、それぞれに対応するソースコードレベルのコマンドと同じように動作します。すなわち、nexti コマンドは over 関数をステップ実行し、stepi は次の命令が呼び出した関数をステップ実行します (呼び出された関数の最初の命令で停止します)。コマンドの書式も同じです。詳細については、next コマンド」step コマンド」を参照してください。

nextistepi の出力は、対応するソースレベルのコマンドの場合と次の 2 つの違いがあります。

次に例を示します。


(dbx) func
hand::ungrasp
(dbx) nexti
ungrasp +0x18:  call support
(dbx)

詳細については、nexti コマンド」stepi コマンド」を参照してください。

機械命令レベルでトレースする

機械命令レベルでのトレースは、ソースコードレベルでのトレースと同じように行われます。ただし、tracei コマンドを使用する場合は例外です。tracei コマンドでは、実行中のアドレスま たはトレース対象の変数の値がチェックされた場合にだけ、単一の命令が実行されます。tracei コマンドは、stepi のような動作を自動的に行います。すなわち、プログラムは 1 度に 1 つの命令だけ進み、関数呼び出しに入ります。

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 コマンドを使用します。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 レジスタ情報

SPARC アーキテクチャーのレジスタ情報は次のとおりです。

レジスタ  

内容の説明  

$g0 through $g7

「大域」レジスタ 

$o0 through $o7

「出力」レジスタ 

$l0 through $l7

「局所」レジスタ 

$i0 through $i7

「入力」レジスタ 

$fp

フレームポインタ (レジスタ $i6 と等価) 

$sp

スタックポインタ (レジスタ $o6 と等価) 

$y

Y レジスタ 

$psr

プロセッサ状態レジスタ 

$wim

ウィンドウ無効マスクレジスタ 

$tbr

トラップベースレジスタ 

$pc

プログラムカウンタ 

$npc

次のプログラムカウンタ 

$f0 through $f31

FPU "f" レジスタ 

$fsr

FPU 状態レジスタ 

$fq

FPU キュー 

$f0f1 $f2f3 ... $f30f31 のような浮動小数点レジスタのペアは、C の「double」型とみなされます (通常、$fN レジスタは C の「float」型とみなされます)。これらのペアは、$d0 ... $d30 とも呼ばれます。

次の追加レジスタは、SPARC V9 および V8+ ハードウェアで使用できます。


$g0g1 through $g6g7
$o0o1 through $o6o7
$xfsr $tstate $gsr
$f32f33 $f34f35 through $f62f63 ($d32 ... $$d62)

SPARC のレジスタとアドレッシングの詳細については、『SPARC アーキテクチャーマニュアル バージョン 8』(トッパン刊) および『SPARC Assembly Language Reference Manual』を参照してください。

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 ビット) 

上記のうち最初の 4 つの 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 through $st7

データレジスタ 

AMD64 レジスタ情報

AMD64 アーキテクチャーのレジスタ情報は次のとおりです。

レジスタ  

内容の説明  

rax

汎用レジスタ - 関数呼び出しの引数の引き渡し 

rbx

汎用レジスタ - 呼び出し先保存 

rcx

汎用レジスタ - 関数呼び出しの引数の引き渡し 

rdx

汎用レジスタ - 関数呼び出しの引数の引き渡し 

rbp

汎用レジスタ - スタック管理/フレームポインタ 

rsi

汎用レジスタ - 関数呼び出しの引数の引き渡し 

rdi

汎用レジスタ - 関数呼び出しの引数の引き渡し 

rsp

汎用レジスタ - スタック管理/スタックポインタ 

r8

汎用レジスタ - 関数呼び出しの引数の引き渡し 

r9

汎用レジスタ - 関数呼び出しの引数の引き渡し 

r10

汎用レジスタ - 一時レジスタ 

r11

汎用レジスタ - 一時レジスタ 

r12

汎用レジスタ - 呼び出し先保存 

r13

汎用レジスタ - 呼び出し先保存 

r14

汎用レジスタ - 呼び出し先保存 

r15

汎用レジスタ - 呼び出し先保存 

rflags

フラグレジスタ 

rip

命令ポインタ 

mmx0/st0

64 ビットメディアおよび浮動小数点レジスタ 

mmx1/st1

64 ビットメディアおよび浮動小数点レジスタ 

mmx2/st2

64 ビットメディアおよび浮動小数点レジスタ 

mmx3/st3

64 ビットメディアおよび浮動小数点レジスタ 

mmx4/st4

64 ビットメディアおよび浮動小数点レジスタ 

mmx5/st5

64 ビットメディアおよび浮動小数点レジスタ 

mmx6/st6

64 ビットメディアおよび浮動小数点レジスタ 

mmx7/st7

64 ビットメディアおよび浮動小数点レジスタ 

xmm0

128 ビットメディアレジスタ 

xmm1

128 ビットメディアレジスタ 

xmm2

128 ビットメディアレジスタ 

xmm3

128 ビットメディアレジスタ 

xmm4

128 ビットメディアレジスタ 

xmm5

128 ビットメディアレジスタ 

xmm6

128 ビットメディアレジスタ 

xmm7

128 ビットメディアレジスタ 

xmm8

128 ビットメディアレジスタ 

xmm9

128 ビットメディアレジスタ 

xmm10

128 ビットメディアレジスタ 

xmm11

128 ビットメディアレジスタ 

xmm12

128 ビットメディアレジスタ 

xmm13

128 ビットメディアレジスタ 

xmm14

128 ビットメディアレジスタ 

xmm15

128 ビットメディアレジスタ 

cs

セグメントレジスタ 

os

セグメントレジスタ 

es

セグメントレジスタ 

fs

セグメントレジスタ 

gs

セグメントレジスタ 

ss

セグメントレジスタ 

fcw

fxsave および fxstor メモリーイメージ制御ワード

fsw

fxsave および fxstor メモリーイメージステータスワード

ftw

fxsave および fxstor メモリーイメージタグワード

fop

fxsave および fxstor メモリーイメージ最終 x87 オペコード

frip

fxsave および fxstor メモリーイメージ 64 ビットオフセットからコードセグメントへ

frdp

fxsave および fxstor メモリーイメージ 64 ビットオフセットからデータセグメントへ

mxcsr

fxsave および fxstor メモリーイメージ 128 メディア命令制御およびステータスレジスタ

mxcsr_mask

mxcsr_mask のビットを設定し、mxcsr でサポートされる機能ビットを示す