異なるプログラミング言語であっても共通点があるのが普通ですが、
その表記法が全く同様であるということはめったにありません。
例えば、
ポインタ
p
の指す値を取り出す方法は、
ANSI Cでは*p
ですが、
Modula-2ではp^
です。
値の表現方法
(および表示方法)
もまた異なります。
16進数は、
Cでは`0x1ae'のようになりますが、
Modula-2では`1AEH'のようになります。
いくつかの言語については、
言語固有の情報がGDBに組み込まれており、
これにより、
プログラムを記述した言語を使って上記のような操作を記述したり、
プログラムを記述した言語の構文にしたがってGDBに値を出力させることができます。
式を記述するのに使用される言語を、
作業言語と呼びます。
作業言語を制御する方法は2つあります。
GDBに自動的に設定させる方法と、
ユーザが手作業で選択する方法です。
どちらの目的でも、
set language
コマンドを使用することができます。
起動時のデフォルトでは、
GDBが言語を自動的に設定するようになっています。
作業言語は、
ユーザの入力する式がどのように解釈されるか、
あるいは、
値がどのように表示されるかを決定します。
この作業言語とは別に、
GDBの認識しているすべてのソース・ファイルには、
それ自体の作業言語があります。
オブジェクト・ファイルのフォーマットによっては、
ソース・ファイルの記述言語を示す情報を、
コンパイラが書き込んでいることがあるかもしれません。
しかし、
ほとんどの場合、
GDBはファイル名から言語を推定します。
ソース・ファイルの言語の種類が、
C++シンボル名がデコード
(demangle)
されるか否かを制御します。
これによりbacktrace
は、
個々のフレームを、
その対応する言語にしたがって適切に表示することができます。
GDBの中から、
ソース・ファイルの言語を設定することはできません。
他の言語で記述されたソースからCのソースを生成する、
cfront
やf2c
のようなプログラムをユーザが使用する場合には、
このことが問題となるでしょう。
このような場合には、
生成されるCの出力に#line
指示子を使用するよう、
そのプログラムを設定してください。
こうすることによって、
GDBは、
元になったプログラムのソース・コードが記述された言語を正しく知ることができ、
生成されたCのコードではなく、
元になったソース・コードを表示します。
ソース・ファイル名が以下のいずれかの拡張子を持つ場合、 GDBはその言語を以下に示すものと推定します。
さらに、 言語に対してファイル名の拡張子を関連付けすることも可能です。 言語の表示を参照してください。
GDBに言語を自動的に設定させる場合、
ユーザのデバッグ・セッションとユーザのプログラムにおいて、
式は同様に解釈されます。
もしそうしたければ、
言語を手作業で設定することもできます。
そのためには、
コマンド`set language lang'を実行します。
ここで、
langは、
c
やmodula-2
のような言語名です。
サポートされている言語のリストは、
`set language'で表示させることができます。
言語を手作業で設定すると、
GDBは、
作業言語を自動的に更新することができなくなります。
このことは、
作業言語がソースの言語と同一ではなく、
かつ、
ある式がどちらの言語でも有効でありながら、
その意味が異なるような状況でプログラムをデバッグしようとしたときに、
混乱をもたらす可能性があります。
例えば、
カレントなソース・ファイルがC言語で記述されていて、
GDBがそれをModula-2として解析している場合に、
print a = b + c
のようなコマンドを実行すると、
その結果は意図したものとは異なるものになるでしょう。
これはC言語では、
b
とc
とを加算して、
その結果をa
に入れるということを意味し、
表示される結果は、
a
の値となります。
Modula-2では、
これはa
とb+c
の結果を比較してBOOLEAN
型の値を出力することを意味します。
GDBに作業言語を自動的に設定させるには、 `set language local'または`set language auto'を使用します。 この場合、 GDBは作業言語を推定します。 つまり、 ユーザ・プログラムが (通常はブレイクポイントに達することによって) あるフレーム内部で停止したとき、 GDBは、 そのフレーム内の関数に対して記録されている言語を作業言語として設定します。 フレームの言語が不明の場合 (つまり、 そのフレームに対応する関数またはブロックが、 既知ではない拡張子を持つソース・ファイルにおいて定義されている場合)、 カレントな作業言語は変更されず、 GDBは警告メッセージを出力します。 このようなことは、 全体がただ1つの言語で記述されているほとんどのプログラムにおいては 不要であると思われるでしょう。 しかし、 あるソース言語で記述されたプログラム・モジュールやライブラリは、 他のソース言語で記述されたメイン・プログラムから使用することができます。 このような場合に`set language auto'を使用することで、 作業言語を手作業で設定する必要がなくなります。
以下のコマンドは、 作業言語、 および、 ソース・ファイルの記述言語を知りたいときに役に立ちます。
show language
print
コマンドなどによって
ユーザ・プログラム内部の変数を含む式を作成したり評価したりするには、
このコマンドによって示される言語を使用します。
info frame
info source
普通ではない状況においては、 標準のリストに含まれない拡張子を持つソース・ファイルがあるかもしれません。 この場合には、 その拡張子を特定の言語に明示的に関連付けすることができます。
set extension-language .ext language
info extensions
注意: 現在のリリースでは、 型チェックと範囲チェックを行うGDBコマンドは組み込まれていますが、 それらは実際には何も実行しません。 このセクションでは、 これらのコマンドが本来持つべく意図されている機能について記述してあります。
いくつかの言語は、
一連のコンパイル時チェック、
実行時チェックによって、
一般によく見られるエラーの発生を防ぐように設計されています。
これらのチェックには、
関数や演算子への引数の型のチェックや、
数学的操作の結果のオーバーフローを実行時に確実に検出することなどが含まれています。
このようなチェックは、
型の不一致を排除したり、
ユーザ・プログラムの実行時に範囲エラーをチェックしたりすることによって、
コンパイル後のプログラムの正しさを確かなものにするのに役に立ちます。
GDBは、
ユーザが望むのであれば、
上記のような条件のチェックを行います。
GDBはユーザ・プログラムの文をチェックすることはしませんが、
例えば、
print
コマンドによる評価を目的としてGDBに直接入力された式をチェックすることはできます。
作業言語の場合と同様に、
GDBが自動的にチェックを行うか否かを、
ユーザ・プログラムのソース言語によって決定することもできます。
サポートされている言語のデフォルトの設定については、
サポートされる言語を参照してください。
いくつかの言語、 例えばModula-2などは、 強く型付けされています。 これは、 演算子や関数への引数は正しい型でなくてはならず、 そうでない場合にはエラーが発生するということを意味しています。 このようなチェックは、 型の不一致のエラーが実行時に問題を発生させるのを防いでくれます。 例えば、 1+2は
1 + 2 => 3 ですが、1+2.3は error--> 1 + 2.3
のようにエラーになります。
第2の例がエラーになるのは、
CARDINAL
型の1はREAL
型の2.3と型の互換性がないからです。
GDBコマンドの中で使われる式については、
ユーザがGDBの型チェック機能に対して、
以下のような指示を出すことができます。
最後の指示が選択された場合、
GDBは上記の第2の(エラー)例のような式でも評価しますが、
その際には警告メッセージを出力します。
型チェックをしないよう指示した場合でも、
型に関係のある原因によってGDBが式の評価ができなくなる場合がありえます。
例えば、
GDBはint
の値とstruct foo
の値を加算する方法を知りません。
こうした特定の型エラーは、
使用されている言語に起因するものではなく、
この例のように、
そもそも評価することが意味をなさないような式に起因するものです。
個々の言語は、
それが型に関してどの程度厳密であるかを定義しています。
例えば、
Modula-2とCはいずれも、
算術演算子への引数としては数値を要求します。
Cでは、
列挙型とポインタは数値として表わすことができますので、
これらは算術演算子への正当な引数となります。
特定の言語に関する詳細については、
サポートされる言語を参照してください。
GDBは、
型チェック機能を制御するためのコマンドをさらにいくつか提供しています。
set check type auto
set check type on
set check type off
set check type warn
show type
いくつかの言語 (例えば、 Modula-2) では、 型の上限を超えるとエラーになります。 このチェックは、 実行時に行われます。 このような範囲チェックは、 計算結果がオーバーフローしたり、 配列の要素へのアクセス時に使うインデックスが配列の上限を超えたりすることがないことを確実にすることによって、 プログラムの正しさを確かなものにすることを意図したものです。 GDBコマンドの中で使う式については、 範囲エラーの扱いを以下のいずれかにするよう GDBに指示することができます。
範囲エラーは、 数値がオーバフローした場合、 配列インデックスの上限を超えた場合、 どの型のメンバでもない定数が入力された場合に発生します。 しかし、 言語の中には、 数値のオーバフローをエラーとして扱わないものもあります。 C言語の多くの実装では、 数学的演算によるオーバフローは、 結果の値を「一巡」させて小さな値にします。 例えば、 mが整数値の最大値、 sが整数値の最小値とすると、
m + 1 => s
になります。 これも個々の言語に固有な性質であり、 場合によっては、 個々のコンパイラやマシンに固有な性質であることもあります。 特定の言語に関する詳細については、 サポートされる言語を参照してください。 GDBは、 範囲チェック機能を制御するためのコマンドをさらにいくつか提供しています。
set check range auto
set check range on
set check range off
set check range warn
show range
GDBは、
C、
C++、
Fortran、
Chill、
アセンブリ言語、
Modula-2をサポートしています。
いくつかのGDBの機能は、
使用されている言語にかかわらず、
式の中で使用できます。
GDBの@
演算子、
::
演算子、
および`{type}addr'
(式を参照)
は、
サポートされている任意の言語において使用することができます。
次節以降で、
個々のソース言語がGDBによってどの程度までサポートされているのかを詳しく説明します。
これらの節は、
言語についてのチュートリアルやリファレンスとなることを意図したものではありません。
むしろ、
GDBの式解析機能が受け付ける式や、
異なる言語における正しい入出力フォーマットのリファレンス・ガイドとしてのみ役に立つものです。
個々の言語については良い書籍が数多く出ています。
言語についてのリファレンスやチュートリアルが必要な場合は、
これらの書籍を参照してください。
CとC++は密接に関連しているので、
GDBの機能の多くは両方の言語に適用できます。このようなものについては、2つの言語を一緒に議論します。
C++のデバッグ機能は、
C++コンパイラとGDBによって協同で実装されています。
したがって、
C++のコードを効率よくデバッグするには、
GNU g++
、
HP ANSI C++コンパイラ(aCC
)などの、
サポートされているC++コンパイラで、
C++のプログラムをコンパイルする必要があります。
GNU C++を使用する場合、
最高の結果を引き出すには、
stabsデバッグ・フォーマット
を使用してください。
g++
のコマンドライン・オプション`-gstabs'、
または、
`-gstabs+'によって、
このフォーマットを明示的に選択することができます。
詳細については、
Using GNU CCの`Options for Debugging Your Program or GNU CC'
の部分を参照してください。
演算子は、
特定の型の値に対して定義されなければなりません。
例えば、
+
は数値に対しては定義されていますが、
構造体に対しては定義されていません。
演算子は、
型のグループに対して定義されることがよくあります。
C/C++に対しては、以下の定義が有効です。
int
が含まれます。
char
、
enum
も整数型です。
float
とdouble
が含まれます。
(type *)
により定義されるすべての型が含まれます。
以下の演算子がサポートされています。 これらは優先順位の低いものから順に並べられています。
,
=
op=
a op= b
という形式の式において使用され、
a = a op b
に変換されます。
op=
と=
は、
同一の優先順位を持ちます。
opには、
|
、
^
、
&
、
<<
、
>>
、
+
、
-
、
*
、
/
、
%
の各演算子が使用できます。
?:
a ? b : c
は、
aが真であればb、
偽であればcとみなすことができます。
aは整数型でなければなりません。
||
&&
|
^
&
==、!=
<、>、<=、>=
<<、>>
@
+、-
*、/、%
++, --
*
++
と同一の優先度を持ちます。
&
++
と同一の優先順位を持ちます。
C++のデバッグでは、
C++言語そのものにおいては許されていないような`&'の使用法を、
GDBは実装しています。
C++の
(`&ref'により宣言される)
参照変数が格納されているアドレスを調べるのに、
`&(&ref)'
(あるいは、
もしそうしたいのであれば単に`&&ref')
を使用することができます。
-
++
と同一の優先順位を持ちます。
!
++
と同一の優先順位を持ちます。
~
++
と同一の優先順位を持ちます。
., ->
struct
)
および共用体
(union
)
に対して定義されています。
[]
a[i]
は、
*(a+i)
として定義されています。
->
と同一の優先順位を持ちます。
()
->
と同一の優先順位を持ちます。
::
struct
)、
共用体(union
)、
クラス(class
)に対して定義されています。
::
::
と同一の優先順位を持ちます。
GDBでは、 以下のような方法によって、 C/C++の定数を表わすことができます。
long
型の値として扱われるべきことを意味します。
'
)
によって囲まれた単一の文字、
あるいは、
その文字に対応する序数
(通常は、
ASCII値)
です。
引用符の中の単一文字は、
文字またはエスケープ・シーケンスによって表わすことができます。
エスケープ・シーケンスには2つの表記方法があります。
第1の形式は`\nnn'で、
nnnはその文字の序数を表わす8進数です。
第2の形式は`\x'で、
`x'はあらかじめ定義された特別な文字です。
例えば、
`\n'は改行を表わします。
"
)
で囲まれたものです。
GDBが持っている、 式を処理する機能は、 C++のほとんどの式を解釈することができます。
注意: GDBは、 適切なコンパイラが使用されている場合のみ、 C++のコードをデバッグすることができます。 典型的な例を挙げると、 C++のデバッグでは、 シンボル・テーブルの中の追加的なデバッグ情報に依存するため、 特別なサポートが必要になるということがあります。 使用されるコンパイラが、 a.out、 MIPS ECOFF、 RS/6000 XCOFF、 ELFを、 シンボル・テーブルに対するstabs拡張付きで生成することができるのであれば、 以下に列挙する機能を使用することができます (GNU CCの場合は、 `-gstabs'オプションを使用して明示的にstabsデバッグ拡張を要求することができます)。 一方、 オブジェクト・コードのフォーマットが、 標準COFFやELFのDWARFである場合には、 GDBの提供するほとんどのC++サポートは機能しません。
count = aml->GetOriginal(x, y)
this
への暗黙の参照を許します。
::
をサポートしています。
プログラム中と同様に、
式の中でこれを使用することができます。
あるスコープが別のスコープの中で定義されることがありえるため、
必要であれば::
を繰り返し使用することができます。
例えば、
`scope1::scope2::name'という具合です。
GDBはまた、
CおよびC++のデバッグにおいて、
ソース・ファイルを指定することで名前のスコープを解決することを許します
(プログラム変数を参照)。
GDBが自動的に型チェックや範囲チェックの設定を行うことを許すと、
作業言語がCやC++に変更されるときにはいつも、
それらの設定はデフォルトでoff
になります。
これは、
作業言語を選択したのがユーザであってもGDBであっても同様です。
GDBが自動的に言語の設定を行うことを許すと、
GDBは、
名前が`.c'、
`.C'、
`.cc'などで終わるソース・ファイルを認識していて、
これらのファイルからコンパイルされたコードの実行を開始するときに、
作業言語をCまたはC++に設定します。
詳細については、
GDBによるソース言語の推定を参照してください。
デフォルトでは、 GDBがCやC++の式を解析するときには、 型チェックは行われません。 しかし、 ユーザが型チェックを有効にすると、 GDBは以下の条件が成立するときに、 2つの変数の型が一致しているとみなします。
typedef
によって同一の型に宣言されている型を持つ。
範囲チェックは、 onに設定されている場合、 数学的演算において実行されます。 配列のインデックスは、 それ自体は配列ではないポインタのインデックスとして使用されることが多いため、 チェックされません。
set print union
コマンドとshow print union
コマンドは共用体型
(union
)
に適用されます。
`on'に設定されると、
構造体
(struct
)
やクラス
(class
)
の内部にある共用体
(union
)
はすべて表示されます。
`on'でない場合、
それは`{...}'と表示されます。
@
オペレータは、
ポインタとメモリ割り当て関数によって作られた動的配列のデバッグに役に立ちます。
式を参照してください。
GDBのコマンドの中には、 C++を使用しているときに特に役に立つものがあり、 また、 C++専用に特に設計されたものがあります。 以下に、 その要約を示します。
breakpoint menus
rbreak regex
catch throw
catch catch
ptype typename
set print demangle
show print demangle
set print asm-demangle
show print asm-demangle
set print object
show print object
set print vtbl
show print vtbl
オーバーロードされたシンボル名
symbol(types)
と入力してください。
GDBコマンドラインの単語補完機能を使用して、
利用可能な選択肢を一覧表示させたり、
型のリストを完結させたりすることができます。
この機能の使用方法の詳細については、
コマンド名の補完を参照してください。
Modula-2をサポートするために開発されたGDBの拡張機能は、 (現在開発中の) GNU Modula-2コンパイラによって生成されたコードだけをサポートします。 他のModula-2コンパイラは現在サポートされていません。 他のModula-2コンパイラが生成した実行形式モジュールをデバッグしようとすると、 おそらく、 GDBが実行モジュールのシンボル・テーブルを読み込もうとしたところでエラーになるでしょう。
演算子は、
特定の型の値に対して定義されなければなりません。
例えば、
+
は数値に対して定義され、
構造体に対しては定義されません。
演算子は、
型のグループに対して定義されることがよくあります。
Modula-2においては、
以下の定義が有効です。
INTEGER
、
CARDINAL
、
およびそのサブ範囲
(subrange)
から成ります。
CHAR
とそのサブ範囲から成ります。
REAL
から成ります。
POINTER TO type
のように宣言された任意の型から成ります。
SET
、
BITSET
から成ります。
BOOLEAN
から成ります。
以下の演算子がサポートされています。 ここでは、 優先順位の低いものから順に並べています。
,
:=
:=
valueの値は
valueです。
<、>
<=、>=
<
と同一の優先順位を持ちます。
=、<>、#
<
と同一の優先順位を持ちます。
GDBスクリプトの中では、
#
がスクリプトのコメント記号でもあるため、
不等価としては<>
だけが使用可能です。
IN
<
と同一の優先順位を持ちます。
OR
AND、&
@
+、-
*
/
*
と同一の優先順位を持ちます。
DIV、MOD
*
と同一の優先順位を持ちます。
-
INTEGER
、
REAL
型のデータに対して定義されています。
^
NOT
^
と同一の優先順位を持ちます。
.
RECORD
フィールドの区切り記号です。
RECORD
データに対して定義されます。
^
と同一の優先順位を持ちます。
[]
ARRAY
型のデータに対して定義されています。
^
と同一の優先順位を持ちます。
()
PROCEDURE
オブジェクトに対して定義されています。
^
と同一の優先順位を持ちます。
::、.
注意: 集合、 および集合に対する操作は、 まだサポートされていません。 このため、 GDBは
IN
演算子、 あるいは、 集合に対して+
、-
、*
、/
、=
、<>
、#
、<=
、>=
のいずれかの演算子が使用された場合、 これをエラーとして扱います。
Modula-2では、 いくつかの組み込みプロシージャ、 組み込み関数が使用できます。 これらの説明にあたり、 以下のメタ変数を使用します。
ARRAY
型の変数を表わします。
CHAR
型の定数、
または変数を表わします。
SET OF mtype
でなければなりません
(ここでのmtypeはmの型です)。
また、 すべてのModula-2の組み込みプロシージャは、 以下に説明する値を返します。
ABS(n)
CAP(c)
CHR(i)
DEC(v)
DEC(v,i)
EXCL(m,s)
FLOAT(i)
HIGH(a)
INC(v)
INC(v,i)
INCL(m,s)
MAX(t)
MIN(t)
ODD(i)
TRUE
を返します。
ORD(x)
SIZE(x)
TRUNC(r)
VAL(t,i)
注意: 集合、 および集合に対する操作はまだサポートされていません。 したがって、
INCL
プロシージャ、EXCL
プロシージャを使用すると、 GDBはエラーとして扱います。
GDBでは、 Modula-2の定数を以下のような方法で表現することができます。
'
)または2重引用符("
)で囲まれた単一文字より成ります。
文字型定数は、
その文字の序数値
(通常はASCII値)
の後ろに`C'を付加することで表現することもできます。
'
)または2重引用符("
)で囲まれた連続する文字から成ります。
C言語のスタイルでのエスケープ・シーケンスも使用できます。
エスケープ・シーケンスに関する簡単な説明については、
C/C++定数を参照してください。
TRUE
およびFALSE
から成ります。
型チェックと範囲チェックがGDBにより自動的に設定される場合、
作業言語がModula-2に変わるたびに、
それらはデフォルトでon
に設定されます。
これは、
作業言語を選択したのがユーザであろうとGDBであろうと同様です。
GDBに自動的に言語を設定させると、
ファイル名の末尾が`.mod'であるファイルからコンパイルされたコードに入るたびに、
作業言語はModula-2に設定されます。
詳細については、
GDBによるソース言語の推定を参照してください。
Modula-2プログラムのデバッグを容易にするために2、 3の修正が施されています。 これは主に、 型に対する厳密性を緩めることによって実現されています。
:=
)
は、
右側の引数の値を返します。
注意: GDBは現在のところ、 型チェック、 範囲チェックをまだ実装していません。
GDBは、 以下のいずれかの条件が成立するとき、 2つのModula-2変数の型が等しいとみなします。
TYPE t1 = t2
文によって等しいと宣言されている型である。
型チェックが有効である限り、 等しくない型の変数を組み合わせようとする試みはすべてエラーとなります。 範囲チェックは、 数学的操作、 代入、 配列のインデックス境界、 およびすべての組み込み関数、 組み込みプロシージャにおいて実行されます。
::
と.
Modula-2のスコープ演算子
(.
)
とGDBのスコープ演算子
(::
)
との間には2、
3の微妙な相違点があります。
この2つは似た構文を持っています。
module . id scope :: id
ここで、
scopeはモジュール名またはプロシージャ名、
moduleはモジュール名、
idはユーザ・プログラムの中で宣言された任意の
(異なるモジュール以外の)
識別子です。
::
演算子を使用すると、
GDBはscopeによって指定されたスコープにおいて識別子idを探します。
指定されたスコープにおいてそれを見つけることができないと、
GDBはscopeによって指定されたスコープを包含するすべてのスコープを探します。
.
演算子を使用すると、
GDBはカレントなスコープにおいて、
modueによって指定された定義モジュールから取り込まれた、
idによって指定される識別子を探します。
この演算子では、
識別子idが定義モジュールmoduleから取り込まれていない場合やmoduleにおいてidが識別子でない場合は、
エラーになります。
GDBコマンドの中には、
Modula-2プログラムのデバッグにはほとんど役に立たないものがいくつかあります。
set print
、
show print
の5つのサブ・コマンド`vtbl'、
`demangle'、
`asm-demangle'、
`object'、
`union'はC/C++にのみ適用されます。
最初の4つはC++に適用され、
最後の1つはCの共用体
(union
)
に適用されます。
これらは、
Modula-2において直接類似するものが存在しません。
@
演算子
(式を参照)
は、
どの言語においても使用することができますが、
Modula-2においてはあまり役に立ちません。
この演算子は、
動的配列のデバッグを支援することを目的とするものですが、
C/C++では作成できる動的配列は、
Modula-2では作成できません。
しかし、
整数値定数によってアドレスを指定することができるので、
`{type}adrexp'は役に立ちます
(式を参照)。
GDBスクリプトの中では、
Modula-2の不等価演算子#
はコメントの開始記号として解釈されます。
代わりに<>
を使用してください。