dbx コマンドによるデバッグ

付録 C ユーザーへのアドバイス

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

一般的な GDB コマンドに対する dbx の同等機能の使用

次の表は、一般的な GNU デバッグ (GDB) コマンドにほぼ等しい dbx コマンドを示しています。

表 C-1 dbx コマンドと一般的な GDB コマンドの相対表

GDB

DBX

break line

stop at line

break func

stop in func

break *addr

stopi at addr

break ... if expr

stop ... -if expr

cond n

stop ... -if expr

tbreak

stop ... -temp

watch expr

stop expr [低速]

watch var

stop modify &var [高速]

catch x

intercept x

info break

status

info watch

status

clear

clear

clear fun

delete n

delete

delete all

disable

handler -disable all

disable n

handler -disable n

enable

handler -enable all

enable n

handler -enable n

ignore n cnt

handler -count n cnt

commands n

when ... { cmds; }

backtrace n

where n

frame n

frame n

info reg reg

print $reg

finish

step up

signal num

cont sig num

jump line

cont at line

set var=expr

assign var=expr

x/fmt addr

x addr/fmt

disassem addr

dis addr

shell cmd

sh cmd [必要な場合]

info func regex

funcs regexp

ptype type

whatis -t type

define cmd

function cmd

handle sig

stop sig sig

info signals

status; catch

attach pid

debug - pid

attach pid

debug a.out pid

file file

[必要ない]

exec file

debug file

core file

debug a.out corefile

set editing on

set -o emacs

set language x

language x

set prompt x

PS1=x

set history size x

HISTSIZE=x

set print object on

dbxenv output_dynamic_type on

show commands

history

dir name

pathmap name

show dir

pathmap

info line <n

listi n

info source

file

info sources

files; modules

forw regex

search regexp

rev regex

bsearch regexp

dbx の変更の検査

.dbxinit ファイルの使用

dbx を以前から使用しているユーザーは、新しい .dbxrc ファイルではなく、.dbxinit ファイルを使用している可能性があります。.dbxrc ファイルがある場合、dbx はそれを読み取って、.dbxinit ファイルを無視します。必要であれば、次の行を .dbxrc ファイルに追加することによって、dbx で両方のファイルを読み取ることができます。


kalias alias=dalias
source ‾/.dbxinit
kalias alias=kalias

.dbxrc ファイルがなくて、.dbxinit ファイルがある場合は、次の警告メッセージが表示されます。


.dbxinit 互換モードを使用します。詳細は 'help .dbxrc' を参照してください。

現在 dbx は、.dbxinit ファイルを読み取りますが、この機能は今後のリリースでなくなる可能性があります。

.dbxinit ファイルを使用している場合は、.dbxrc ファイルを代わりに使用する方法について、第 2 章「dbx のカスタマイズ」を参照してください。

別名の定義

alias コマンドは、dalias または kalias の事前定義された別名です。

シンボル / および ?

Korn シェルベースのパーサーの説明では、/ (スラッシュ) コマンドを UNIX のパス名と区別できないため、名前変更する必要があります。代わりに search を使用してください。

次の例は、ルートディレクトリからファイル abc を実行する方法を示します。


(dbx) /abc

同様に、? (疑問符) は現在シェルメタキャラクタであるため、名前変更する必要があります。代わりに bsearch を使用してください。

次の例では、最後の 3 文字が abc である 4 文字のファイル名を持つ、カレントディレクトリ内のファイルすべてに一致するパターンを読み取ってから、結果のコマンドを実行します。


(dbx) ?abc

前述のコマンドを頻繁に使用する場合は、それらの別名を作成することができます。

alias ff=search

前方検索 

alias fb=bsearch

後方検索 

組み込みスラッシュコマンド

組み込みスラッシュコマンドは名前が変更されました。このコマンドは現在無効です。


0x1234/5X

examine コマンドか、またはその別名である x を次のように使用してください。


examine 0x1234/5X
x 0x1234/5X

set の代わりに assign を使用する

set は Korn シェルの set コマンドになり、assign の別名ではなくなりました。

コマンド行編集を有効にする

