この付録は、次の各節から構成されています。
次の表は、一般的な 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 を以前から使用しているユーザーは、新しい .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 は Korn シェルの set コマンドになり、assign の別名ではなくなりました。
コマンド行編集はいくつかの方法で有効にすることができます。まず、$FCEDIT、$EDITOR、または $VISUAL のいずれかが設定されている場合は、その値がチェックされます。最後の構成要素、つまり最後のスラッシュの後にある構成要素に emacs という文字列が含まれる場合は、emacs モードが有効になります。vi という文字列が含まれる場合は vi モードが有効になります。3 つの環境変数がどれも設定されていないか、または設定されたリスト内の最初のものに emacs も vi も含まれない場合、コマンド行編集は無効です。
emacs モードまたは vi モードは、コマンド行あるいは .dbxrc ファイルから有効にすることができます。
set -o emacs set -o vi
set +o emacs +o vi
dbx で abc という名前がカレントスコープに定義されていないと示される場合は、実行の現時点から abc という名前のシンボルにアクセスすることができません。詳細については、第 3 章「コードの表示」を参照してください。
dbx によって作成されるファイルはすべて、環境変数 TMPDIR が設定されていないかぎり、ディレクトリ /tmp にあります。この変数が設定されている場合は、ディレクトリ $TMPDIR が使用されます。
ソースファイルがコンパイル時の場所に存在しない場合、あるいはデバッグ中のマシンとは異なるマシンでコンパイルを行って、そのコンパイルディレクトリが同じパス名でマウントされていない場合、dbx はファイルを見つけることができません。解決方法については、第 1 章「dbx の起動」の pathmap コマンドの項を参照してください。
到達する予定のブレークポイントに到達しない場合は、次の可能性があります。
関数にブレークポイントを設定しても、それが予想した関数ではない可能性があります。whereis funcname を使用して、指定の名前の関数が複数存在するかを調べてください。次に whereis の出力によって示された正しい構文を stop コマンドで使用してください。
ブレークポイントが while ループ中にある場合、コンパイラは、次の形式のコードを論理的に変換します。
while (condition) statement
if (condition) { again: statement if condition goto again; }
この場合、while に設定したブレークポイントは、外部 if でのみブレークポイントになります。これは、dbx が、複数の異なるアドレスにマップするソース行を処理できないためです。
C++ メンバーの型は、whatis の出力で失われる場合があります。次の例では、メンバー stackcount の型が失われます。
(dbx) whatis stack class stack { ... static stackcount; /* 未定義あるいは未割り当て */ ... };
クラスメンバーが定義されていないか、あるいは割り当てられていない場合、dbx はその型を判別できないため、型は印刷されません。
アクセス検査だけにこの制限があります。リーク検査はこの制限による影響を受けません。
アクセス検査の場合、RTC は各ロード命令とストア命令を、パッチ領域に分岐する分岐命令によって置き換えます。この分岐命令は 8Mバイトの範囲を持っています。デバッグされたプログラムが、置換されたロード命令またはストア命令の 8Mバイト内のアドレススペースをすべて使用してしまった場合、パッチ領域を入れる余地はありません。RTC が、メモリーへのロード命令とストア命令の一部を横取りできない場合、正確な情報を提供できないため、アクセス検査は完全に無効になります。
dbx は、この制限に遭遇するといくつかの方針を内部的に適用し、問題を解決できる場合は実行を続けます。場合によっては dbx を続けることができません。この場合は、エラーメッセージが出されて、アクセス検査はオフになります。対策については、第 9 章「実行時検査」を参照してください。
浮動小数点例外 (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 |
1 |
整数のゼロ除算 |
FPE_INTOVF |
2 |
整数オーバーフロー |
FPE_FLTDIV |
3 |
浮動小数点のゼロ除算 |
FPE_FLTOVF |
4 |
浮動小数点オーバーフロー |
FPE_FLTUND |
5 |
浮動小数点アンダーフロー |
FPE_FLTRES |
6 |
浮動小数点の不正な結果 |
FPE_FLTINV |
7 |
無効な浮動小数点操作 |
FPE_FLTSUB |
8 |
範囲外の添字 |
stop と catch は無関係であり、stop FPE を使用する場合は ignore FPE も必要であることに注意してください。
マルチスレッド機能は、dbx の標準な機能です。
dbx の提供する主なマルチスレッド機能は次のとおりです。
threads コマンドは、既知のスレッドすべてのリストを示します。このリストには、その現在の状態、基本機能、および現在の関数が示されます。
各スレッドのスタックトレースを調べることができます。
特定のスレッドまたはすべてのスレッドを再開 (cont) できます。
特定のスレッドに step または next することができます。
thread コマンドは、スレッド間でナビゲートできます。
スコープを特定のスレッドに制限できます。dbx は、カーソルを現在のスレッドまたは活動中のスレッドに維持します。これは、thread コマンドによって操作できます。カレントスレッドをデフォルトスレッドとして使用するのは、where コマンドと thread -info コマンドだけです。
dbx は、thr_create() によって返される各スレッド (型 thread_t) の ID を認識します。この構文は t@number です。
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 }
アプリケーションが -lthread によってリンクされている場合、dbx はそれをマルチスレッドと想定します。
コレクタおよび fix と continue は、マルチスレッドアプリケーションで動作します。RTC はマルチスレッドアプリケーションで動作しますが、libthread パッチが必要です。
ウォッチポイントの実装は、オペレーティングシステムと関係ありません。また、マルチスレッドアプリケーションでデッドロックなどの問題がすぐに起こるおそれがあります。
特定のスレッドを再開するときに、ほかのスレッドが静止していて、再開されるそのスレッドが必要とする可能性のある資源を保持している場合、プログラムはすぐにデッドロック状態になります。
libthread データ構造はユーザースペースにあって、はぐれポインタが原因のバグによって破壊されるおそれがあります。このような場合には、スレッドの同等機能に似た lwps や lwp のようなコマンドを使用して LWP レベルで作業することをお勧めします。
スリープ中のスレッドの実行を「強いる」ことはできません。通常、マルチスレッドアプリケーションをデバッグする場合は、プログラムの自然な実行フローを変更するのではなく、「後へ下がって監視」することをお勧めします。
スレッドリストから、どのスレッド ID がどの起動関数によるものかを判別することができます。この「ベース関数」は、スレッドリストに出力されます。
既存のマルチスレッドプロセスに接続する場合、どのスレッドが活動中になるかを判断することはできません。
活動中のスレッドが thr_create を実行する場合、カレントスレッドは「作成スレッド」にとどまります。follow_fork に従って考えると、これは親になります。
サンのマルチスレッドモデルには、真のスレッド用のフォークセマンティクスがありません。スレッドツリーや、プロセスの場合のような親子関係がありません。thr_join() は、単純化された表面上のものにすぎません。
活動中のスレッドが thr_exit を実行すると、dbx はダミーの「停止」スレッドを活動中にします。このスレッドは、t@x と表されます。