[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.7 読者のプログラムや GCC をデバッグするためのオプション

GCC には色々特別なオプションがあって、ユーザのプログラムや GCC 自体を デバッグするのに使われる。

-g

デバッグ情報をオペレーティングシステム固有の形式(stabs、 COFF、 XCOFF、 あるいは DWARF)で生成する。 GDB は、このデバッグ情報を使うと動作するようになる。

stabs 形式を使っているほとんどのシステムで、‘-g’ を指定すると、 GDB だけが使うことのできる特別のデバッグ情報を使うようになる。 この特別な情報は GDB の場合にはデバッグをしやすくするが、 他のデバッガを使う場合は、おそらく、デバッガが落ちたり、プログラムを 読み込めなくなってしまうだろう。 特別な情報を生成するかどうかをある程度制御したい場合は、 ‘-gstabs+’、‘-gstabs’、‘-gxcoff+’、‘-gxcoff’、 ‘-gdwarf-1+’、‘-gdwarf-1’ を使うこと(後述参照)。

他の多くの C コンパイラと違って、GCC では ‘-g’ を ‘-O’ と一緒に使うことができる。最適化されたコードによるショートカットの ため、以下のように、驚くような結果が時々出るが。 宣言したはずの変数が全く存在しないことがある。 制御の流れが、簡単に言えば、予想していない場所に移動してしまうことがある。 文の中には実行されないものも出てくる。それらの文が、既に入手済みの 一定の結果や値を計算しているからである。 文の中には別の場所で実行されるものもある。ループの外に移動したからである。

それにもかかわらず、最適化された出力をデバッグすることは可能である。 このため、バグがあるかもしれないプログラムを最適化することが妥当なことに なる。

GCC が複数のデバッグ情報を扱えるように生成されているときは 以下のオプションが役に立つ。

-ggdb

GDB で使用するデバッグ情報を生成する。 これは、利用可能な形式のうち最も表現力のあるものを使うということを 意味する。これには、可能な限りの GDB 向け拡張も含まれる。

-gstabs

stabs 形式のデバッグ情報(サポートされていれば)を GDB 向け拡張なしで 生成する。この形式が、ほとんどの BSD システムの DBX で使われるものである。 MIPS、Alpha、System V Release 4 のシステムでは、 このオプションは、DBX や SDB が理解できない形式の stabs デバッグ情報を 生成する。System V Release 4 のシステムでこのオプションを使うには GNU assembler が必要である。

-gstabs+

stabs 形式のデバッグ情報(サポートされていれば)を、GNU debugger (GDB) だけが 理解できる GNU 拡張付きで生成する。 この拡張を使うと、他のデバッガは落ちたり、プログラムを読み込めなくなったり する。

-gcoff

デバッグ情報を COFF 形式(サポートされていれば)で生成する。 これは、System V Release 4 以前の System V 上の SDB で使われていた形式である。

-gxcoff

デバッグ情報を XCOFF 形式(サポートされていれば)で生成する。 これは、IBM の RS/6000 システム上の DBX デバッガで使われている形式である。

-gxcoff+

デバッグ情報を XCOFF 形式(サポートされていれば)で、 GNU デバッガ(GDB) だけが理解できる GNU の拡張付きで生成する。 この拡張を使うと、他のデバッガは落ちたり、プログラムを読み込めなくなったり する。 また、GNU assembler (GAS) 以外のアセンブラだとエラーが出て失敗する。

-gdwarf

デバッグ情報を DWARF のバージョン1の形式(サポートされていれば)で 生成する。これは、System V Release 4 のシステム上の SDB で使われている 形式である。

-gdwarf+

デバッグ情報を DWARF のバージョン1の形式(サポートされていれば)で、 GNU debugger (GDB) だけが理解できる GNU の拡張付きで生成される。 この拡張を使うと、他のデバッガは落ちたり、プログラムを読み込めなくなったり する。

-gdwarf-2

デバッグ情報を DWARF のバージョン2の形式(サポートされていれば)で 生成する。これは、IRIX 6 上の DBX で使われている形式である。

-glevel
-ggdblevel
-gstabslevel
-gcofflevel
-gxcofflevel
-gdwarflevel
-gdwarf-2level

デバッグ情報を出すことを要求し、かつ、 level で どれぐらいの情報を出すかを指定する。 デフォルトのレベルは 2 である。

レベル 1 は、デバッグする予定のないプログラムの一部の バックトレースが取れるぐらいの、最小限の情報を生成する。 この情報には、関数と外部変数の記述が含まれるが、ローカル変数と行番号に ついての情報は含まれない。

レベル 3 は余分の情報を含める。例えば、プログラムに存在する 全てのマクロ定義などが含まれる。 デバッガの中には、‘-g3’ を使った場合にマクロの展開をサポートするものも ある。

-p

prof プログラムによる解析に適したプロファイル情報を書き出す 余分のコードを生成する。 このオプションは、データを必要とするソースファイルをコンパイルするときに 指定しなければならない。また、リンク時にも指定しなければならない。

-pg

gprof プログラムによる解析に適したプロファイル情報を書き出す 余分のコードを生成する。 このオプションは、データを必要とするソースファイルをコンパイルするときに 指定しなければならない。また、リンク時にも指定しなければならない。

-a

基本ブロックに関するプロファイル情報を書き出す余分のコードを生成する。 このコードは、各基本ブロックが実行された回数、基本ブロックの開始アドレス、 その基本ブロックを含む関数名を記録する。 ‘-g’ が指定されていると、基本ブロックの開始点の行番号とファイル名も 記録される。マシン記述で上書きされていない限り、 デフォルトの動作はテキストファイル ‘bb.out’ に追加することである。

このデータは、tcov のようなプログラムで解析することができる。 だが、このデータの形式は tcov が想定しているものでないことに 注意すること。将来的には GNU gprof を、このデータを 処理できるように拡張する必要があるだろう。

-Q

各関数のコンパイルが終わる毎にその関数名を出力し、 各パスが終了したときにそのパスについての統計情報を出力する。

-ax

基本ブロックプロファイル用の余分なコードを生成する。 実行形式を実行すると、‘-a’ が指定されたときに生成されるものの スーパーセットが出力される。 出力に付け加わるのは、ジャンプが起きたところの基本ブロックの ジャンプ元とジャンプ先のアドレスと、ジャンプの実行回数、 それにオプションで実行される基本ブロックの完全な列である。 出力は、ファイル ‘bb.out’ に追加される。

再コンパイルしなくても異なるプロファイリングの面を試すことができる。 実行形式ファイルは、ファイル ‘bb.in’ から関数名のリストを読み込む。 プロファイリングは、リストにある関数に入った時点で開始し、 その関数の実行が終わった点で終了する。 プロファリングから関数を除外する場合は、その名前の前に `-' を付ける。 関数名が一意的でない場合は、‘/path/filename.d:functionname’ という 形式で書くことで区別できる。 実行形式ファイルの実行により、利用可能なパス名とファイル名が ファイル ‘bb.out’ に書き出される。

幾つかの関数名には特別な意味がある。

__bb_jumps__

ジャンプ元、ジャンプ先、ジャンプの頻度をファイル ‘bb.out’ に書き出す。

__bb_hidecall__

頻度の計数から関数呼び出しを除外する。

__bb_showret__

頻度の計数に関数からの戻りを含める。

__bb_trace__

実行された基本ブロックの列をファイル ‘bbtrace.gz’ に書き出す。 このファイルは ‘gzip’ プログラムを使って圧縮されるので、 ‘gzip’ が PATH に入っていなければならない。 ‘popen’ 関数のないシステムでは、このファイルは ‘bbtrace’ という 名前になり、圧縮は行なわれない。 そういうシステムでは、ほんの数秒のプロファイリングでも、 非常に巨大なファイルができる。 注意: __bb_hidecall____bb_showret__ は ‘bbtrace.gz’ に書き出される列には影響しない。

以下に、ファイル ‘bb.in’ で異なるプロファイリングパラメータを 使った短い例を示す。関数 foo には、基本ブロック 1 と 2 があり、 関数 main のブロック 3 から二回呼び出されるとする。 その呼び出しの後、ブロック 3 は制御を main のブロック 4 に移す。

__bb_trace__main をファイル ‘bb.in’ に 入れておくと、0 3 1 2 1 2 4 というブロック列が ファイル ‘bbtrace.gz’ に書き出される。 ブロック 2 からブロック 3 へ戻るのは示されていない。 これは、ブロックの中のある点へ戻るためで最上位に戻るのではないからである。 ブロックアドレス 0 は常に、制御が測定した関数のどこか外側から、トレースに 移ったことを意味する。 ‘-foo’ を ‘bb.in’ に入れると、関数 foo のブロックは トレースから除かれるので、0 3 4 だけが残る。

__bb_jumps__main をファイル ‘bb.in’ に 入れると、ジャンプの頻度がファイル ‘bb.out’ に書き出される。 頻度は、ブロックのトレースを構成し、トレース中の隣り合わせのブロックの 対毎にカウンタをインクリメントすることで得られる。 トレース 0 3 1 2 1 2 4 は以下の列を表示する。

 
Jump from block 0x0 to block 0x3 executed 1 time(s)
Jump from block 0x3 to block 0x1 executed 1 time(s)
Jump from block 0x1 to block 0x2 executed 2 time(s)
Jump from block 0x2 to block 0x1 executed 1 time(s)
Jump from block 0x2 to block 0x4 executed 1 time(s)

__bb_hidecall__ を置くと、呼出し命令による制御の移動は トレースから取り除かれる。すなわち、トレースは三つの部分に分けられる。 0 3 4 と 0 1 2、それに 0 1 2 である。 __bb_showret__ を置くと、リターン命令による制御の移動が トレースに追加される。トレースは、0 3 1 2 3 1 2 3 4 になる。 このトレースは、‘bbtrace.gz’ に書き出される列とは 同じでないことに注意。これは、ジャンプの頻度を数えるのにしか使われない。

-fprofile-arcs

コンパイル中に 弧(arc) を操作する。 プログラムの関数毎に GCC は、一個のプログラムの流れのグラフを 作り、そのグラフのスパニング・ツリーを探す。スパニング・ツリー上に ない弧だけが操作される。GCC は、そういう弧が実行される回数を 数えるコードを追加する。ある弧が、あるブロックに対する出口にしか なっていないか、あるいは入り口にしかなっていない場合は、 操作を行なうコードをそのブロックに追加することが可能である。 その他の場合は、新しい基本ブロックを作り、操作を行なうコードを保持 しなければならない。

プログラム中のあらゆる弧が操作されるわけではないので、このオプションを 使ってコンパイルしたプログラムは、‘-a’ でコンパイルしたプログラムよりは 高速である。‘-a’ を付けると、プログラム中のあらゆる基本ブロックに 操作コードを追加する。トレードオフがある。gcov は、 全ての分岐について実行回数を数えている訳ではないので、操作された分岐の 実行回数から始めて、プログラムの流れのグラフについて、全グラフが解決 するまで繰り返し行なう。このため、gcov は、 ‘-a’ で得られる情報を使うプログラムよりは、いくらか遅くなる。

-fprofile-arcs’ を指定すると、分岐確率を見積もったり、 基本ブロックの実行回数を計算することも可能になる。 一般に、基本ブロックの実行回数だけでは、全ての分岐確率を見積もることが 出来るだけの情報は得られない。コンパイルしたプログラムが終了するとき、 弧の実行回数を ‘sourcename.da’ というファイルにセーブする。 オプション ‘-fbranch-probabilities’ (see section Options that Control Optimization) を指定して再コンパイルして、見積もった分岐確率を 使って最適化を行なう。

-ftest-coverage

コードカバレージプログラム gcov 用のデータファイルを 作る(see section gcov: a GCC Test Coverage Program). このデータファイル名は、ソースファイル名で始まる。

sourcename.bb

基本ブロックと行番号の対応表である。gcov が 行番号毎に基本ブロックの実行回数を対応させるのに使う。

sourcename.bbg

プログラムのフローグラフにおける、全ての弧のリストである。 これにより gcov がプログラムのフローグラフを再構築することで、 sourcename.da ファイルにある情報から、全ての基本ブロックと 弧の実行回数を計算できるようになる。 (sourcename.da は、‘-fprofile-arcs’ の出力である。)

-Q

各関数がコンパイルされるときにその関数名を出力し、 コンパイルの各パスについて、それが終わったときに統計情報を 出力する。

-dletters

letters で指定されるコンパイル過程のデバッグ出力を行なう。 これは GCC のデバッグに使われる。 デバッグ出力のファイル名は、ほとんどが、ソースファイル名にある単語を 追加して作られる(例えば、‘foo.c.rtl’ や ‘foo.c.jump’ 等)。 以下に letters に指定できる文字とその意味を示す。

b

分岐確率計算後に、‘file.bp’ に出力する。

c

命令組合せ後に、ファイル ‘file.combine’ にダンプする。

d

遅延分岐スケジューリング後に、‘file.dbr’ にダンプする。

D

通常の出力に加えて、全てのマクロ定義を前処理の最後にダンプする。

r

RTL 生成後、‘file.rtl’ にダンプする。

j

最初のジャンプ最適化後に、‘file.jump’ にダンプする。

F

ADDRESSOF の削除後に、‘file.addressof’ にダンプする。

f

フロー解析後に、‘file.flow’ にダンプする。

g

グローバルレジスタ割当後に、‘file.greg’ にダンプする。

G

GCSE 後に、‘file.gcse’ にダンプする。

j

最初のジャンプ最適化後に、‘file.jump’ にダンプする。

J

最後のジャンプ最適化後に、‘file.jump2’ にダンプする。

k

レジスタからスタックへの変換後に、‘file.stack’ にダンプする。

l

ローカルレジスタ割当後に、‘file.lreg’ にダンプする。

L

ループ最適化後に、‘file.loop’ にダンプする。

M

機種依存の再構成パス後に、‘file.mach’ にダンプする。

N

レジスタ移動パス後に、‘file.regmove’ にダンプする。

r

RTL 生成後に、‘file.rtl’ にダンプする。

R

二回目の命令スケジューリング・パス後に、‘file.sched2’ に ダンプする。

s

CSE(時々 CSE に続くジャンプ最適化を含む)後に、‘file.cse’ に ダンプする。

S

一回目の命令スケジューリング・パス後に、‘file.sched’ に ダンプする。

t

二回目のCSE(時々 CSE に続くジャンプ最適化を含む)後に、‘file.cse2’ にダンプする。

a

上記のダンプを全て生成する。

m

メモリ使用状況の統計を、最後に標準出力に出力する。

p

アセンブラ出力に、どのパターンと選択肢が使われたかを示すコメントで 注釈を付ける。各命令の長さも表示される。

x

関数をコンパイルするのではなく、単に RTL を生成する。 普通、‘r’ と一緒に使う。

y

構文解析中にデバッグ情報を標準エラー出力にダンプする。

A

アセンブラ出力に色々なデバッグ情報で注釈を付ける。

-fdump-unnumbered

デバッグダンプを出力するとき(上の -d オプションを参照のこと)、 命令番号と行番号ノートを出力しない。これにより、別のオプションを指定して 起動したコンパイルのデバッグダンプに diff を使いやすくなる。 特に -g のありなしで有効である。

-fpretend-float

クロスコンパイラを実行する際に、ターゲット機種がホスト機種と同じ 浮動小数点形式を使っている振りをさせる。 こうすると、実際の浮動小数点定数としては正しくない出力を行なうが、 実際の命令列は、GCC をターゲット機種で実行させたとき生成する 命令列とおそらく同じである。

-save-temps

通常「一時的」な中間ファイルを保存する。中間ファイルをカレントディレクトリ に置き、ソースファイル名に基づいた名前を付ける。 つまり、‘foo.c’ を ‘-c -save-temps’ を付けてコンパイルすると、 ‘foo.o’ の他に、‘foo.i’ と ‘foo.s’ というファイルができる。

-print-file-name=library

リンク時に使われるライブラリファイル library の絶対パス名を 出力し、他には何も行なわない。このオプションを指定すると、GCC は コンパイルやリンクは一切行なわない。単にファイル名を出力するだけである。

-print-prog-name=program

-print-file-name’ と似ていて、‘cpp’ のようなプログラムを 検索する。

-print-libgcc-file-name

-print-file-name=libgcc.a’ と同じ。

これは、‘-nostdlib’ や ‘-nodefaultlibs’ を使いたいが、 ‘libgc.a’ はリンクしたいというときに便利である。 それには以下のようにすれば良い。

 
gcc -nostdlib files… `gcc -print-libgcc-file-name`
-print-search-dirs

コンフィギュレーションで指定したインストール先ディレクトリ名と、 GCC がプログラムとライブラリを検索するディレクトリのリストを 表示する。その他の事は何も行なわない。

これは gcc が ‘installation problem, cannot exec cpp: No such file or directory’ というエラーメッセージを出したときに役に立つ。 このエラーが出たときには、‘cpp’ とその他のコンパイラのサブプログラムを gcc があると想定している場所に置くか、あるいはそれらをインストールした ディレクトリを環境変数 GCC_EXEC_PREFIX で指定する必要がある。 ここで指定するディレクトリ名には最後に '/' を付けなければならないことに 注意して欲しい。 See section GCC に影響する環境変数.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated using texi2html 1.78.