コマンド行編集はいくつかの方法で有効にすることができます。まず、$FCEDIT$EDITOR、または $VISUAL のいずれかが設定されている場合は、その値がチェックされます。最後の構成要素、つまり最後のスラッシュの後にある構成要素に emacs という文字列が含まれる場合は、emacs モードが有効になります。vi という文字列が含まれる場合は vi モードが有効になります。3 つの環境変数がどれも設定されていないか、または設定されたリスト内の最初のものに emacsvi も含まれない場合、コマンド行編集は無効です。

emacs モードまたは vi モードは、コマンド行あるいは .dbxrc ファイルから有効にすることができます。


set -o emacs
set -o vi

コマンド行編集を無効にするには、次のように入力します。


set +o emacs +o vi

スコープに入れる

dbxabc という名前がカレントスコープに定義されていないと示される場合は、実行の現時点から abc という名前のシンボルにアクセスすることができません。詳細については、第 3 章「コードの表示」を参照してください。

ファイルの検索

dbx によって作成されるファイルはすべて、環境変数 TMPDIR が設定されていないかぎり、ディレクトリ /tmp にあります。この変数が設定されている場合は、ディレクトリ $TMPDIR が使用されます。

ソースファイルがコンパイル時の場所に存在しない場合、あるいはデバッグ中のマシンとは異なるマシンでコンパイルを行って、そのコンパイルディレクトリが同じパス名でマウントされていない場合、dbx はファイルを見つけることができません。解決方法については、第 1 章「dbx の起動」pathmap コマンドの項を参照してください。

ブレークポイントへの到達

到達する予定のブレークポイントに到達しない場合は、次の可能性があります。

この場合、while に設定したブレークポイントは、外部 if でのみブレークポイントになります。これは、dbx が、複数の異なるアドレスにマップするソース行を処理できないためです。

C++ メンバーと whatis コマンド

C++ メンバーの型は、whatis の出力で失われる場合があります。次の例では、メンバー stackcount の型が失われます。


(dbx) whatis stack
class stack {
...
static stackcount;       /* 未定義あるいは未割り当て */
...
};

クラスメンバーが定義されていないか、あるいは割り当てられていない場合、dbx はその型を判別できないため、型は印刷されません。

実行時検査の 8 Mバイト制限

アクセス検査だけにこの制限があります。リーク検査はこの制限による影響を受けません。

アクセス検査の場合、RTC は各ロード命令とストア命令を、パッチ領域に分岐する分岐命令によって置き換えます。この分岐命令は 8Mバイトの範囲を持っています。デバッグされたプログラムが、置換されたロード命令またはストア命令の 8Mバイト内のアドレススペースをすべて使用してしまった場合、パッチ領域を入れる余地はありません。RTC が、メモリーへのロード命令とストア命令の一部を横取りできない場合、正確な情報を提供できないため、アクセス検査は完全に無効になります。

dbx は、この制限に遭遇するといくつかの方針を内部的に適用し、問題を解決できる場合は実行を続けます。場合によっては dbx を続けることができません。この場合は、エラーメッセージが出されて、アクセス検査はオフになります。対策については、第 9 章「実行時検査」を参照してください。

dbx を使用した浮動小数点例外の検索

浮動小数点例外 (FPE) を捕獲する場合は、次の 2 つのことを実行する必要があります。まず、プロセスを停止して、次のように入力します。


(dbx) catch FPE

次に、次のコードを Fortran アプリケーションに追加します。


integer ieeer, ieee_handler, myhandler
ieeer = ieee_handler('set', 'all', myhandler)
...
        
integer function myhandler(sig, code, context)
integer sig, code(5)
call abort()
end

これは、IEEE ソフトウェアがすべてのエラーをサイレント (シグナルを出さない状態) に設定するために必要です。これにより、すべての IEEE 例外が必要に応じて SIGFPE を生成します。

ieee_handler() のパラメータを調整するか、または dbx catch コマンドの代替を使用すると、表示する例外をさらに調整することができます。


stop sig FPE

これは、catch FPE または次のコードと同様に作動します。


stop sig FPE subcode

さらに細かく制御するには、subcode を次のように指定できます。

FPE_INTDIV

