通常、
プログラミング言語というものは共通点を持つものですが、
その表記法が全く同様であるということはめったにありません。
例えば、
ポインタ
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
注意: 現在のリリースでは、 型および範囲のチェックを行う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 4は、C、C++、Modula-2
をサポートしています。
いくつかのGDBの機能は、
使用されている言語にかかわらず、
式の中で使用できます。
GDBの@
演算子、
::
演算子、
および`{type}addr'
(式を参照)
は、
サポートされている任意の言語において使用することができます。
次節以降で、
個々のソース言語がGDBによってどの程度までサポートされているのかを詳しく説明します。
これらの節は、
言語についてのチュートリアルやリファレンスとなることを意図したものではありません。
むしろ、
GDBの構文解析機能が受け付ける式や、
異なる言語における正しい入出力フォーマットのリファレンス・ガイドとしてのみ役に立つものです。
個々の言語については良い書籍が数多く出ています。
言語リファレンスやチュートリアルが必要な場合は、
これらの書籍を参照してください。
CとC++は密接に関連しているので、
GDBの機能の多くは両方の言語に適用できます。このようなものについては、2つの言語を一緒に議論します。
C++のデバッグ機能は、
GNU C++コンパイラとGDBによって協同で実装されています。
したがって、
C++のコードを効率よくデバッグするには、
C++のユーザ・プログラムを
GNU C++コンパイラg++
でコンパイルする必要があります。
C++プログラムのデバッグ時に最高の結果を引き出すには、
スタブ・デバッグ・フォーマットを使用してください。
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ではGNU C++コンパイラでコンパイルされたC++コードしかデバッグできません。 さらに、 C++のデバッグはシンボル・テーブルの中の追加的なデバッグ情報の使用に依存するため、 特別なサポートが必要です。 GDBはこのようなサポートをスタブ・デバッグ・フォーマットでのみ手に入れることができます。 使用されるコンパイラがa.out、 MIPS ECOFF、 RS/6000 XCOFF、 ELFを、 シンボル・テーブルへのスタブ拡張付きで生成することができるのであれば、 これらの機能を使用することができます (GNUの場合は、 `-gstabs'オプションを使用して明示的にスタブ・デバッグ拡張を要求することができます)。 一方、 オブジェクト・コードのフォーマットが標準COFFやDWARFのELFである場合には、 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 exceptions
info 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
でなければなりません。
また、 すべての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の不等価#
はコメントの開始記号として解釈されます。
代わりに<>
を使用してください。