dbx コマンドによるデバッグ | ![]() ![]() ![]() ![]() ![]() |
第 3 章
コードの表示
プログラムが停止するたびに
dbx
が表示するソースコードは、その停止位置に対応するコードです。また、プログラムが停止するたびに、dbx
は現在の関数の値をプログラムが停止した関数の値に再設定します。プログラムの停止後、その停止場所以外の関数やファイルを一時的に表示することができます。この章では、デバッグセッション中に
dbx
がどのようにコードを参照し、関数やシンボルを検索するかを説明します。また、コマンドを使用して、プログラムの停止位置とは別の場所のコードを一時的に表示したり、識別子、型、クラスの宣言を調べたりする方法も説明します。コード位置へのマッピング
dbx
は、プログラムに関連するソースファイルおよびオブジェクトコードファイルの位置を知っていなければなりません。オブジェクトファイルのデフォルトディレクトリは、プログラムが最後にリンクされたときにオブジェクトファイルがあったディレクトリです。ソースファイルのデフォルトディレクトリは、最後のコンパイル時にそれらが存在したディレクトリです。ソースファイルまたはオブジェクトファイルを移動したか、またはそれらを新しい位置にコピーした場合は、プログラムを再リンクするか、または新しい位置に変更してから、デバッグを行う必要があります。
ソースファイルまたはオブジェクトファイルを移動した場合、その新しい位置を検索パスに追加できます。
pathmap
コマンドは、ファイルシステムの現在のディレクトリと実行可能イメージ内の名前のマッピングを作成します。このマッピングは、ソースパスとオブジェクトファイルパスに適用されます。
ディレクトリ from から ディレクトリ to への新しいマッピングを確立するには、次のように入力します。
(dbx)
pathmap [-c]
from to
-c
を使用すると、このマッピングは、現在の作業ディレクトリにも適用されます。
pathmap
コマンドは、ホストによってベースパスの異なる、自動マウントされた明示的な NFS マウントファイルシステムを扱う場合でも便利です。-c
は、現在の作業ディレクトリが自動マウントされたファイルシステム上で不正確なオートマウンタが原因で起こる問題を解決する場合に使用してください。
/tmp_mnt
と/
のマッピングはデフォルトで存在します。詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「pathmap コマンド」を参照してください。
停止位置とは別の部分のコードを表示する
プログラムを実行していないときはいつでも、プログラム内の停止位置とは別の部分を表示できます。プログラムに含まれるすべての関数またはファイルを表示できます。
ファイルの内容を表示する
dbx
がプログラムの一部として認識していれば、どのファイルでもその内容を表示できます (モジュールまたはファイルが-g
オプションでコンパイルされていない場合でも可能です)。ファイルを表示した場合、関数は変更されません。ファイルの内容を表示するためには、次のように入力します。
(dbx)
file
filename
ファイルコマンドを単独で使用すると、現在表示中のファイル名が表示されます
(dbx)
file
dbx
は、行番号を指定しないと、最初の行からファイルを表示します。
(dbx)
file
filename ;
list
line_number関数を表示する
func
コマンドを使用すると、関数を表示することができます。コマンドfunc
に続けて、関数名を入力します。次の例を示します。
(dbx)
func adjust_speed
func
コマンドを単独で使用すると、現在表示中の関数が表示されます。あいまいな関数名をリストから選択する (C++)
C++ の場合、あいまいな名前または多重定義されている関数名を指定してメンバー関数を表示しようとすると、多重定義されているというメッセージが表示され、指定された名前を持つ関数のリストが示されます。
指定の関数があいまいな場合は、表示したい関数の番号を入力します。関数が属している特定クラスを知っている場合は、次のように入力することができます。
(dbx)
func block::block
複数存在する場合の選択
同じスコープレベルから複数のシンボルにアクセスできる場合、
dbx
は、あいまいさについて報告するメッセージを出力します。
(dbx)
func main
(dbx)
which C::foo
識別子 'foo' が複数あります以下の名前から 1 つ選択してください:0) Cancel1) `a.out`t.cc`C::foo(int)2) `a.out`t.cc`C::foo()>1`a.out`t.cc`C::foo(int)
which
コマンドのコンテキストでシンボル名のリストから特定のシンボルを選んでも、dbx
またはプログラムの状態には影響しません。いずれにせよ、どのシンボルを選んでも名前を表示するだけです。
which
コマンドは、dbx
がどのシンボルを検索するかを前もって示すものです。あいまいな名前を指定して、多重定義されていると表示された場合は、該当する複数の名前のうちのどれを使用するかがまだ特定されていません。リストに表示されている名前から 1 つを選んでください。詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「func コマンド」を参照してください。
ソースリストの出力
list
コマンドは、ファイルまたは関数のソースリストを出力するために使用します。filename を指定した場合は filename の先頭を表示、number を指定した場合は現在のファイルの number 行目を表示、function を指定した場合はその関数を表示します。
(dbx)
list [-i | -instr] [+] [-]
number
[
function|
filename]
詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「list コマンド」を参照してください。
呼び出しスタックの操作によってコードを表示する
プロセスが存在するときにコードを表示する方法としては、さらに「呼び出しスタックを操作する」方法があります。この方法では、
スタック操作
コマンドを使用して現在スタック上にある関数を表示します。スタックを操作すると、現在の関数とファイルは、スタック関数を表示するたびに変更されます。停止位置は、スタックの「底」にあるものと考えられます。したがって、そこから離れるには
up
コマンドを使用します。つまり、main
関数などに向かって移動します。現在のフレーム方向へ移動するには、down
コマンドを使用します。コールスタックのウォーキングについての詳細は、「スタックを移動してホームに戻る」を参照してください。
スコープ決定演算子を使用してシンボルを修飾する
func
またはfile
を使用する場合、スコープ決定演算子を使用して、ターゲットとして指定する関数の名前を修飾することができます。
dbx
では、シンボルを修飾するためのスコープ決定演算子として、逆引用符演算子 (`
) と C++ のスコープ決定演算子 (::
) 、ブロック局所演算子 (:lineno) を使用することができます。これらの演算子は別々に、ときには同時に使用します。停止位置以外の部分のコードを表示するためにファイルや関数の名前を修飾するだけでなく、スコープ外の変数や式の出力や表示を行なったり、型やクラスの宣言を表示したり (
whatis
コマンド) する場合にも、シンボルを修飾することが必要です。シンボルの修飾規則はすべての場合で同じです。この節で示す規則は、あらゆる種類のシンボル名の修飾に適用されます。逆引用符演算子
逆引用符演算子 (
`
) は、大域スコープの変数を検索するために使用できます。
(dbx)print `item
プログラムでは、同じ関数名を 2 つの異なるファイル (またはコンパイルモジュール) で使用できます。この場合、
dbx
に対しても関数名を修飾して、表示する関数を認識させる必要があります。ファイル名に関連して関数名を修飾するには、汎用逆引用符 (`
) スコープ決定演算子を使用してください。
(dbx)func `file_name`function_name
コロンを重ねたスコープ決定演算子 (C++)
次のような名前を持つ C++ のメンバー関数またはトップレベル関数を修飾するときには、コロンを 2 つ重ねた演算子 (
::
) を使用します。多重定義された関数名を修飾できます。多重定義された関数名を修飾しないと、
dbx
は多重定義表示リストを自動的に表示して、表示する関数を選択するよう要求します。関数のクラス名がわかっている場合は、それを二重コロンのスコープ決定演算子とともに使用して、名前を修飾できます。
(dbx)
func
class::function_name(
args)
たとえば、
hand
がクラス名でdraw
が関数名の場合は、次のようになります。
(dbx)
func
hand::drawブロックローカル演算子
ブロックローカル演算子 (:lineno) は、逆引用符演算子と組み合わせて使用します。これは、必要なインスタンスを参照する式の行番号を識別します。
(dbx)
stop in `animate.o`change_glyph:230`item
リンカー名
dbx
は、(C++ のようにさまざまな名前が混在するため)リンカー名ごとにシンボルを探すよう特別な構文を使用します。シンボル名の接頭辞として#
記号を付け、Korn シェルで$
記号の前にエスケープ文字\
を使用します。スコープ決定パス
dbx
固有コマンドにターゲットとして指定されたシンボルが検索を必要とするものである場合、dbx
はそのシンボルを次の順序で検索します。
- 最初に現在の関数のスコープ内で検索を行います。プログラムが、入れ子になったブロックで停止した場合はそのブロック内で検索した後、その関数によって宣言されている外側のすべてのブロックのスコープ内で検索します。
- C++ の場合のみ : 現在の関数クラスのクラスメンバーとその基底クラス。
- C++ の場合のみ : 現在のネームスペース。
- すぐ外側にある「コンパイル単位」: 一般に、現在の関数が含まれているファイル。
- ロードオブジェクトのスコープ。
- 大域的スコープ。
- 上記のすべてで該当するシンボルが見つからなかった場合は非公開変数、すなわちファイル内で「静的」な変数または関数と見なします。
dbxenv
によるscope_look_aside
の設定値によっては、コンパイル単位ごとにファイル静的シンボルを検索することもできます。
dbx
はこの検索パスで最初に見つけたシンボルを使用します。変数が見つからなかった場合はエラーを報告します。シンボルを検索する
同じ名前が多くの場所で使用されたり、プログラム内の異なる種類の構成要素を参照したりすることがあります。
dbx
コマンドwhereis
は、特定の名前を持つすべてのシンボルの完全修飾名 (すなわち位置) のリストを表示します。一方、dbx
コマンドwhich
は、特定の名前をdbx
コマンドのターゲットとしたときに、実際に使用されるシンボルを示します。シンボルの出現を出力する
指定シンボルの出現すべてのリストを出力するには、
whrereis
symbol を使用します。ここで、symbol は任意のユーザー定義識別子にすることができます。次に例を示します。
この出力には、プログラムがシンボルを定義する読み込み可能オブジェクトの名前が、各オブジェクトの構成要素の種類 (クラス、関数、または変数) とともに示されます。
dbx
シンボルテーブルの情報は必要に応じて読み取られるため、whereis
コマンドは、すでに読み込まれているシンボルの出現についてしか出力しません。デバッグセッションが長くなると、出現のリストは大きくなります。詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「whereis コマンド」を参照してください。
実際に使用されるシンボルを調べる
which
コマンドにより、特定の名前を (完全に修飾しないで) デバッグコマンドのターゲットとして指定したときにどのシンボルが使用されるかを前もって調べることができます。
(dbx)func
wedge::wedge(char*, int, int, const point&, load_bearing_block*)(dbx)which draw
`
block_draw.cc`
wedge::draw(unsigned long)
which
コマンドに指定したシンボル名が局所的スコープにない場合、スコープ決定パスで検索が行われます。決定パスで最初に見つかった名前の完全修飾名が示されます。決定パスに含まれる任意の場所で、同じスコープの該当するシンボルが複数見つかった場合、あいまいであることを示すメッセージが表示されます。
(dbx)
which fid
識別子 'foo' が複数あります以下の名前から 1 つ選択してください:0) Cancel1) `example`file1.c`fid2) `example`file2.c`fid
dbx
は、あいまいなシンボル名をリストで示し、多重定義であることを表示します。which
コマンドのコンテキストでシンボル名のリストから特定のシンボルを選んでも、dbx
またはプログラムの状態には影響しません。ほとんどの場合、どのシンボルを選んでも名前が表示されるだけです。
which
コマンドは、あるシンボル (この例の場合はblock
) をコマンド (たとえば、変数、メンバー、型、クラスを調べる
dbx
コマンドwhatis
は、識別子、構造体、型、C++ のクラス、式の型の宣言または定義を出力します。検査できる識別子には、変数、関数、フィールド、配列、列挙定数が含まれます。詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「whatis コマンド」および「C++ で使用される whatis コマンド」を参照してください。
変数、メンバー、関数の定義を調べる
(dbx)
whatis
identifier識別名は、必要に応じてファイルおよび関数情報によって修飾します。
C++ については、
whatis
identifier は、関数テンプレート例示をリストします。テンプレート定義は、whatis -t
identifier を付けて表示されます。 「型およびクラスの定義を調べる」を参照してください。
(dbx)whatis block::movable
int movable;
(dbx)whatis the_table
class table *the_table;
(dbx)whatis the_table->draw
void table::draw(unsigned long pw);メンバー関数で停止したときは、
this
ポインタを調べることができます。この例の場合、whatis
からの出力は、コンパイラがレジスタにthis
変数を自動的に割り当てたことを示しています。
型およびクラスの定義を調べる
whatis
コマンドの-t
オプションは、型を表示します。C++ については、whatis -t
で表示されるリストは、テンプレート定義およびクラステンプレート例示を含みます。型または C++ のクラスの宣言を出力するには次のようにします。
(dbx)whatis -t
type_or_class_name
whatis
コマンドには、継承されたメンバーを表示するための-r
(再帰) オプションが用意されています。このオプションを指定すると、指定したクラス class_name の宣言とともに、そのクラスが親クラスから継承したメンバーが表示されます。
(dbx)
whatis -t -r
class_name
whatis
-r
による出力は、クラス階層と各クラスのサイズによって長くなることがあります。出力の先頭には、階層の最も上にあるクラスから継承されたメンバーのリストが示されます。メンバーのリストは、コメント行によって親クラスごとに分けられます。ここに、2 つの例を示します。
table
クラスは、load_bearing_block
クラスの子クラスの 1 つです。また、load_bearing_block
クラスは、block
の子クラスです。
-r
を指定しないと、table
クラスで宣言されているメンバーが示されます。
次に、子クラスが継承するメンバーを表示するために
whatis
-r
がその子クラスで使用された場合の結果を示します。
自動読み取り機能の使用
通常、デバッグしたいプログラムは全体を
-g
オプションを使用して、コンパイルする必要があります。プログラムのコンパイル方法によって、各プログラムおよび共有ライブラリモジュールについて生成されるデバッグ情報は、各プログラムおよび共有ライブラリモジュールのオブジェクトコードファイル (.o
ファイル)、またはプログラム実行可能ファイルのいずれか、あるいはこの両方に保存されます。
-g -c
コンパイラオプションによってコンパイルを行うと、各モジュールのデバッグ情報は、その.o
ファイルに保存されます。dbx
は、各モジュールのデバッグ情報を必要に応じて、セッション中に自動的に読み取ります。この必要に応じた読み取り機能は、自動読み取り機能と呼ばれます。自動読み取り機能は、dbx
のデフォルト機能です。自動読み取り機能によって、大きなプログラムを
dbx
に読み込むときに時間を大幅に節約することができます。自動読み取り機能は、プログラム.o
ファイルが、dbx
に認識された位置に続けて存在することによって機能しています。dbx
の認識後に.o
ファイルを移動しないで下さい。
注 -.o
ファイル を.a
ファイルに保存してから、アーカイブライブラリを使用してリンクすると、関連の.o
ファイルを削除することができますが、.a
ファイルは削除できません。
デフォルトにより、
dbx
は、コンパイル時に記録された絶対パスを使用して、プログラムがコンパイルされたときのディレクトリのファイル、およびリンクされた位置での.o
ファイルを検索します。それらのファイルがない場合は、pathmap
コマンドを使用してサーチパスを設定します。オブジェクトファイルが作成されない場合、デバッグ情報は、実行可能ファイルに保存されます。つまり、
.o
ファイルを作成しないコンパイルの場合、コンパイラはすべてのデバッグ情報を実行可能ファイルに保存します。保存されたデバッグ情報は、-xs
オプションでコンパイルされたアプリケーションと同じ方法で読み取られます。「.o ファイルが存在しない場合のデバッグ」を参照してください。
.o
ファイルが存在しない場合のデバッグ
-g -c
オプションでコンパイルされたプログラムは、各モジュールのデバッグ情報を、そのモジュールの.o
ファイルに保存します。自動読み取り機能を使用するには、プログラムの
.o
ファイルと共有ライブラリの.o
ファイルが続けて存在している必要があります。デバッグしたいモジュールのプログラムの
.o
ファイルまたは共有ライブラリの.o
ファイルの維持が不可能な場合は、コンパイラの-xs
オプションを使用して (-g
オプションの後に付けます) プログラムをコンパイルします。-xs
でコンパイルしたモジュールと、このオプションを使わずにコンパイルしたモジュールが混在してもかまいません。-xs
オプションは、コンパイラのリンカーに、すべてのデバッグ情報を実行可能プログラムに配置するよう命令するオプションです。したがって、これらのモジュールをデバッグするのに、.o
ファイルの存在は必要ありません。
dbx
4.0 では、-xs
オプションでコンパイルされたモジュールのデバッグ情報は、dbx
の起動時に読み込まれます。そのため、-xs
でコンパイルされた大きなプログラムでは、dbx
の起動に時間がかかることがあります。
dbx
5.0 では、-xs
でコンパイルされたモジュールのデバッグ情報は、.o
ファイルに保存されたデバッグ情報と同様に遅延して読み込まれます。しかし、dbx
に、これらの情報を起動時に読み込むよう命令することができます。dbx
の環境変数delay_xs
を使用すれば、-xs
でコンパイルされたモジュールのデバッグ情報の読み込み遅延機能をオフにすることができます。この環境変数を設定するには、.dbxrc
ファイルに次の行を追加します。
dbxenv delay_xs off
Sun WorkShop デバッグの「デバッグオプション」ダイアログを使用して、この変数を設定することもできます。Sun WorkShop オンラインヘルプの「デバッグウィンドウの使い方」の「-xs を使ってコンパイルしたモジュールの読み込みを遅延する」を参照してください。
モジュールについてのデバッグ情報
module
コマンドおよびそのオプションは、デバッグセッション中、プログラムモジュールを追跡するのに役立ちます。module
コマンドを使用して、1 つまたはすべてのモジュールについてのデバッグ情報を読み込みます。通常dbx
は、必要に応じて、自動的にゆっくりとモジュールについてのデバッグ情報を読み込みます。1 つのモジュール name についてのデバッグ情報を読み込むには、次のように入力します。
(dbx)
module [-f] [-q]
nameすべてのモジュールについてのデバッグ情報を読み込むには、次のように入力します。
(dbx)
module [-f] [-q] -a
-f
ファイルが実行可能より新しい場合でも、デバッグ情報を強制的に読み込みます。 -q
静止モードを指定します。 -v
言語、ファイル名などを印刷する冗長モードを指定します。
(dbx)module
モジュールのリスト
modules
コマンドは、モジュール名をリストすることにより、モジュールを追跡することができます。すでに
dbx
に読み取られたデバッグ情報を含むモジュールの名前をリスト表示するには、次のように入力します。
(dbx)
modules [-v] -read
すべてのプログラムモジュール名 (デバッグ情報付き、またはなし) をリスト表示するには、次のように入力します。
(dbx)
modules [-v]
デバッグ情報付きのすべてのプログラムモジュール名をリスト表示するには、次のように入力します。
(dbx)
modules [-v] -debug
-v
言語、ファイル名などを出力する冗長モードを指定します。
サン・マイクロシステムズ株式会社 Copyright information. All rights reserved. |
ホーム | 目次 | 前ページへ | 次ページへ | 索引 |