整数のゼロ除算 

FPE_INTOVF

整数オーバーフロー 

FPE_FLTDIV

浮動小数点のゼロ除算 

FPE_FLTOVF

浮動小数点オーバーフロー 

FPE_FLTUND

浮動小数点アンダーフロー 

FPE_FLTRES

浮動小数点の不正な結果 

FPE_FLTINV

無効な浮動小数点操作 

FPE_FLTSUB

範囲外の添字 

stopcatch は無関係であり、stop FPE を使用する場合は ignore FPE も必要であることに注意してください。

マルチスレッドプログラムでの dbx の使用

マルチスレッド機能は、dbx の標準な機能です。

dbx の提供する主なマルチスレッド機能は次のとおりです。

スコープを特定のスレッドに制限できます。dbx は、カーソルを現在のスレッドまたは活動中のスレッドに維持します。これは、thread コマンドによって操作できます。カレントスレッドをデフォルトスレッドとして使用するのは、where コマンドと thread -info コマンドだけです。

スレッド番号

dbx は、thr_create() によって返される各スレッド (型 thread_t) の ID を認識します。この構文は t@number です。

LWP 番号

dbx は、/proc (マニュアルページ procfs(4)) インタフェースによって表示される各 LWP (型 lwpid_t) の ID を認識します。この構文は l@number です。

特定スレッドのブレークポイント

通常のブレークポイントをフィルタ処理することによって、特定スレッドにブレークポイントを設定できます。


stop in foo -thread t@4

ここで、t@4 は ID 4 のスレッドを示します。

あるスレッドがブレークポイントに達すると、すべてのスレッドが停止します。これは、「同時停止」または「世界の停止」と呼ばれています。

/proc と LWP の立場から見ると、これは同期デバッグです。

スレッドのナビゲートを容易にするには、次のコードを .dbxrc に追加してください。


_cb_prompt() {
        if [ $mtfeatures = “true”]
        then
                PS1='[$thread $lwp]: '
        else
                PS1=”(dbx-$proc) “
        fi
}

dbx によるマルチスレッドアプリケーションの識別

アプリケーションが -lthread によってリンクされている場合、dbx はそれをマルチスレッドと想定します。

コレクタ、RTC、fix と continue、およびウォッチポイント

コレクタおよび fixcontinue は、マルチスレッドアプリケーションで動作します。RTC はマルチスレッドアプリケーションで動作しますが、libthread パッチが必要です。

ウォッチポイントの実装は、オペレーティングシステムと関係ありません。また、マルチスレッドアプリケーションでデッドロックなどの問題がすぐに起こるおそれがあります。

マルチスレッドの注意点

特定のスレッドを再開するときに、ほかのスレッドが静止していて、再開されるそのスレッドが必要とする可能性のある資源を保持している場合、プログラムはすぐにデッドロック状態になります。

libthread データ構造はユーザースペースにあって、はぐれポインタが原因のバグによって破壊されるおそれがあります。このような場合には、スレッドの同等機能に似た lwpslwp のようなコマンドを使用して LWP レベルで作業することをお勧めします。

スリープ中のスレッド

スリープ中のスレッドの実行を「強いる」ことはできません。通常、マルチスレッドアプリケーションをデバッグする場合は、プログラムの自然な実行フローを変更するのではなく、「後へ下がって監視」することをお勧めします。

thr_join、thr_create()、および thr_exit

スレッドリストから、どのスレッド ID がどの起動関数によるものかを判別することができます。この「ベース関数」は、スレッドリストに出力されます。

既存のマルチスレッドプロセスに接続する場合、どのスレッドが活動中になるかを判断することはできません。

活動中のスレッドが thr_create を実行する場合、カレントスレッドは「作成スレッド」にとどまります。follow_fork に従って考えると、これは親になります。

サンのマルチスレッドモデルには、真のスレッド用のフォークセマンティクスがありません。スレッドツリーや、プロセスの場合のような親子関係がありません。thr_join() は、単純化された表面上のものにすぎません。

活動中のスレッドが thr_exit を実行すると、dbx はダミーの「停止」スレッドを活動中にします。このスレッドは、t@x と表されます。