dbx コマンドによるデバッグ ホーム目次前ページへ次ページへ索引


第 17 章

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

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

この章は次の各節から構成されています。

メモリーの内容を調べる

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

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

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

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

あるメモリーの内容を表示するには、書式 fmtcount 項目の address で表される次の構文を使用します。デフォルトの addr は、前に表示された最後のアドレスの次のアドレスになります。デフォルト count は 1 です。デフォルト fmt は、前の examine または x コマンドで使用されたものと同じです。

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

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

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

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)

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

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

i アセンブラ命令として表示
d 10 進表記の16 ビット (2 バイト) で表示
D 10 進表記の32 ビット (4 バイト) で表示
o 8 進表記の16 ビット (2 バイト) で表示
O 8 進表記の32 ビット (4 バイト) で表示
x 16 進表記の16 ビット (2 バイト) で表示
X 16 進表記の32 ビット (4 バイト) で表示 (デフォルトの書式)
b 8 進表記のバイトで表示
c 1 バイトの文字で表示
w ワイド文字で表示
s NULL バイトで終わる文字列で表示
W ワイド文字列で表示
f 単精度浮動小数点数として表示
F,g 倍精度浮動小数点数として表示
E 拡張精度浮動小数点数として表示
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)

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 コマンドの使用

このコマンドは、表示書式を i として指定した examine コマンドと同じです。

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]

Intel の場合は次のとおりです。

(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 は次の命令が呼び出した関数をステップ実行します (呼び出された関数の最初の命令で停止します)。コマンドの書式も同じです。詳細については、Sun WorkShop オンラインヘプ」の「dbx コマンドの使い方」の「next コマンド」と「step コマンド」を参照してください。

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

例を示します。

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

詳細については、Sun WorkShop オンラインヘプ」の「dbx コマンドの使い方」の「nexti コマンド」と「stepi コマンド」を参照してください。

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

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

tracei コマンドを使用すると、各命令が実行され、アドレスの実行またはトレース中の変数または式の値を dbx が調べている間、プログラムは一瞬停止します。このように tracei コマンドの場合、実行速度がかなり低下します。

トレースとそのイベント使用および修飾子については、「コードをトレースする」と、Sun WorkShop オンラインヘプ」の「dbx コマンドの使い方」の「nexti コマンド」と「trace コマンド」を参照してください。

構文は次のとおりです。

tracei event-specification [modifier]

共通に使用される tracei 書式は次のとおりです。

tracei step 各命令をトレース
tracei next 各命令をトレースするが、呼び出しを飛び越します。
tracei at address 指定のコードアドレスをトレース


詳細については、Sun WorkShop オンラインヘプ」の「dbx コマンドの使い方」の「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]

詳細については、Sun WorkShop オンラインヘプ」の「dbx コマンドの使い方」の「stopi コマンド」を参照してください。

あるアドレスにブレークポイントを設定する

特定のアドレスにブレークポイントを設定するには、コマンドペインで次のように入力します。

(dbx) stopi at address

例 :

(dbx) nexti
stopped in hand::ungrasp at 0x12638
(dbx) stopi at &hand::ungrasp
(3) stopi at &hand::ungrasp
(dbx) 

adb コマンドの使用

adb(1) 構文で adb コマンドを入力できます。また、すべてのコマンドを adb 構文として解釈する adb モードに変更することもできます。ほとんどの adb コマンドがサポートされています。

詳細については、Sun WorkShop オンラインヘプ」の「dbx コマンドの使い方」の「adb コマンド」を参照してください。

regs コマンドの使用

regs コマンドを使用すると、すべてのレジスタの値を表示することができます。

次に、regs コマンドの構文を示します。

regs [-f] [-F]

-f には浮動小数点レジスタ (単精度)、-F には浮動小数点レジスタ (倍精度) が含まれます。これは、SPARC だけのオプションです。

詳細については、Sun WorkShop オンラインヘプ」の「dbx コマンドの使い方」の「regs コマンド」を参照してください。

SPARC の場合は次のようになります。

dbx   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
... 

プラットフォーム固有のレジスタ

次の表は、式で使用できる SPARC および x86 のプラットフォームに固有のレジスタ名を示しています。

SPARC レジスタ情報

SPARC システムのレジスタ情報は次のとおりです。

レジスタ 説明
$g0-$g7 「大域」レジスタ
$o0-$o7 「出力」レジスタ
$l0-$17 「局所」レジスタ
$i0-$i7 「入力」レジスタ
$fp フレームポインタ (レジスタ $i6 と等価)
$sp スタックポインタ (レジスタ $o6 と等価)
$y Y レジスタ
$psr プロセッサ状態レジスタ
$wim ウィンドウ無効マスクレジスタ
$tbr トラップベースレジスタ
$pc プログラムカウンタ
$npc 次のプログラムカウンタ
$f0-$f31 FPU "f" レジスタ
$fsr FPU 状態レジスタ
$fq FPU キュー


$f0f1 $f2f3...$f30f31 のような浮動小数点レジスタのペアは、C の "doule" 型とみなされます。通常、$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』(トッパン刊) および『Sun-4 Assembly Language Reference Manual』を参照してください。

Intel レジスタ情報

Intel システムのレジスタ情報は次のとおりです。

レジスタ 説明
$gs 代替データセグメントレジスタ
$fs 代替データセグメントレジスタ
$es 代替データセグメントレジスタ
$ds データセグメントレジスタ
$edi デスティネーションインデックスレジスタ
$esi ソースインデックスレジスタ
$ebp フレームポインタ
$esp スタックポインタ
$ebx 汎用レジスタ
$edx 汎用レジスタ
$ecx 汎用レジスタ
$eax 汎用レジスタ
$trapno 例外ベクトル番号
$err 例外を示すエラーコード
$eip 命令ポインタ
$cs コードセグメントレジスタ
$eflags フラグ
$es 代替データセグメントレジスタ
$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 - $st7 データレジスタ



サン・マイクロシステムズ株式会社
Copyright information. All rights reserved.
ホーム   |   目次   |   前ページへ   |   次ページへ   |   索引