dbx コマンドによるデバッグ | ![]() ![]() ![]() ![]() ![]() |
第 11 章
修正継続機能 (fix と continue)
fix
を使用すると、デバッグプロセスを停止しないで、編集されたソースコードを簡単に再コンパイルすることができます。修正継続機能の使用
fix
とcontinue
の各機能を使用すると、ソースファイルを修正して再コンパイルし、プログラム全体を作成しなおすことなく実行を続けることができます。.o
ファイルを更新して、それらをデバッグ中のプログラムに組み込むことにより、再リンクの必要がなくなります。
- プログラムをリンクしなおす必要がない。
- プログラムを
dbx
に再読み込みする必要がない。- 修正した位置からプログラムの実行を再開できる。
注 - 構築が進行中の場合は、Sun WorkShop のfix
を使用しないでください。
fix と continue の働き
fix
コマンドを使用するには、エディタウィンドウでソースを編集する必要があります (コードの変更方法については、「fix と continue によるソースの変更」参照)。変更結果を保存してfix
と入力します。fix コマンドについては、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「fix コマンド」を参照してください。
fix
が実行されると、dbx
は適切なコンパイラオプションでコンパイラを呼び出します。変更後のファイルがコンパイルされ、一時共有オブジェクト (.so
) ファイルが作成されます。古いファイルと新しいファイルとを比較することによって、修正の安全性を検査する意味上のテストが行われます。実行時リンカーを使用して新しいオブジェクトファイルが動作中のプロセスにリンクされ、プログラムカウンタが古い関数から新しい関数の同じ行に移動します (その関数が修正中のスタックの 1 番上にある場合)。さらに、古いファイルのブレークポイントがすべて新しいファイルに移動します。
対象となるファイルがデバッグ情報つきでコンパイルされているかどうかに関わらず、
fix
とcont
を実行できます。ただし、デバッグ情報なしでコンパイルされているファイルの場合には多少の機能制限があります。Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「fix コマンド」の-g
オプションの解説を参照してください。共有オブジェクト (
.so
) ファイルの修正は可能ですが、その場合、そのファイルを特別なモードでオープンする必要があります。dlopen
関数の呼び出しで、RTLD_NOW|RTLD_GLOBAL
またはRTLD_LAZY|RTLD_GLOBAL
のどちらかを使用します。fix と continue によるソースの変更
fix
とcontinue
を使用すると、ソースを次の方法で変更できます。古いファイルから新しいファイルに関数をマップすると問題が起きることがあります。ソースファイルの編集時にこのような問題の発生を防ぐには、次のことを守ってください。
- 関数の名前を変更しない。
- 関数に渡す引数の型を追加、削除、または変更しない。
- スタック上で現在アクティブな関数の局所変数の型を追加、削除、または変更しない。
- テンプレートの宣言やテンプレートインスタンスを変更しない。C++ テンプレート関数定義の本体でのみ修正可能です。
上記の変更を行う場合は、fix と continue で処理するよりプログラム全体を作りなおす方が簡単です。
プログラムの修正
変更後にソースファイルを再リンクするとき
fix
コマンドを使用すればプログラム全体を再コンパイルしなくて済みます。引き続きプログラムの実行を続けることができます。1. 変更をソースファイルに保存します。この手順を忘れても、Sun WorkShop では自動的に変更が保存されます。
2.dbx
プロンプトでfix
と入力します。修正は無制限に行うことができますが、1 つの行でいくつかの修正を行った場合は、プログラムを作成しなおすことを考えてください。
fix
コマンドは、メモリー内のプログラムのイメージを変更しますが、ディスク上のイメージは変更しません。また修正を行うと、メモリーのイメージは、ディスク上のイメージと同期しなくなります。
fix
コマンド は、実行可能ファイル内での変更ではなく、.o
ファイルとメモリーイメージの変更だけを行います。プログラムのデバッグを終了したら、プログラムを作成しなおして、変更内容を実行可能ファイルにマージする必要があります。デバッグを終了すると、プログラムを作成しなおすように指示するメッセージが出されます。
-a
以外のオプションを指定し、ファイル名引数なしでfix
コマンドを実行すると、現在変更を行なったソースファイルだけが修正されます。
fix
を実行すると、コンパイル時にカレントであったファイルの現在の作業ディレクトリが検索されてからコンパイル行が実行されます。したがってコンパイル時とデバッグ時とでファイルシステム構造が変化すると正しいディレクトリが見つからなくなることがあります。これを防ぐには、pathmp
コマンドを使用します。これは 1 つのパス名から別のパス名までのマッピングを作成するコマンドです。マッピングはソースパスとオブジェクトファイルパスに適用されます。修正後の続行
プログラムの実行を継続するには、
cont
コマンドを使用します (Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「cont コマンド」参照)。プログラムの実行を再開するには、変更による影響を判断するための以下の条件に注意してください。
実行された関数への変更
すでに実行された関数に変更を加えた場合、その変更内容は次のことが起こるまで無効です。
変数への単純な変更以上のことを修正した場合は、
fix
コマンドに続けてrun
コマンドを使用してください。run
コマンドを使用すると、プログラムの再リンクが行われないため処理が速くなります。呼び出されていない関数への変更
呼び出されていない関数に変更を加えた場合、変更内容は、その関数が呼び出されたときに有効になります。
現在実行中の関数への変更
現在実行中の関数に変更を加えた場合、
fix
コマンドの影響は、変更内容が停止した関数のどの場所に関連しているかによって異なります。
- 実行済みのコードを変更しても、そのコードは再実行されません。コードを実行するには、現在の関数をスタックからポップし (Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「pop コマンド」と「デバッグウィンドウの使い方」の「現在のフレームへの呼び出しスタックのポップ」参照)、変更した関数を呼び出した位置から処理を続けます。取り消すことのできない副作用 (ファイルのオープンなど) が発生しないか、コードの内容をよく理解しておく必要があります。
- 変更内容がまだ実行されていないコードにある場合は、新しいコードが実行されます。
現在スタック上にある関数への変更
停止された関数ではなく、現在スタック上にある関数に変更を加えた場合、変更されたコードは、その関数の現在の呼び出しでは使用されません。停止した関数から戻ると、スタック上の古いバージョンの関数が実行されます。
- 変更したすべての関数がスタックから削除されるまで
pop
コマンドを実行します。コードを実行して問題が発生しないか確認します。cont
at
linenum コマンドを使用して、別の行から実行を続ける。- データ構造を手作業で修正してから (
assign
コマンドを使用)、実行を続ける。run
コマンドを使用してプログラムを再び実行する。スタック上の修正された関数にブレークポイントがある場合、このブレークポイントは、新しいバージョンの関数に移動します。古いバージョンが実行される場合、プログラムはこれらの関数で停止しません。
修正後の変数の変更
大域変数への変更は、
pop
コマンドでもfix
コマンドでも取り消されません。大域変数に正しい値を手作業で再び割り当てるには、assign
コマンドを使用してください。(Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「assign コマンド」参照)。以下の例は、修正継続機能を使用して簡単なバグを修正する方法を示しています。6 行目で NULL ポインタを逆参照しようとしたときに、セグメンテーションエラーが発生します。
edit
でファイルの編集をします。14 行目を 0 ではなくbuf
をコピー (copy
) するように変更し、fix
を実行します。
ここでプログラムを続行しても、NULL ポインタがスタックをプッシュしているためセグメント例外が返されます。
pop
コマンドを使用して、スタックフレームを 1 つ上がってください。
(dbx)pop
main で停止しました 行番号 14 ファイル "testfix.c"14 copy(buf);ここでプログラムを続行すると、プログラムは実行されますが、大域変数 from がすでに増分されているため正しい値が出力されません。
assign コマンドを使用して大域変数を復元し、続行してください。プログラムは次のように正しい値を表示します。assign コマンドを使用しないと、
プログラムは ships と表示すべきところを hips と表示します。
(dbx)
assign from = from-1
(dbx)
cont
ships
ヘッダファイルの変更
場合によってはソースファイルだけでなくヘッダ (
.h
) ファイルも変更することがあります。変更したヘッダファイルをインクルードしている、プログラム内のすべてのソースファイルから、それらのヘッダファイルをアクセスするには、そのヘッダファイルをインクルードしているすべてのソースファイルのリストを引数としてfix
コマンドに渡す必要があります。ソースファイルのリストを指定しなければ、主要ソースファイルだけが再コンパイルされ、変更したヘッダファイルは主要ソースファイルにしかインクルードされず、プログラムの他のソースには変更前のヘッダファイルがインクルードされたままになります。C++ テンプレート定義の修正
C++ テンプレート定義は直接修正できないので、これらのファイルはテンプレートインスタンスで修正します。テンプレート定義ファイルを変更しなかった場合に日付チェックを上書きするには、
-f
オプションを使用します。dbx
によるテンプレート定義.o
ファイルの検索範囲は、デフォルトのリポジトリディレクトリSunWS_cache
です。dbx
のfix
コマンドは-ptr
コンパイラスイッチをサポートしていません。
サン・マイクロシステムズ株式会社 Copyright information. All rights reserved. |
ホーム | 目次 | 前ページへ | 次ページへ | 索引 |