Modula-2とChillのサポートはまだ部分的なものです。 Modula-2に関する情報については、 See Modula-2。 Chillに関するドキュメントはまだありません。
集合、 サブ範囲 (subrange)、 ファイル変数、 入れ子関数を使っているPascalプログラムをデバッグすることは、 現時点ではできません。 Pascalの構文を使って、 式の入力、 変数の値の表示、 およびそれに類することを実行することを、 GDBはサポートしていません。 GDBは、 Fortranで記述されたプログラムのデバッグに使うことができます。 しかし、 Fortranの構文を使って、 式の入力、 変数の値の表示、 およびそれに類する機能を実行することは、 まだサポートされていません。 変数によっては、 末尾にアンダースコアを付けて参照する必要のある場合があります。
基本的には、 GPLは、 「あなたはこれらの自由を与えられるが、 これらの自由をほかの誰からも奪うことはできない」 と主張するライセンスです。
Richard Stallmanは、
GDB、
および、
その他の多くの
GNU
プログラムの最初の開発者です。
ほかにも多くの人々がGDBの開発に貢献してきました。
この節では、
主要な貢献者を紹介したいと思います。
フリー・ソフトウェアの素晴らしい点の1つは、
誰もがそれに貢献する自由があるということです。
残念ながら、
ここですべての人を紹介することはできません。
GDB
ディストリビューションに含まれる
ChangeLog
というファイルにおおまかな紹介を載せてあります。
バージョン2.0よりもずっと前の変更内容は、いつのまにか紛失してしまいました。
お願い: このセクションへの追加は大歓迎です。 あなたやあなたの友人 (公平を期すため、あなたの敵も加えておきましょう) が不当にもこのリストから除外されているのであれば、 喜んで名前を付け加えます。
彼らの多大な労働が感謝されていないと思われないように、 最初に、 GDBの主要なリリースを通じて GDBの面倒を見てきた人々に特に感謝します。 その人々とは、 Jim Blandy(リリース4.18)、 Jason Molenda(リリース4.17)、 Stan Shebs(リリース4.14)、 Fred Fish(リリース4.16, 4.15, 4.13, 4.12, 4.11, 4.10, 4.9)、 Stu GrossmanとJohn Gilmore(リリース4.8, 4.7, 4.6, 4.5, 4.4)、 John Gilmore(リリース4.3, 4.2, 4.1, 4.0, 3.9)、 Jim Kingdon(リリース3.5, 3.4, 3.3)、 Randy Smith(リリース3.2, 3.1, 3.0) です。
Richard Stallmanは、様々な機会にPeter TerMaat、Chris Hanson、Richard Mlynarikの支援を受けながら、2.8までのリリースを担当しました。
Michael Tiemannは、 GDBにおけるGNU C++サポートのほとんどを開発してくれました。 C++のサポートについては、 Per Bothnerからも重要な貢献がありました。 James ClarkはGNU C++のデマングラ (demangler) を開発してくれました。 C++についての初期の仕事は Peter TerMaatによるものです (彼はまた、 リリース3.0までの一般的なアップデート作業の多くを担当してくれました)。 GDB 4は、 複数のオブジェクト・ファイル・フォーマットを調べるのに BFD サブルーチン・ライブラリを使用しています。 BFDは、 David V. Henkel-Wallace、 Rich Pixley、 Steve Chamberlain、 John Gilmoreによる共同プロジェクトです。
David Johnsonは、最初のCOFFサポートを開発してくれました。 Pace Willisonは最初のカプセル化されたCOFF (encapsulated COFF) のサポートを開発してくれました。
Harris Computer Systems社のBrent Bensonは、 DWARF 2のサポート部分を提供してくれました。
Adam de BoorとBradley DavisはISI Optimum Vのサポート部分を提供してくれました。 Per Bothner、引地信之、Alessandro Forinは、 MIPSのサポート部分を提供してくれました。 Jean-Daniel FeketeはSun 386iのサポート部分を提供してくれました。 Chris HansonはHP9000サポートを改善してくれました。 引地信之と長谷井智之は、 Sony/News OS 3のサポート部分を提供してくれました。 David JohnsonはEncore Umaxのサポート部分を提供してくれました。 Jyrki KuoppalaはAltos 3068のサポート部分を提供してくれました。 Jeff LawはHP PAとSOMのサポート部分を提供してくれました。 Keith PackardはNS32Kのサポート部分を提供してくれました。 Doug RabsonはAcorn Risc Machineのサポート部分を提供してくれました。 Bob RuskはHarris Nighthawk CX-UXのサポート部分を提供してくれました。 Chris SmithはConvexのサポート (および、Fortranデバッグのサポート) 部分を提供してくれました。 Jonathan StoneはPyramidのサポート部分を提供してくれました。 Michael TiemannはSPARCのサポート部分を提供してくれました。 Tim TuckerはGould NP1とGould Powernodeのサポート部分を提供してくれました。 Pace WillisonはIntel 386のサポート部分を提供してくれました。 Jay VosburghはSymmetryのサポート部分を提供してくれました。
Andreas SchwabはM68K Linuxのサポート部分を提供してくれました。
Rich SchaeferとPeter SchauerはSunOS共用ライブラリのサポートを手伝ってくれました。
Jay FenlasonとRoland McGrathは、 GDBとGASがいくつかのマシン命令セットに関して共通の認識を持つようにしてくれました。
Patrick Duval、Ted Goldstein、Vikram Koka、Glenn Engelはリモート・デバッグ機能の開発を手伝ってくれました。 Intel社、Wind River Systems 社、AMD社、ARM社はそれぞれ、 i960、VxWorks、A29K UDI、RDIターゲット用のリモート・デバッグ・モジュールを提供してくれました。
Brian Foxは、コマンドライン編集やコマンドライン・ヒストリを提供する readlineライブラリの開発者です。
SUNY BuffaloのAndrew Beersは言語切り替えのソース・コード とModula-2サポート を開発し、このマニュアルのプログラミング言語関連 (Languages) の章を提供してくれました。
Fred FishはUnix System Vr4サポートのほとんどを開発してくれました。 彼はまた、 C++のオーバーロードされたシンボルを扱えるようコマンド補完機能を拡張してくれました。
Hitachi America, Ltd.は、 H8/300プロセッサ、 H8/500プロセッサ、 および、 Super-Hプロセッサのサポートを後援してくれました。
NECは、 v850プロセッサ、 Vr4xxxプロセッサ、 および、 Vr5xxxプロセッサのサポートを後援してくれました。
Mitsubishi(三菱)は、 D10Vプロセッサ、 D30Vプロセッサ、 および、 M32R/Dプロセッサのサポートを後援してくれました。
Toshiba(東芝)は、 TX39 Mipsプロセッサのサポートを後援してくれました。
Matsushita(松下)は、 MN10200プロセッサとMN10300プロセッサのサポートを後援してくれました。
Fujitsu(富士通)は、 SPARCliteプロセッサとFR30プロセッサのサポートを後援してくれました。
Kung Hsu、Jeff Law、Rick Sladkeyはハードウェア・ウォッチポイントのサポートを追加してくれました。
Michael Snyderはトレースポイントのサポートを追加してくれました。
Stu Grossmanはgdbserverを開発してくれました。
Jim Kingdon、Peter Schauer、Ian Taylor、Stu GrossmanはGDB全体にわたって、 ほとんど数えることができないほどのバグ・フィックスとソース・コードの整理を行ってくれました。
Hewlett-Packard社のBen Krepp、 Richard Title、 John Bishop、 Susan Macchia、 Kathy Mann、 Satish Pai、 India Paul、 Steve Rehrauer、 Elena Zannoniは、 PA-RISC 2.0アーキテクチャ、 HP-UX 10.20、10.30、11.0(narrow mode)、 HPによるカーネル・スレッドの実装、 HP aC++コンパイラ、 および、 端末ユーザ・インターフェイスの各サポート部分を提供してくれました。 また、 このマニュアルの中のHP固有の情報は、 Kim Haaseにより提供されたものです。
Cygnus Solutions社は、 1991年以降、 GDBの保守作業とGDBの多くの開発作業を後援しています。 フルタイムでGDBに関わる仕事をしたCygnusのエンジニアは、 Mark Alexander、 Jim Blandy、 Per Bothner、 Edith Epstein、 Chris Faylor、 Fred Fish、 Martin Hunt、 Jim Ingham、 John Gilmore、 Stu Grossman、 Kung Hsu、 Jim Kingdon、 John Metzler、 Fernando Nasser、 Geoffrey Noer、 Dawn Perchik、 Rich Pixley、 Zdenek Radouch、 Keith Seitz、 Stan Shebs、 David Taylor、 Elena Zannoniです。 さらに、 Dave Brolley、 Ian Carmichael、 Steve Chamberlain、 Nick Clifton、 JT Conklin、 Stan Cox、 DJ Delorie、 Ulrich Drepper、 Frank Eigler、 Doug Evans、 Sean Fagan、 David Henkel-Wallace、 Richard Henderson、 Jeff Holcomb、 Jeff Law、 Jim Lemke、 Tom Lord、 Bob Manson、 Michael Meissner、 Jason Merrill、 Catherine Moore、 Drew Moseley、 Ken Raeburn、 Gavin Romig-Koch、 Rob Savoye、 Jamie Smith、 Mike Stump、 Ian Taylor、 Angela Thomas、 Michael Tiemann、 Tom Tromey、 Ron Unrau、 Jim Wilson、 David Zuhnは、 大小様々な貢献をしてくれました。
その気になれば、 このマニュアルを使ってGDBのすべてを学習することももちろん可能ですが、 GDBを使い始めるには、 いくつかのコマンドを知っていれば十分です。 本章では、そのようなコマンドについて説明します。
汎用的なマクロ・プロセッサであるGNU m4
には、
かつて、
まだ正式なバージョンがリリースされる以前に、
次のような不具合がありました。
引用を表わす文字列をデフォルトとは異なるものに変更すると、
あるマクロ定義の内部に入れ子状態になっている他のマクロ定義を取り出すために使われるコマンドが、
正しく動作しなくなることがある、
という不具合です。
以下の短いm4
セッションでは、
0000
に展開されるマクロfoo
を定義しています。
さらに、
m4
の組み込みコマンドdefn
を使って、
マクロbar
に同一の定義を与えています。
ところが、
引用の開始文字列を<QUOTE>
に、
引用の終了文字列を<UNQUOTE>
にそれぞれ変更すると、
全く同一の手順で新しい同義語baz
を定義しようとしても、
うまくいかないのです。
$ cd gnu/m4 $ ./m4 define(foo,0000) foo 0000 define(bar,defn(`foo')) bar 0000 changequote(<QUOTE>,<UNQUOTE>) define(baz,defn(<QUOTE>foo<UNQUOTE>)) baz C-d m4: End of input: 0: fatal error: EOF in string
ここでGDBを使って、 何が起こっているのか調べてみましょう。
$ gdb m4 GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 4.18, Copyright 1999 Free Software Foundation, Inc... (gdb)GDBは、 必要なときに他のシンボルを見つけるのに最低限必要となるシンボル情報しか読み込みません。 その結果、 最初のプロンプトが表示されるまでの時間が極めて短いのです。 ここで、 出力情報がこのマニュアルの紙幅に収まるようにするために、 GDBに対して表示幅を通常よりも狭くするよう指示を出してみましょう。
(gdb) set width 70
m4
の組み込みコマンドであるchangequote
がどのように動作するのかを調べてみる必要があります。
ソースを見ると、
関連するサブルーチンがm4_changequote
であることがわかります。
そこで、
GDBのbreak
コマンドでブレイクポイントを設定してみます。
(gdb) break m4_changequote Breakpoint 1 at 0x62f4: file builtin.c, line 879.
run
コマンドを使って、
GDBの管理下でm4
を走らせます。
m4_changequote
サブルーチンに到達するまでは、
プログラムは通常どおりの動作をします。
(gdb) run Starting program: /work/Editorial/gdb/gnu/m4/m4 define(foo,0000) foo 0000
ブレイクポイントでプログラムを停止させるためにchangequote
を実行すると、
GDBはm4
の実行を停止し、
停止した箇所のコンテキスト情報を表示します。
changequote(<QUOTE>,<UNQUOTE>) Breakpoint 1, m4_changequote (argc=3, argv=0x33c70) at builtin.c:879 879 if (bad_argc(TOKEN_DATA_TEXT(argv[0]),argc,1,3))
次にn
(next
)コマンドを実行すると、
現在停止している関数の中で1行だけ処理が実行されます。
(gdb) n 882 set_quotes((argc >= 2) ? TOKEN_DATA_TEXT(argv[1])\ : nil,
set_quotes
というのは、
いわくありげなサブルーチンです。
next
コマンドの代わりにs
(step
)コマンドを使うことで、
このサブルーチンの中に入ることができます。
step
コマンドは、
それがどのサブルーチンの中にあるかということにかかわりなく、
次の1行に移動します。
この場合、
次の1行はset_quotes
の中ですから、
そこへ移動することになります。
(gdb) s set_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "<UNQUOTE>") at input.c:530 530 if (lquote != def_lquote)
m4
がその中で現在停止しているサブルーチン
(および、そのサブルーチンへの引数)
が表示されています。
これをスタック・フレーム表示と呼びます。
それは、
スタックの状態を要約した情報を表示しています。
backtrace
コマンド
(あるいは、
bt
と省略することもできます)
を使って、
現在、
スタック全体の中のどこにいるかを知ることもできます。
backtrace
コマンドは、
アクティブなサブルーチンのスタック・フレームを表示します。
(gdb) bt #0 set_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "<UNQUOTE>") at input.c:530 #1 0x6344 in m4_changequote (argc=3, argv=0x33c70) at builtin.c:882 #2 0x8174 in expand_macro (sym=0x33320) at macro.c:242 #3 0x7a88 in expand_token (obs=0x0, t=209696, td=0xf7fffa30) at macro.c:71 #4 0x79dc in expand_input () at macro.c:40 #5 0x2930 in main (argc=0, argv=0xf7fffb20) at m4.c:195
次に、2、3行先に進んで、
何が起こっているのかを見てみましょう。
最初の2回は、
s
コマンドを使います。
続く2回は、
xstrdup
サブルーチンの中に入ってしまうのを防ぐために、
n
コマンドを使います。
(gdb) s 0x3b5c 532 if (rquote != def_rquote) (gdb) s 0x3b80 535 lquote = (lq == nil || *lq == '\0') ? \ def_lquote : xstrdup(lq); (gdb) n 536 rquote = (rq == nil || *rq == '\0') ? def_rquote\ : xstrdup(rq); (gdb) n 538 len_lquote = strlen(rquote);
最後に表示された行は、少し妙な感じがします。
2つの変数lquote
、
rquote
を調べて、
本当にそれが、
新たに指定された引用開始文字列、
引用終了文字列であるかどうか確認することができます。
値を調べるにはp
(print
)コマンドを使用します。
(gdb) p lquote $1 = 0x35d40 "<QUOTE>" (gdb) p rquote $2 = 0x35d50 "<UNQUOTE>"
lquote
とrquote
は確かに引用開始文字列、
引用終了文字列のようです。
前後関係を調べるには、
l
(list
)コマンドを使って、
現在停止している行を中心にその前後10行を表示します。
(gdb) l 533 xfree(rquote); 534 535 lquote = (lq == nil || *lq == '\0') ? def_lquote\ : xstrdup (lq); 536 rquote = (rq == nil || *rq == '\0') ? def_rquote\ : xstrdup (rq); 537 538 len_lquote = strlen(rquote); 539 len_rquote = strlen(lquote); 540 } 541 542 void
len_lquote
とlen_rquote
に値を設定している行を実行させてから、
それらの値を調べてみましょう。
(gdb) n 539 len_rquote = strlen(lquote); (gdb) n 540 } (gdb) p len_lquote $3 = 9 (gdb) p len_rquote $4 = 7
len_lquote
とlen_rquote
が、
それぞれlquote
とrquote
の長さであるとすると、
ここに表示されている値は明らかに誤りです。
p
コマンドを使って、
正しい値を設定することができます。
p
コマンドによって任意の式の値を表示することができますが、
ここでいう「式」には、
サブルーチンの呼び出しや、
値の割り当ても含まれます。
(gdb) p len_lquote=strlen(lquote) $5 = 7 (gdb) p len_rquote=strlen(rquote) $6 = 9
新しい引用文字列をセットした状態で、
m4
の組み込みコマンドdefn
を使用しようとすると発生する問題を修正するには、
これだけで十分でしょうか?
c
(continue
)コマンドを使えば、
m4
に処理を継続させて、
実際に問題を発生させていた例を実行することができます。
(gdb) c Continuing. define(baz,defn(<QUOTE>foo<UNQUOTE>)) baz 0000
今度はうまくいきました。
新たにセットされた引用文字列は、
デフォルトの引用文字列と同じように機能しました。
問題の原因は、
プログラム内の2箇所のタイプ・ミスで、
長さの設定が正しく行われていないことにあったようです。
EOFを入力して、
m4
を終了させましょう。
C-d Program exited normally.
Program exited normally.
というメッセージは、
GDBが出力したもので、
m4
の実行が終了したことを意味しています。
GDBの
quit
コマンドで、
GDBセッションを終了することができます。
(gdb) quit
本章では、 GDBの起動方法、 終了方法を説明します。 基本は、 以下の2つです。
gdb
と入力してGDBを起動する
gdb
というプログラムを実行することで、
GDBが起動されます。
ひとたび起動されると、
GDBは終了を指示されるまで、
端末からのコマンド入力を受け付けます。
あるいは、
最初からGDBのデバッグ環境を指定するために、
様々な引数やオプションを指定して
gdb
プログラムを実行することもできます。
ここで説明するコマンドライン・オプションは、 様々な状況に対応するために設計されたものです。 環境によっては、 ここで説明するオプションのいくつかは、 事実上使用できない場合もあります。 GDBの最も基本的な起動方法は、 デバッグされる実行プログラムの名前を引数に指定することです。
gdb program
起動時に、 実行プログラム名とともに、 コア・ファイルの名前を指定することもできます。
gdb program core
あるいは、 既に実行中のプロセスをデバッグする場合には、 そのプロセスIDを第2引数に指定することもできます。
gdb program 1234
ここでは、
GDBはプロセスID 1234
のプロセスにアタッチします
(ただし、
1234
という名前のファイルが存在しないというのが条件です。
GDBは、
まずコア・ファイルの存在を確認します)。
このような第2引数の利用が可能であるためには、 かなり完成されたオペレーティング・システムが必要になります。 ボード・コンピュータに接続して、 リモート・デバッガとしてGDBを使用する場合には、 そもそも「プロセス」という概念がないかもしれませんし、 多くの場合、 コア・ダンプというものもないでしょう。
gdb
を起動すると、
GDBの無保証性を説明する文章が表示されますが、
-silent
オプションを指定することで、
これを表示しないようにすることもできます。
gdb -silent
コマンドライン・オプションを指定することで、 GDBの起動方法をさらに制御することができます。 GDB自身に、 使用可能なオプションを表示させることができます。
gdb -help
のようにgdbプログラムを実行することで、
使用可能なオプションがすべて、
その使用方法についての簡単な説明付きで表示されます
(短縮して、
gdb -h
という形で実行しても同じ結果が得られます)。
ユーザの指定したすべてのオプションと引数は、
順番に処理されます。
-x
オプションが指定されている場合は特別で、
順序の違いに意味がでてきます。
起動されたGDBは、
指定された引数のうちオプション以外のものは、
実行ファイル名およびコア・ファイル名
(あるいはプロセスID)
であると解釈します。
これは、
-se
オプションと-c
オプションが指定されたのと同じことです
(GDBは、
対応するオプション・フラグを持たない最初の引数を-se
オプション付きと同等とみなし、
同じく対応するオプション・フラグを持たない第2の引数があれば、
これを-c
オプション付きと同等とみなします)。
多くのオプションには、
完全形と短縮形があります。
以下の一覧では、
その両方を示します。
オプション名は、
他のオプションと区別がつけば、
最後まで記述しなくても、
GDBによって正しく認識されます
(オプション名には-
ではなく--
を使うことも可能ですが、
ここでは一般的な慣例にしたがうこととします)。
-symbols file
-s file
-exec file
-e file
-se file
-core file
-c file
-c number
attach
コマンドを実行するのと同等です
(ただし、
numberで指定される名前のコア・ダンプ形式のファイルが存在する場合は、
そのファイルをコア・ダンプとして読み込みます)。
-command file
-x file
-directory directory
-d directory
-m
-mapped
mmap
システム・コールによるファイルのメモリへのマッピングが使用可能である場合、
このオプションを使うことで、
プログラムのシンボル情報を再利用可能なファイルとしてカレント・ディレクトリに書き出させることができます。
仮にデバッグ中のプログラム名が/tmp/fred
であるとすると、
マップされたシンボル・ファイルは./fred.syms
となります。
この後のGDBデバッグ・セッションは、
このファイルの存在を検出し、
そこから迅速にシンボル情報をマップします。
この場合、
実行プログラムからシンボル情報を読み込むことはありません。
.syms
ファイルは、
GDBが実行されるホスト・マシンに固有のものです。
このファイルは、
内部のGDBシンボル・テーブルのイメージをそのまま保存したものです。
これを、
複数のホスト・プラットフォーム上において、
共有することはできません。
-r
-readnow
-mapped
オプションと-readnow
オプションは、
完全なシンボル情報を含む.syms
ファイルを作成するために、
通常は一緒に指定されます
(.syms
ファイルに関する詳細については、
See Commands to specify files)。
後に使用する目的で.syms
を作成するだけで、
それ以外には何もしないようにするためのGDBの単純な起動方法は、
以下のとおりです。
gdb -batch -nx -mapped -readnow programname
-nx
-n
.gdbinit
という名前です。
ただし、
PC上ではgdb.ini
となります)。
通常は、
すべてのコマンド・オプションと引数が処理された後に、
初期化ファイル内のコマンドが実行されます。
See Command files。
-quiet
-q
-batch
-x
オプションで指定されたすべてのコマンド・ファイルを処理した後、
終了コード0
で終了します
(-n
オプションによって禁止されていなければ、
初期化ファイル内に記述されているすべてのコマンドも実行されます)。
コマンド・ファイルに記述されたGDBコマンドの実行中にエラーが発生した場合には、
0
以外の終了コードで終了します。
batchモードはGDBをフィルタとして実行する場合に便利です。 例えば、 あるプログラムを別のコンピュータ上にダウンロードして実行する場合などです。 このような使い方の邪魔にならないよう、
Program exited normally.
というメッセージは、
batchモードでは表示されません
(通常このメッセージは、
GDBの管理下で実行中のプログラムが終了するときに、
必ず表示されます)。
-cd directory
-fullname
-f
\032
文字、
続いてコロンで区切られたファイル名、
行番号、
桁位置、
最後に改行、
というものです。
Emacs-GDBインターフェイス・プログラムは、
フレームに対応するソース・コードを表示させる命令として、
2つの\032
文字を使用します。
-b bps
-tty device
quit
quit
コマンド
(省略形はq
)
を使用するか、
あるいは、
ファイルの終端文字
(通常はC-d)
を入力します。
expressionを指定しない場合、
GDBは正常終了します。
expressionが指定された場合、
expressionの評価結果をエラー・コードとして終了します。
割り込み (多くの場合C-c) はGDBを終了させません。 割り込みは通常、 実行中のGDBコマンドを終了させ、 GDBのコマンド・レベルに復帰させます。 割り込み文字は、 いつ入力しても安全です。 というのは、 割り込みの発生が危険である間は、 GDBが割り込みの発生を抑止するからです。
アタッチされたプロセスやデバイスを制御するために
GDBを使用していた場合、
detach
コマンドでそれを解放することができます
(see Debugging an already-running process)。
デバッグ・セッションの途中でシェル・コマンドを実行する必要がある場合、
GDBを終了したり一時停止させたりする必要はありません。
shell
コマンドを使用することができます。
shell command string
SHELL
環境変数が設定されていれば、
その値が実行されるべきシェルを決定します。
SHELL
環境変数が設定されていなければ、
GDBは/bin/sh
を実行します。
開発環境ではしばしばmake
ユーティリティが必要とされます。
GDB内部でmake
ユーティリティを使用する場合は、
shell
コマンドを使用する必要はありません。
make make-args
make
プログラムを実行します。
これは、
shell make make-args
を実行するのと同じことです。
step
コマンドはstep
を実行する回数を引数に取ります。
例えば、
step 5
のようになります。
step
コマンドは引数なしでも実行可能です。
コマンドによっては、
全く引数を受け付けないものもあります。
GDBコマンド名は省略可能です。
ただし、
省略された名前があいまいなものではあってはなりません。
省略形は、
それぞれのコマンドのドキュメント内に記載されています。
場合によっては、
あいまいな省略形も許されることがあります。
例えば、
s
は、
文字s
で始まるコマンドがほかにも存在するにもかかわらず、
step
コマンドの省略形として特別に定義されています。
ある省略形が使用可能か否かは、
それをhelp
コマンドへの引数として使用することで判定可能です。
GDBへの入力として空行を与える
(<RET>キーだけを押す)
ことは、
1つ前に実行したコマンドを繰り返すということを意味します。
ただし、
いくつかのコマンド
(例えば、run
コマンド)は、
この方法で実行を繰り返すことはできません。
意図に反して再実行してしまうと問題を引き起こす可能性があるため、
繰り返し実行してほしくないようなコマンドの場合です。
list
コマンドとx
コマンドは、
<RET>キーにより繰り返し実行すると、
新たに引数が生成されて実行されるので、
前回実行されたときと全く同様の状態で繰り返し実行されるわけではありません。
こうすることで、
ソース・コードの内容やメモリの内容を容易に調べることができます。
GDBは、
別の用途でも<RET>キーを使用します。
more
ユーティリティと同様の方法で、
長い出力を分割して表示する場合です
(see Screen size)。
このような場合、
<RET>キーを余分に押してしまうことは往々にしてありえるので、
GDBはこのような表示方法を使用しているコマンドについては、
<RET>キーによる繰り返し実行を行いません。
テキストの中に#記号があると、 そこから行末まではコメントになります。 コメントの部分は実行されません。 これは、 特にコマンド・ファイルの中で便利です (see Command files)。
途中まで入力されたコマンド名は、 それがあいまいでなければ、 GDBが残りの部分を補完してくれます。 また、 いつでも、 コマンド名の補完候補の一覧を表示してくれます。 この機能は、 GDBコマンド名、 GDBサブ・コマンド名、 ユーザ・プログラムのシンボル名に対して有効です。 GDBに単語の残りの部分を補完させたい場合には、 <TAB>キーを押します。 補完候補が1つしか存在しない場合、 GDBは残りの部分を補完し、 ユーザがコマンドを (<RET>キーを押すことで) 完結させるのを待ちます。 例えば、 ユーザが以下のように入力したとしましょう。
(gdb) info bre <TAB>GDBは
breakpoints
という単語の残りの部分を補完します。
なぜなら、
info
コマンドのサブ・コマンドのうち、
bre
で始まるのはこの単語だけだからです。
(gdb) info breakpoints
この時点で、
ユーザは<RET>キーを押してinfo breakpoints
コマンドを実行するか、
あるいはbreakpoints
コマンドが実行したいコマンドではなかった場合には、
バックスペース・キーを押してこれを消去してから、
他の文字を入力することができます
(最初からinfo breakpoints
コマンドを実行するつもりであれば、
コマンド名補完機能ではなくコマンド名の省略形を利用して、
info bre
と入力した後、
ただちに<RET>キーを押してもいいでしょう)。
<TAB>キーが押されたときに、
2つ以上の補完候補が存在する場合、
GDBはベル音を鳴らします。
さらにいくつか文字を入力してから補完を再度試みることも可能ですし、
単に続けて<TAB>キーを押すことも可能です。
後者の場合、
GDBは補完候補の全一覧を表示します。
例えば、
make_
で始まる名前を持つサブルーチンにブレイクポイントを設定したいような場合に、
b make_まで入力して<TAB>キーを入力したところベル音が鳴ったとしましょう。
ここで続けて<TAB>キーを入力すると、
プログラム内のmake_
で始まるすべてのサブルーチン名が表示されます。
例えば、
以下のように入力したとします。
(gdb) b make_ <TAB>
ここでGDBはベル音を鳴らします。 もう一度<TAB>キーを入力すると、 以下のように表示されます。
make_a_section_from_file make_environ make_abs_section make_function_type make_blockvector make_pointer_type make_cleanup make_reference_type make_command make_symbol_completion_list (gdb) b make_
補完候補を表示した後、
ユーザが続きを入力できるよう、
GDBは途中まで入力された文字列
(ここではb make_
)
を再表示します。
最初から補完候補の一覧を表示したいのであれば、 <TAB>キーを2回押す代わりにM-?を入力することもできます。 ここで、 M-?というのは<META> ?を意味します。 これを入力するには、 キーボード上に<META>シフト・キーとして指定されたキーがあれば、 それを押しながら?を入力します。 <META>シフト・キーがない場合には、 <ESC>キーを押した後、 ?を入力します。
ときには、
入力したい文字列が、
論理的には『単語』であっても、
GDBが通常は単語の一部に含めない括弧のような文字を含む場合があります。
このような場合に単語の補完機能を使用するためには、
GDBコマンド内において、
そのような単語を'
(単一引用符)
で囲みます。
このようなことが必要になる可能性が最も高いのは、
C++関数名を入力するときでしょう。
これは、
C++が関数のオーバーローディング
(引数の型の違いによって識別される、
同一の名前を持つ関数の複数の定義)
をサポートしているからです。
例えば、
関数name
にブレイクポイントを設定する場合、
それがint
型のパラメータを取るname(int)
なのか、
それともfloat
型のパラメータを取るname(float)
なのかをはっきりさせる必要があります。
このような場合に単語の補完機能を使用するには、
単一引用符'
を関数名の前に入力します。
こうすることによって、
<TAB>キーまたはM-?キーが押されて単語補完が要求されたときに、
補完候補の決定には通常よりも多くのことを検討する必要のあることがGDBに通知されます。
(gdb) b 'bubble( <M-?> bubble(double,double) bubble(int,int) (gdb) b 'bubble(
場合によっては、 名前の補完をするには引用符を使用する必要があるということを、 GDBが自分で認識できることもあります。 このような場合、 ユーザが引用符を入力していなくても、 GDBが (可能な限り補完を行いつつ) 引用符を挿入してくれます。
(gdb) b bub <TAB>
GDBは入力された1行を以下のように変更し、
ベル音を鳴らします。 (gdb) b 'bubble(
一般的には、 オーバーロードされたシンボルに対して補完が要求された際に引数リストがまだ入力されていないと、 GDBは、 引用符が必要であると判断します (そして実際に挿入します)。
オーバーロードされた関数に関する情報については、
see C++ expressions。
コマンドset overload-resolution off
を使用すれば、
オーバーロードの解決を無効化することができます。
see GDB features for C++。
help
コマンドを使うことで、
GDBコマンドに関するヘルプ情報をGDB自身に表示させることができます。
help
h
help
コマンド
(省略形はh
)
を引数なしで実行することで、
コマンドのクラス名の簡単な一覧を表示させることができます。
(gdb) help List of classes of commands: running -- Running the program stack -- Examining the stack data -- Examining data breakpoints -- Making program stop at certain points files -- Specifying and examining files status -- Status inquiries support -- Support facilities user-defined -- User-defined commands aliases -- Aliases of other commands obscure -- Obscure features Type "help" followed by a class name for a list of commands in that class. Type "help" followed by command name for full documentation. Command name abbreviations are allowed if unambiguous. (gdb)
help class
status
クラスを指定した場合の表示例を以下に示します。
(gdb) help status Status inquiries. List of commands: show -- Generic command for showing things set with "set" info -- Generic command for printing status Type "help" followed by command name for full documentation. Command name abbreviations are allowed if unambiguous. (gdb)
help command
help
の引数にコマンド名を指定することで、
そのコマンドの使用法に関する簡単な説明が表示されます。
complete args
complete args
コマンドにコマンド名の先頭の部分を指定すると、
コマンド名の補完候補の一覧を表示します。
argsには、
補完されるべきコマンド名の先頭の文字列を指定します。
例えば、
complete i
は、以下のような結果を表示します。
info inspect ignore
これは、 GNU Emacsでの使用を想定したものです。
help
コマンドに加えて、
GDBのinfo
コマンドおよびshow
コマンドを使用することで、
ユーザ・プログラムの状態やGDBの状態を問い合わせることができます。
どちらのコマンドも、
多くの観点からの問い合わせをサポートしています。
このマニュアルでは、
それぞれを適切と思われる箇所で紹介しています。
索引のinfo
やshow
の部分に、
それぞれのサブ・コマンドの紹介されているページが示されています。
See Index。
info
i
)
は、
ユーザ・プログラムの状態を表わす情報を表示するものです。
例えば、
info args
によってユーザ・プログラムに与えられた引数を、
info registers
によって現在使用中のレジスタの一覧を、
info breakpoints
によってユーザが設定したブレイクポイントの一覧を、
それぞれ表示することができます。
help info
によって、
info
コマンドのサブ・コマンドの完全な一覧が表示されます。
set
set
コマンドによって、
ある式の評価結果を環境変数に割り当てることができます。
例えば、
GDBのプロンプト文字列を$記号に変更するには、
set prompt $
を実行します。
show
info
コマンドとは異なり、
show
コマンドはGDB自身の状態を表わす情報を表示するものです。
show
コマンドで表示可能な状態はすべて、
対応するset
コマンドで変更可能です。
例えば、
数値の表示に使用する基数は
set radix
コマンドで制御できます。
現在どの基数が使用されているかを単に知るためには、
show radix
コマンドを使用します。
変更可能なすべてのパラメータとそれらの現在の値を表示するためには、
show
コマンドを引数なしで実行します。
また、
info set
コマンドを使用することもできます。
どちらのコマンドも、
同じ情報を出力します。
以下に、
対応するset
コマンドを持たないという意味で例外的である、
3つのshow
サブ・コマンドを示します。
show version
show copying
show warranty
プログラムをGDB配下で実行するには、 コンパイル時にデバッグ情報を生成する必要があります。 ユーザが選択した環境で、 必要に応じて引数を指定して、 GDBを起動することができます。 プログラムの入力元と出力先をリダイレクトすること、 既に実行中のプロセスをデバッグすること、 子プロセスを終了させることもできます。
プログラムを効率的にデバッグするためには、 そのプログラムのコンパイル時にデバッグ情報を生成する必要があります。 このデバッグ情報はオブジェクト・ファイルに格納されます。 この情報は、 個々の変数や関数の型、 ソース・コード内の行番号と実行形式コードのアドレスとの対応などを含みます。
デバッグ情報の生成を要求するには、
コンパイラの実行時に-g
オプションを指定します。
多くのCコンパイラでは、
-g
オプションと-O
オプションを同時に指定することができません。
このようなコンパイラでは、
デバッグ情報付きの最適化された実行ファイルを生成することができません。
GNUのCコンパイラであるGCCは、
-O
オプションの有無にかかわらず、
-g
オプションが指定できます。
したがって、
最適化されたコードをデバッグすることが可能です。
プログラムをコンパイルするときには、
常に-g
オプションを指定することをお勧めします。
自分のプログラムは正しいと思うかもしれませんが、
自分の幸運を信じて疑わないというのは無意味なことです。
-g -O
オプションを指定してコンパイルされたプログラムをデバッグするときには、
オプティマイザがコードを再調整していることを忘れないでください。
デバッガは、
実際に存在するコードの情報を表示します。
実行されるパスがソース・ファイルの記述と一致していなくても、
あまり驚かないでください。
これは極端な例ですが、
定義されているが実際には使われていない変数を、
GDBは認識しません。
なぜなら、
コンパイラの最適化処理により、
そのような変数は削除されるからです。
命令スケジューリング機能を持つマシンなどでは、
-g
を指定してコンパイルされたプログラムでは正しく動作することが、
-g -O
を指定してコンパイルされたプログラムでは正しく動作しないということがあります。
-g -O
を指定してコンパイルされたプログラムのデバッグで何かおかしな点があれば、
-g
だけを指定してコンパイルしてみてください。
これで問題が解決するようであれば、
(再現環境と一緒に)
障害として私たちに報告してください。
古いバージョンのGNU Cコンパイラは、
デバッグ情報の生成のためのオプションの1つとして
-gg
をサポートしていました。
現在のGDBはこのオプションをサポートしていません。
お手元のGNU Cコンパイラにこのオプションがあるようであれば、
それは使わないでください。
run
r
run
コマンドを使用してください。
(VxWorks以外の環境では)
最初にプログラム名を指定する必要があります。
これには、
GDBへの引数を使用する方法
(see Getting In and Out of GDB)
と、
file
コマンドまたはexec-file
コマンドを使用する方法
(see Commands to specify files)
とがあります。
プロセスをサポートする環境でプログラムを実行している場合、
run
コマンドは下位プロセスを生成し、
そのプロセスにプログラムを実行させます
(プロセスをサポートしていない環境では、
run
コマンドはプログラムの先頭アドレスにジャンプします)。
プログラムの実行は、 上位プロセスから受け取る情報によって影響されます。 GDBはこの情報を指定する手段を提供しています。 これは、 ユーザ・プログラムが起動される前に実行されていなければなりません (ユーザ・プログラムの実行後にその情報を変更することも可能ですが、 その変更結果は、 次にプログラムを実行したときに初めて有効になります)。 この情報は、 4つに分類することができます。
run
コマンドへの引数として指定します。
ターゲット上でシェルが使用可能であれば、
引数を表現するのに通常使用する手法
(例えば、
ワイルドカード拡張や変数による代替など)
が利用できるよう、
シェルを経由して引数を渡します。
UNIXシステムでは、
SHELL
環境変数によって、
使用されるシェルを選択することができます。
See Your program's arguments。
set environment
コマンドと
unset environment
コマンドを使用して、
ユーザ・プログラムの実行に影響する環境の一部を変更することができます。
See Your program's environment。
cd
コマンドで設定可能です。
See Your program's working directory。
run
コマンドのコマンド・ライン上で、
標準入力、
標準出力をリダイレクトすることも可能です。
また、
tty
コマンドによって別のデバイスを割り当てることも可能です。
See Your program's input and output。
注意: 入出力のリダイレクトは機能しますが、 デバッグ中のプログラムの出力を、 パイプを使用して他のプログラムに渡すことはできません。 このようなことをすると、 GDBは誤って、 別のプログラムのデバッグを開始してしまうでしょう。
run
コマンドを実行すると、
ユーザ・プログラムはすぐに実行を始めます。
プログラムを停止させる方法については、
See Stopping and continuing。
プログラムが停止すると、
print
コマンドまたはcall
コマンドを使用して、
プログラム内の関数を呼び出すことができます。
See Examining Data。
GDBが最後にシンボル情報を読み込んだ後に、
シンボル・ファイルの修正タイムスタンプが変更されている場合、
GDBはシンボル・テーブルを破棄し再読み込みを行います。
この場合、
GDBは、
その時点におけるブレイクポイントの設定を保持しようと試みます。
ユーザ・プログラムへの引数は、
run
コマンドへの引数によって指定可能です。
それはまずシェルに渡され、
ワイルドカードの展開やI/Oのリダイレクトの後、
プログラムに渡されます。
SHELL
環境変数によって、
GDBの使用するシェルが指定されます。
SHELL
環境変数が定義されていないと、
GDBは/bin/sh
を使用します。
引数を指定せずに
run
コマンドを実行すると、
前回run
コマンドを実行したときの引数、
または、
set args
コマンドでセットされた引数が使用されます。
set args
set args
が引数なしで実行された場合、
run
コマンドは、
ユーザ・プログラムを引数なしで実行します。
一度プログラムに引数を指定して実行すると、
次にプログラムを引数なしで実行する唯一の方法は、
run
コマンドを実行する前に
set args
コマンドを実行することです。
show args
環境とは、 環境変数とその値の集合のことです。 環境変数は、 慣例として、 ユーザ名、 ユーザのホーム・ディレクトリ、 端末タイプ、 実行プログラムのサーチ・パスなどを記録します。 通常、 環境変数はシェル上で設定され、 ユーザの実行するすべてのプログラムによって継承されます。 デバッグ時には、 GDBを終了・再起動せずに環境を変更して、 ユーザ・プログラムを実行できると便利でしょう。
path directory
PATH
(実行ファイルのサーチ・パス)
の先頭に追加します。
これは、
GDBとユーザ・プログラムの両方に対して有効です。
:
(コロン)
またはスペースで区切られた複数のディレクトリを指定することもできます。
環境変数PATH
の中に既にdirectoryが含まれている場合には、
directoryは環境変数PATH
の先頭に移動されます。
これにより、
directoryはより早く検索されることになります。
文字列$cwd
によって、
GDBがパスを検索する時点における作業ディレクトリを参照することができます。
.
(ピリオド)
を使用すると、
path
コマンドを実行したディレクトリを参照することになります。
directory引数に.
(ピリオド)
が含まれていると、
GDBはまずそれを
(カレント・ディレクトリに)
置き換えてから、
サーチ・パスに追加します。
show paths
PATH
の値)を表示します。
show environment [varname]
environment
はenv
に省略可能です。
set environment varname [=] value
例えば、
以下のコマンドは、
後にUNIXプログラムが実行されるときのユーザ名としてfoo
をセットします
(=
の前後のスペースは見やすくするためのもので、
実際には必要ありません)。
set env USER = foo
unset environment varname
set env varname =
とは異なります。
unset environment
は、
環境変数の値として空文字列をセットするのではなく、
環境変数そのものを環境から削除します。
注意: GDBは、
環境変数SHELL
により指定されるシェル
(環境変数SHELL
が設定されていない場合には/bin/sh
)
を使用してプログラムを実行します。
SHELL
環境変数の指定するシェルが初期化ファイルを実行するものである場合
(例えば、
C-shellの.cshrc
、
BASHの.bashrc
)、
初期化ファイルの中で設定された環境変数はユーザ・プログラムに影響を与えます。
環境変数の設定は、
.login
や.profile
のように、
ユーザがシステム内に入るときに実行されるファイルに移したほうがよいでしょう。
run
コマンドで実行されるユーザ・プログラムは、
実行時のGDBの作業ディレクトリを継承します。
GDBの作業ディレクトリは、
もともと親プロセス
(通常はシェル)
から継承したものですが、
cd
コマンドによって、
GDBの中から新しい作業ディレクトリを指定することができます。
GDBの作業ディレクトリは、
GDBによって操作されるファイルを指定するコマンドに対して、
デフォルト・ディレクトリとして機能します。
See Commands to specify files。
cd directory
pwd
info terminal
run
コマンドにおいてシェルのリダイレクト機能を使用することによって、
ユーザ・プログラムの入出力をリダイレクトすることが可能です。
例えば、
run > outfile
はユーザ・プログラムの実行を開始し、
その出力をファイルoutfile
に書き込みます。
ユーザ・プログラムの入出力先を指定する別の方法に、
tty
コマンドがあります。
このコマンドはファイル名を引数として取り、
そのファイルを後に実行されるrun
コマンドのデフォルトの入出力先とします。
このコマンドはまた、
後のrun
コマンドにより生成される子プロセスを制御する端末を変更します。
例えば、
tty /dev/ttyb
は、
それ以降に実行されるrun
コマンドによって起動されるプロセスの
デフォルトの入出力先および制御端末を/dev/ttyb
端末とします。
run
コマンド実行時に明示的にリダイレクト先を指定することで、
tty
コマンドで指定された入出力装置を変更することができますが、
制御端末の設定は変更できません。
tty
コマンドを使用した場合も、
run
コマンドで入力をリダイレクトした場合も、
ユーザ・プログラムの入力元だけが変更されます。
これらのコマンドを実行しても、
GDBの入力元は、ユーザの使用している端末のままです。
attach process-id
info files
コマンドで、
現在デバッグ対象となっているプログラムの情報が表示されます)。
このコマンドは、
プロセスIDを引数に取ります。
UNIXプロセスのプロセスIDを知るのに通常使用する方法は、
ps
ユーティリティ、
または、
シェル・コマンドのjobs -l
の実行です。
attach
コマンドを実行後<RET>キーを押しても、
コマンドは再実行されません。
attach
コマンドを使用するには、
プロセスをサポートする環境でユーザ・プログラムを実行する必要があります。
例えば、
オペレーティング・システムの存在しないボード・コンピュータのような環境で動作するプログラムに対して、
attach
コマンドを使うことはできません。
さらに、
ユーザは、
プロセスに対してシグナルを送信する権利を持っている必要があります。
attach
コマンドを使用すると、
デバッガは、
まずカレントな作業ディレクトリの中で、
プロセスにより実行されているプログラムを見つけようとします。
(プログラムが見つからなければ)
次に、
ソース・ファイルのサーチ・パス
(see Specifying source directories)
を使用して、
プログラムを見つけようとします。
file
コマンドを使用して、
プログラムをロードすることも可能です。
See Commands to Specify Files。
指定されたプロセスをデバッグする準備が整った後に、
GDBが最初にすることは、
そのプロセスを停止することです。
run
コマンドを使用してプロセスを起動した場合は、
通常使用可能なすべてのGDBコマンドを使用して、
アタッチされたプロセスの状態を調べたり変更したりすることができます。
ブレイクポイントの設定、
ステップ実行、
継続実行、
記憶域の内容の変更が可能です。
プロセスの実行を継続したいのであれば、
GDBがプロセスにアタッチした後に、
continue
コマンドを使用することができます。
detach
detach
コマンドを使用してそのプロセスをGDBの管理から解放することができます。
プロセスからディタッチしても、
そのプロセスは実行を継続します。
detach
コマンド実行後は、
ディタッチされたプロセスと
GDBは互いに完全に依存関係がなくなり、
attach
コマンドによる別のプロセスへのアタッチや、
run
コマンドによる別のプロセスの起動が可能になります。
detach
コマンドを実行後<RET>キーを押しても、
detach
コマンドは再実行されません。
プロセスがアタッチされている状態で、
GDBを終了したりrun
コマンドを使用したりすると、
アタッチされたプロセスを終了させてしまいます。
デフォルトの状態では、
このようなことを実行しようとすると、
GDBが確認を求めてきます。
この確認処理を行うか否かは、
set confirm
コマンドで設定可能です
(see Optional warnings and messages)。
kill
このコマンドは、 実行中のプロセスではなく、 コア・ダンプをデバッグしたいときに便利です。 GDBは、 ユーザ・プログラムの実行中は、 コア・ダンプ・ファイルを無視します。
いくつかのオペレーティング・システム上では、
GDBの管理下でブレイクポイントを設定されている状態のプログラムを、
GDBの外で実行することができません。
このような場合、
kill
コマンドを使用することで、デバッガの外でのプログラムの実行が可能になります。
kill
コマンドは、
プログラムを再コンパイル、
再リンクしたい場合にも便利です。
というのは、
多くのシステムでは、
プロセスとして実行中の実行ファイルを更新することはできないからです。
次にrun
コマンドを実行したときに、
GDBは、
実行ファイルが変更されていることを認識し、
シンボル・テーブルを再度読み込みます
(この際、その時点でのブレイクポイントの設定を維持しようと試みます)。
いくつかのオペレーティング・システムは、
/proc
と呼ばれる便利な機能を提供しています。
これは、
ファイル・システム関連のサブルーチンを使用して、
実行中プロセスのイメージを調べるのに使用することができます。
GDBが、
この機能を持つオペレーティング・システム用に構成されていれば、
info proc
コマンドを使用することで、
ユーザ・プログラムを実行しているプロセスに関するいくつかの情報を知ることができます。
info proc
は、
procfs
をサポートするSVR4システム上でのみ機能します。
info proc
info proc mappings
info proc times
info proc id
info proc status
info proc all
HP-UXやSolarisのようなオペレーティング・システムにおいては、 1つのプログラムが複数のスレッドを実行することができます。 「スレッド」の正確な意味は、 オペレーティング・システムによって異なります。 しかし、 一般的には、 1つのアドレス空間を共有するという点を除けば、 プログラム内のマルチスレッドは、 マルチプロセスと類似しています (アドレス空間の共有とは、 複数のスレッドが同一の変数の値を参照したり変更したりすることが可能であるということです)。 その一方で、 個々のスレッドは自分用のレジスタ、 実行スタック、 そしておそらくはプライベート・メモリを持ちます。 GDBは、 マルチスレッド・プログラムのデバッグ用に、 以下のような便利な機能を提供しています。
thread threadno
info threads
thread apply [threadno] [all] args
注意: これらの機能は、 スレッドをサポートするオペレーティング・システム用に構成された すべてのGDBで使用可能なわけではありません。 GDBがスレッドをサポートしていない環境では、 これらのコマンドは無効です。 例えば、 スレッドをサポートしていないシステム上で GDBのGDBのスレッド・デバッグ機能により、 ユーザ・プログラムの実行中に、 すべてのスレッドを観察することができます。 ただし、 GDBに制御権のある状態では、 特定の1つのスレッドだけがデバッグの対象となります。 このスレッドは、 カレント・スレッドと呼ばれます。 デバッグ用のコマンドは、 カレント・スレッドの立場から見たプログラムの情報を表示します。info threads
コマンドを実行しても何も表示されませんし、thread
コマンドの実行は常に拒絶されます。(gdb) info threads (gdb) thread 1 Thread ID 1 not known. Use the "info threads" command to see the IDs of currently known threads.
ユーザ・プログラム内部において新しいスレッドの存在を検出すると、
GDBは、
[New systag]
という形式で、
ターゲット・システム上におけるこのスレッドのIDを表示します。
ここでsystagとはスレッドのIDで、
その形式はシステムによって異なります。
例えば、
LynxOS上では、
GDBが新しいスレッドを検出すると、
[New process 35 thread 27]
のように表示されます。
一方、
SGIのシステム上では、
systagは単にprocess 368
のような形式で、
これ以外の情報は含まれません。
GDBは、
ユーザ・プログラム内の個々のスレッドに対して、
デバッグ用の整数値のスレッド番号を独自に割り当てます。
info threads
*
は、
そのスレッドがカレント・スレッドであることを意味しています。
以下に例を示します。
(gdb) info threads 3 process 35 thread 27 0x34e5 in sigpause () 2 process 35 thread 23 0x34e5 in sigpause () * 1 process 35 thread 13 main (argc=1, argv=0x7ffffff8) at threadtest.c:68
thread threadno
info threads
コマンドの出力の最初のフィールドに表示される、
GDB内部のスレッド番号です。
GDBは、
指定されたスレッドのシステム上のIDとカレントなスタック・フレームの要約を表示します。
(gdb) thread 2 [Switching to process 35 thread 23] 0x34e5 in sigpause ()
[New ...]
メッセージと同様、
Switching to
の後ろに表示される情報の形式は、
そのシステムにおけるスレッドの識別方法に依存します。
thread apply [threadno] [all] args
thread apply
コマンドにより、
1つのコマンドを1つ以上のスレッドに対して実行することができます。
実行対象となるスレッドのスレッド番号を、
引数threadnoに指定します。
threadnoは、
info threads
コマンドの出力の最初のフィールドに表示される、
GDB内部のスレッド番号です。
すべてのスレッドに対してコマンドを実行するには、
thread apply all
argsコマンドを使用してください。
[Switching to systag]
という形式のメッセージでそのスレッドを示し、
コンテキスト切り替えの発生に注意を促します。
複数スレッドを持つプログラムの停止時や起動時のGDBの動作の詳細については、 See Stopping and starting multi-thread programs。
また、 複数スレッドを持つプログラムの中におけるウォッチポイントについては、 See Setting watchpoints。
fork
関数を使用して新たにプロセスを生成するプログラムのデバッグに関しては、
GDBは特別な機能を提供していません。
プログラムがfork
を実行するとき、
GDB
は引き続き親プロセスのデバッグを継続し、
子プロセスは妨げられることなく実行を続けます。
子プロセスが実行するコードにブレイクポイントを設定してあると、
子プロセスはSIGTRAP
シグナルを受信し、
(そのシグナルをキャッチする処理がなければ)
子プロセスは終了してしまいます。
しかし、
子プロセスをデバッグしたい場合には、
それほど困難ではない回避策があります。
fork
の呼び出し後に子プロセスが実行するソース・コードの中に、
sleep
関数の呼び出しを加えてください。
GDBに子プロセスのデバッグをさせる理由がないときに遅延が発生することのないように、
特定の環境変数が設定されているときのみ、
あるいは、
特定のファイルが存在するときのみ、
sleep
関数を呼び出すようにするとよいでしょう。
子プロセスがsleep
を呼び出している間に、
ps
ユーティリティを使用して子プロセスのプロセスIDを獲得します。
次に、
GDBに対して
(親プロセスもデバッグするのであれば、
新たにGDBを起動して、
そのGDBに対して)、
子プロセスにアタッチするよう指示してください
(see Attach)。
これ以降は、
通常の方法でプロセスにアタッチした場合と全く同様に、
子プロセスのデバッグが可能です。
デバッガを使用する主な目的は、
プログラムが終了してしまう前に停止させたり、
問題のあるプログラムを調査して何が悪いのかを調べたりすることにあります。
GDB内部においてプログラムが停止する原因はいくつかあります。
例えば、
シグナルの受信、
ブレイクポイントへの到達、
step
コマンドのようなGDBコマンドの実行後の新しい行への到達などです。
プログラムが停止すると、
変数の値の調査や設定、
新しいブレイクポイントの設定、
既存のブレイクポイントの削除などを行った後に、
プログラムの実行を継続することができます。
通常、
GDBが表示するメッセージは、
ユーザ・プログラムの状態について多くの情報を提供してくれます。
ユーザはいつでも明示的にこれらの情報を要求することができます。
info program
ブレイクポイントによって、
プログラム内のある特定の箇所に到達するたびに、
プログラムを停止することができます。
個々のブレイクポイントについて、
そのブレイクポイントにおいてプログラムを停止させるためには満足されなければならない、
より詳細な条件を設定することができます。
ブレイクポイントの設定は、
いくつかあるbreak
コマンドのいずれかによって行います
(see Setting breakpoints)。
行番号、
関数名、
プログラム内における正確なアドレスを指定することで、
プログラムのどこで停止するかを指定することができます。
HP-UX、
SunOS 4.x、
SVR4、
Alpha OSF/1上では、
実行開始前に共用ライブラリ内にブレイクポイントを設定することもできます。
HP-UXシステムでは、
ちょっとした制約があります。
プログラムによって直接呼び出されるのではない共用ライブラリ・ルーチン
(例えば、
pthread_create
の呼び出しにおいて、
引数として指定されるルーチン)
にブレイクポイントをセットするためには、
そのプログラムの実行が開始されるまで待たなければなりません。
ウォッチポイントは、 ある式の値が変化したときにユーザ・プログラムを停止させる、 特別なブレイクポイントです。 ウォッチポイントは、 他のブレイクポイントと同じように管理することができますが、 設定だけは特別なコマンドで行います (see Setting watchpoints)。 有効化、 無効化、 および削除を行うときに使用する各コマンドは、 対象がブレイクポイントであってもウォッチポイントであっても同一です。
ブレイクポイントでGDBが停止するたびに、 常に自動的にユーザ・プログラム内のある値を表示させるようにすることができます。 See Automatic display。
キャッチポイントは、
C++の例外の発生やライブラリのローディングのようなある種のイベントが発生したときに、
ユーザ・プログラムを停止させる、
また別の特殊なブレイクポイントです。
ウォッチポイントと同様、
キャッチポイントを設定するために使用する特別なコマンドがあります。
(see Setting catchpoints)。
しかし、
この点を除けば、
キャッチポイントを他のブレイクポイントと同様に管理することができます。
(ユーザ・プログラムがシグナルを受信したときに停止するようにするためには、
handle
コマンドを使用します。
see Signals)。
ユーザが新規に作成した個々のブレイクポイント、 ウォッチポイント、 キャッチポイントに対して、 GDBは番号を割り当てます。 この番号は1から始まる連続する整数値です。 ブレイクポイントの様々な側面を制御するコマンドの多くにおいて、 変更を加えたいブレイクポイントを指定するのにこの番号を使用します。 個々のブレイクポイントを有効化、 無効化することができます。 無効化されたブレイクポイントは、 再度有効化されるまで、 ユーザ・プログラムの実行に影響を与えません。
ブレイクポイントは、
break
コマンド
(省略形はb
)
によって設定されます。
デバッガのコンビニエンス変数$bpnum
に、
最後に設定されたブレイクポイントの番号が記録されます。
コンビニエンス変数の使用方法については、
See Convenience variables。
ブレイクポイントの設定箇所を指定する方法はいくつかあります。
break function
break +offset
break -offset
break linenum
break filename:linenum
break filename:function
break *address
break
break
コマンドは、
選択されたスタック・フレーム内において次に実行される命令にブレイクポイントを設定します
(see Examining the Stack)。
最下位にあるスタック・フレーム以外のフレームが選択されていると、
このブレイクポイントは、
制御がそのフレームに戻ってきた時点で、
ユーザ・プログラムを停止させます。
これが持つ効果は、
選択されたフレームの下位にあるフレームにおいて
finish
コマンドを実行するのと似ています。
ただし、
1つ異なるのは、
finish
コマンドがアクティブなブレイクポイントを残さないという点です。
最下位のスタック・フレームにおいて引数なしで
break
コマンドを実行した場合、
そのときに停止していた箇所に次に到達したときに、
GDBはユーザ・プログラムを停止させます。
これは、
ループの内部では便利でしょう。
GDBは通常、
実行を再開したときに、
最低でも1命令が実行されるまでの間は、
ブレイクポイントの存在を無視します。
そうでなければ、
ブレイクポイントで停止した後、
そのブレイクポイントを無効にしない限り、
先へ進めないことになってしまいます。
この規則は、
ユーザ・プログラムが停止したときに、
既にそのブレイクポイントが存在したか否かにかかわらず、
適用されます。
break ... if cond
...
の部分には、
これまでに説明してきた停止箇所を指定するための引数のいずれかが入ります
(...
は省略も可能です)。
ブレイクポイントの条件式の詳細については、
See Break conditions。
tbreak args
break
コマンドと同様であり、
ブレイクポイントも同じように設定されますが、
tbreak
により設定されたブレイクポイントは、
プログラムが最初にそこで停止した後に自動的に削除されます。
See Disabling breakpoints。
hbreak args
break
コマンドと同様であり、
ブレイクポイントも同じように設定されますが、
hbreak
により設定されるブレイクポイントは、
ハードウェアによるサポートを必要とします。
ターゲット・ハードウェアによっては、
このような機能を持たないものもあるでしょう。
これの主な目的は、
EPROM/ROMコードのデバッグであり、
ユーザはある命令にブレイクポイントを設定するのに、
その命令を変更する必要がありません。
これは、
SPARClite DSUの提供するトラップ発生機能と組み合わせて使用することができます。
DSUは、
デバッグ・レジスタに割り当てられた
データ・アドレスまたは命令アドレスをプログラムがアクセスすると、
トラップを発生させます。
ハードウェアの提供するブレイクポイント・レジスタは、
データ・ブレイクポイントを2つまでしか取れないので、
3つ以上使用しようとすると、
GDBはそれを拒絶します。
このような場合、
不要になったハードウェア・ブレイクポイントを削除または無効化してから、
新しいハードウェア・ブレイクポイントを設定してください。
See Break conditions。
thbreak args
hbreak
コマンドと同様であり、
ブレイクポイントも同じように設定されます。
しかし、
tbreak
コマンドの場合と同様、
最初にプログラムがそこで停止した後に、
このブレイクポイントは自動的に削除されます。
また、
hbreak
コマンドの場合と同様、
このブレイクポイントはハードウェアによるサポートを必要とするものであり、
ターゲット・ハードウェアによっては、
そのような機能がないこともあるでしょう。
See Disabling breakpoints。
また、
See Break conditions。
rbreak regex
break
コマンドで設定されたブレイクポイントと同様に扱われます。
他のすべてのブレイクポイントと同様の方法で、
削除、
無効化、
および条件の設定が可能です。
C++プログラムのデバッグにおいて、
あるオーバーロードされたメンバ関数が、
特別なクラスだけが持つメンバ関数というわけではない場合、
そのメンバ関数にブレイクポイントを設定するのに、
rbreak
コマンドは便利です。
info breakpoints [n]
info break [n]
info watchpoints [n]
y
、
有効でないブレイクポイントをn
で示します。
ブレイクポイントが条件付きのものである場合、
info break
コマンドは、
そのブレイクポイントに関する情報の次の行に、
その条件を表示します。
ブレイクポイント・コマンドがあれば、
続いてそれが表示されます。
info break
コマンドに引数としてブレイクポイント番号nが指定されると、
その番号に対応するブレイクポイントだけが表示されます。
コンビニエンス変数$_
、
および、
x
コマンドのデフォルトの参照アドレスには、
一覧の中で最後に表示されたブレイクポイントのアドレスが設定されます
(see Examining memory)。
info break
コマンドは、
ブレイクポイントに到達した回数を表示します。
これは、
ignore
コマンドと組み合わせると便利です。
まず、
ignore
コマンドによってブレイクポイントへの到達をかなりの回数無視するよう設定します。
プログラムを実行し、
info break
コマンドの出力結果から何回ブレイクポイントに到達したかを調べます。
再度プログラムを実行し、
今度は前回の実行時に到達した回数より1だけ少ない回数だけ無視するように設定します。
こうすることで、
前回の実行時にそのブレイクポイントに最後に到達したときと同じ状態でプログラムを停止させることが簡単にできます。
longjmp
を適切に処理するためなどです。
これらの内部的なブレイクポイントには-1
から始まる負の番号が割り当てられます。
info breakpoints
コマンドは、
このようなブレイクポイントを表示しません。
これらのブレイクポイントは、
GDBの保守コマンドmaint info breakpoints
で表示することができます。
maint info breakpoints
info breakpoints
コマンドと同様の形式で呼び出され、
ユーザが明示的に設定したブレイクポイントと、
GDBが内部的な目的で使用しているブレイクポイントの両方を表示します。
内部的なブレイクポイントは、
負のブレイクポイント番号で示されます。
タイプ欄にブレイクポイントの種類が表示されます。
breakpoint
watchpoint
longjmp
longjmp
が呼び出されたときに正しくステップ処理ができるように、
内部的に設定されたブレイクポイント
longjmp resume
longjmp
のターゲットとなる箇所に内部的に設定されたブレイクポイント
until
until
コマンドで一時的に使用される内部的なブレイクポイント
finish
finish
コマンドで一時的に使用される内部的なブレイクポイント
ウォッチポイントを設定することで、 ある式の値が変化したときに、 プログラムの実行を停止させることができます。 その値の変更が、 プログラムのどの部分で行われるかをあらかじめ知っている必要はありません。
システムによって、 ウォッチポイントがソフトウェアによって実装されていることもあれば、 ハードウェアによって実装されていることもあります。 GDBは、 ユーザ・プログラムをシングル・ステップ実行して、 そのたびに変数の値をテストすることによって、 ソフトウェア・ウォッチポイントを実現しています。 これは、 通常の実行と比較すると、 何百倍も遅くなります。 (それでも、 プログラムのどの部分が問題を発生させたのか全く手掛りのない誤りを見つけることができるのであれば、 十分価値のあることかもしれません)。
HP-UXやLinuxのようなシステム上のGDBには、 ハードウェア・ウォッチポイントのサポートも組み込まれています。 これを使用すれば、 ユーザ・プログラムの実行が遅くなることはありません。
watch expr
rwatch expr
rwatch
コマンドで設定されていなければなりません。
awatch expr
awatch
コマンドで設定されていなければなりません。
info watchpoints
info break
と同じです。
watch
コマンドを実行すると、
ハードウェア・ウォッチポイントの設定が可能な場合には、
GDBは、
以下のような報告を行います。
Hardware watchpoint num: expr
SPARClite DSUは、
デバッグ・レジスタに割り当てられた
データ・アドレスや命令アドレスにプログラムがアクセスすると、
トラップを発生させます。
データ・アドレスについては、
DSUがwatch
コマンドを支援しています。
しかし、
ハードウェアの提供するブレイクポイント・レジスタは、
データ・ウォッチポイントを2つまでしか取れず、
その2つは同じ種類のウォッチポイントでなければなりません。
例えば、
2つのウォッチポイントを、
両方ともwatch
コマンドで設定すること、
両方ともrwatch
コマンドで設定すること、
あるいは、
両方ともawatch
コマンドで設定することは可能ですが、
それぞれを異なるコマンドで設定することはできません。
異なる種類のウォッチポイントを同時に設定しようとしても、
コマンドの実行をGDBが拒否します。
このような場合、
使用しないウォッチポイント・コマンドを削除または無効化してから、
新しいウォッチポイント・コマンドを設定してください。
print
やcall
を使用して関数を対話的に呼び出すと、
それまでにセットされていたウォッチポイントはいずれも、
GDBが別の種類のブレイクポイントに到達するか、
あるいは、
関数の呼び出しが終了するまでの間は、
効果を持たなくなります。
注意: マルチスレッド・プログラムでは、 ウォッチポイントの有用性は限定されます。 現在のウォッチポイントの実装では、 GDBは、 単一スレッドの中 でしか式の値を監視することができません。 カレント・スレッドの処理の結果としてのみ、 その式の値が変更されること (かつ、 他のスレッドがカレント・スレッドにはならないこと) が確実であれば、 通常どおり、 ウォッチポイントを使用することができます。 しかし、 カレント・スレッド以外のスレッドが式の値を変更することがあると、 GDBは、 その変更に気付かないかもしれません。
キャッチポイントを使用することによって、
C++例外や共用ライブラリのローディングのような、
ある種のプログラム・イベントが発生したときに、
デバッガを停止させることができます。
キャッチポイントを設定するには、
catch
コマンドを使用します。
catch event
throw
catch
exec
exec
の呼び出し。
現在これは、
HP-UXにおいてのみ利用可能です。
fork
fork
の呼び出し。
現在これは、
HP-UXにおいてのみ利用可能です。
vfork
vfork
の呼び出し。
現在これは、
HP-UXにおいてのみ利用可能です。
load
load libname
unload
unload libname
tcatch event
カレントなキャッチポイントの一覧を表示するには、
info break
コマンドを使用します。
現在、
GDBにおけるC++の例外処理
(catch throw
とcatch catch
)
にはいくつかの制限があります。
catch
コマンドが、
例外処理をデバッグする手段としては最適なものではないような場合もあります。
どこで例外が発生したのかを正確に知りたい場合、
例外ハンドラが呼び出される前にプログラムを停止させた方がよいでしょう。
なぜなら、
スタック・ポインタの調整が行われる前のスタックの状態を見ることができるからです。
例外ハンドラの内部にブレイクポイントを設定してしまうと、
どこで例外が発生したのかを調べるのは簡単ではないでしょう。
例外ハンドラが呼び出される直前で停止させるには、
実装に関する知識が若干必要になります。
GNU C++の場合、
以下のようなANSI Cインターフェイスを持つ
__raise_exception
というライブラリ関数を呼び出すことで例外を発生させます。
/* addrは例外識別子が格納される領域 idは例外識別子 */ void __raise_exception (void **addr, void *id);
スタック・ポインタの調整が行われる前に、
すべての例外をデバッガにキャッチさせるには、
__raise_exception
にブレイクポイントを設定します
(see Breakpoints; watchpoints; and exceptions)。
idの値に依存する条件を付けたブレイクポイント (see Conditions) を使用することで、 特定の例外が発生したときにだけユーザ・プログラムを停止させることができます。 複数の条件付きブレイクポイントを設定することで、 複数の例外の中のどれかが発生したときにユーザ・プログラムを停止させることもできます。
ブレイクポイント、 ウォッチポイント、 キャッチポイントがプログラムを1回停止させた後、 同じところで再びプログラムを停止させたくない場合、 それらを取り除くことがしばしば必要になります。 これが、 ブレイクポイントの削除と呼ばれるものです。 削除されたブレイクポイントはもはや存在しなくなり、 それが存在したという記録も残りません。
clear
コマンドを使用する場合、
ブレイクポイントを、
それがプログラム内部のどこに存在するかを指定することによって削除します。
delete
コマンドの場合は、
ブレイクポイント番号を指定することで、
個々のブレイクポイント、
ウォッチポイント、
キャッチポイントを削除することができます。
ブレイクポイントで停止した後、 先へ進むために、 そのブレイクポイントを削除する必要はありません。 ユーザが実行アドレスを変更することなく継続実行する場合、 最初に実行される命令に設定されているブレイクポイントを、 GDBは自動的に無視します。
clear
clear function
clear filename:function
clear linenum
clear filename:linenum
delete [breakpoints] [bnums...]
set confirm off
コマンドが事前に実行されていない場合、
GDBは、
削除してもよいかどうか確認を求めてきます)。
このコマンドの省略形は
d
です。
ブレイクポイント、 ウォッチポイント、 キャッチポイントを削除するのではなく、 無効化したい場合もあるでしょう。 無効化によって、 ブレイクポイントは、 それがあたかも削除されたかのように機能しなくなりますが、 後に再度有効化することができるよう、 そのブレイクポイントに関する情報は記憶されます。
ブレイクポイント、
ウォッチポイント、
キャッチポイントは、
enable
コマンドとdisable
コマンドによって有効化、
無効化されます。
これらのコマンドには、
引数として1つ以上のブレイクポイント番号を指定することも可能です。
指定すべき番号が分からない場合は、
info break
コマンド、
または、
info watch
コマンドによってブレイクポイント、
ウォッチポイント、
キャッチポイントの一覧を表示させてください。
ブレイクポイント、 ウォッチポイント、 キャッチポイントは、 有効/無効という観点から見て、 4つの異なる状態を持つことができます。
break
コマンドで設定されたブレイクポイントの初期状態はこの状態です。
tbreak
コマンドで設定されたブレイクポイントの初期状態はこの状態です。
以下のコマンドを使用することで、 ブレイクポイント、 ウォッチポイント、 キャッチポイントの有効化、 無効化が可能です。
disable [breakpoints] [bnums...]
disable
コマンドは
dis
と省略することができます。
enable [breakpoints] [bnums...]
enable [breakpoints] once bnums...
enable [breakpoints] delete bnums...
tbreak
コマンド
(see Setting breakpoints)
で設定されたブレイクポイントを除き、
ユーザによって設定されたブレイクポイントの初期状態は有効状態です。
その後、
ユーザが上記のコマンドのいずれかを使用した場合に限り、
無効化されたり有効化されたりします
(until
コマンドは、
独自にブレイクポイントを設定、
削除することができますが、
ユーザの設定した他のブレイクポイントの状態は変更しません。
see Continuing and stepping)。
最も単純なブレイクポイントは、 指定された箇所にプログラムが到達するたびに、 プログラムの実行を停止させます。 ブレイクポイントに対して条件を指定することも可能です。 ここで、 「条件」とは、 プログラムが記述された言語で表現された真偽値を表す式のことです (see Expressions)。 条件付きのブレイクポイントにプログラムが到達するたびに、 その式が評価されます。 そして、 その結果が真であった場合だけ、 プログラムは停止します。
これは、
プログラムの正当性を検査するために診断式を使用するのとは逆になります。
診断式の場合は、
成立しないとき、
すなわち条件が偽であるときに、
プログラムを停止させます。
C言語でassertという診断式をテストするためには、
しかるべきブレイクポイントに! assert
という条件を設定します。
ウォッチポイントに対して条件を設定することもできます。 もともとウォッチポイントは、 ある式の値を検査するものですから、 これは必要ないかもしれません。 しかし、 ある変数の新しい値がある特定の値に等しいか否かを検査するのは条件式のほうに任せて、 ウォッチポイントの対象そのものは単にその変数の名前にしてしまうという設定の方が簡単でしょう。
ブレイクポイントの成立条件に副作用を持たせたり、 場合によってはプログラム内部の関数を呼び出させたりすることもできます。 プログラムの進行状況をログに取る関数を呼び出したり、 特別なデータ構造をフォーマットして表示するユーザ定義の関数を使用したい場合などに便利です。 この効果は、 同じアドレスに有効なブレイクポイントが別に設定されていない限り、 完全に予測可能です (別のブレイクポイントが設定されていると、 GDBはこのブレイクポイントを先に検出し、 他のブレイクポイントで設定した条件式をチェックすることなくプログラムを停止させてしまうかもしれません)。 あるブレイクポイントに到達したときに、 副作用を持つ処理を実行させるためには、 ブレイクポイント・コマンドの方がより便利であり、 より柔軟でしょう (see Breakpoint command lists)。
ブレイクポイントの成立条件は、
ブレイクポイントを設定する際に、
break
コマンドの引数にif
を使用することによって、
設定できます。
See Setting breakpoints。
ブレイクポイントの成立条件は、
condition
コマンドによっていつでも変更できます。
watch
コマンドは、
if
キーワードを認識しません。
ウォッチポイントに対して条件を追加設定する唯一の方法は、
condition
コマンドを使うことです。
condition bnum expression
condition
コマンドを使用すると、
GDBはただちにexpressionの構文の正当性、
および、
expressionの中で使用されるシンボル参照の、
ブレイクポイントのコンテキストにおける有効性をチェックします。
しかし、
condition
コマンドが実行されるときに、
expressionの値がGDBによって実際に評価されるわけではありません。
See Expressions。
condition bnum
ブレイクポイント成立条件の特別なものに、 ブレイクポイントに到達した回数がある数に達したときにプログラムを停止させるというものがあります。 これは大変便利なので、 それを実現するための特別な方法が提供されています。 それは、 ブレイクポイントの通過カウント (ignore count) を使用する方法です。 すべてのブレイクポイントは、 通過カウントと呼ばれる整数値を持っています。 ほとんどの場合、 この通過カウントの値はゼロであり、 何ら影響力を持ちません。 しかし、 通過カウントとして正の値を持つブレイクポイントに到達すると、 ユーザ・プログラムはそこで停止せず、 単に通過カウントの値を1減少させて処理を継続します。 したがって、 通過カウントがnであると、 ユーザ・プログラムがそのブレイクポイントに到達した回数がn以下の間は、 そのブレイクポイントにおいてプログラムは停止しません。
ignore bnum count
次にブレイクポイントに到達したときにプログラムを停止させるには、 countにゼロを指定してください。
ブレイクポイントで停止した後にcontinue
コマンドを使用して実行を再開する場合、
ignore
コマンドを使用することなく、
直接continue
コマンドの引数に通過カウントを指定することができます。
See Continuing and stepping。
ブレイクポイントが通過カウントとして正の値を持ち、 かつ、 成立条件を持つ場合、 成立条件はチェックされません。 通過カウントが0に達すると、 GDBは成立条件のチェックを再開します。
$foo-- <= 0
のように、
評価のたびに値の減少するコンビニエンス変数を使用した評価式によって、
通過カウントと同様の効果を達成することができます。
See Convenience variables。
通過カウントは、 ブレイクポイント、 ウォッチポイント、 キャッチポイントに適用されます。
ブレイクポイント (あるいは、 ウォッチポイント、 キャッチポイント) に対して、 それによってプログラムが停止したときに実行される一連のコマンドを指定することができます。 例えば、 ある特定の式の値を表示したり、 他のブレイクポイントを有効化したりできると便利なこともあるでしょう。
commands [bnum]
... command-list ...
end
end
だけから成る1行を記述します。
ブレイクポイントからすべてのコマンドを削除するには、
commands
行に続いて
(コマンドを1つも指定せずに)
end
を記述します。
引数bnumが指定されない場合、
commands
は、
最後に設定されたブレイクポイント、
ウォッチポイント、
キャッチポイントを対象とします
(最後に到達したブレイクポイントではありません)。
command-listの記述中は、 <RET>キーが持つ、 最後に実行されたコマンドを繰り返し実行する機能は無効です。
ブレイクポイント・コマンドを使用してプログラムの実行を再開することができます。
continue
、
step
、
または、
実行を再開させるその他の任意のコマンドを使用してください。
コマンド・リストの中で、
実行を再開するコマンドの後に記述されているものは無視されます。
というのは、
プログラムが実行を再開すると
(たとえそれがnext
コマンドやstep
コマンドによるものであっても)
別のブレイクポイントに到達する可能性があり、
そのブレイクポイントがコマンド・リストを持っていると、
どちらのリストを実行するべきかあいまいになるからです。
コマンド・リストの先頭に指定されたコマンドがsilent
であると、
ブレイクポイントで停止したときに通常出力されるメッセージは表示されません。
これは、
ある特定のメッセージを出力して実行を継続するようなブレイクポイントを設定するのに望ましいでしょう。
コマンド・リスト中の後続のコマンドがどれもメッセージを出力しない場合、
ブレイクポイントに到達したことをユーザに示す情報は何も表示されないことになります。
silent
はブレイクポイント・コマンド・リストの先頭においてのみ意味を持ちます。
echo
、
output
、
printf
の各コマンドを使用することで、
細かく管理された出力を表示することができます。
これらのコマンドは、
silent
指定のブレイクポイントで使うと便利です。
See Commands for controlled output。
例えば、
ブレイクポイント・コマンドを使用して、
foo
へのエントリにおいて
x
が正の値を持つときに、
その値を表示するには以下のようにします。
break foo if x>0 commands silent printf "x is %d\n",x cont end
ブレイクポイント・コマンドの1つの応用として、
あるバグの持つ影響を取り除いて、
他のバグを見つけるためにテストを継続することができます。
誤りのある行の次の行にブレイクポイントを設定し、
その条件の中で誤りの発生を検査し、
ブレイクポイント・コマンドの中で修正の必要な変数に正しい値を割り当てます。
コマンド・リストの最後にはcontinue
コマンドを記述して、
プログラムが停止しないようにします。
また、
プログラムの先頭にはsilent
コマンドを記述し、
何も出力されないようにします。
以下に例を挙げます。
break 403 commands silent set x = y + 4 cont end
プログラミング言語によっては
(特にC++の場合)、
異なるコンテキストにおいて使用するために、
同一の関数名を複数回定義することが可能です。
これは、
オーバーローディングと呼ばれます。
関数名がオーバーロードされている場合、
break function
だけでは、
どこにブレイクポイントを設定したいのかをGDBに正しく指定するのに十分ではありません。
このような場合には、
ブレイクポイントを設定したい関数がどれであるかを正確に指定するために、
break function(types)
のような形式を使用することができます。
このような形式を使用しないと、
GDBは候補となりえるブレイクポイントの一覧を番号付きのメニューとして表示し、
プロンプト>
によってユーザの選択を待ちます。
先頭の2つの選択肢は常に、
[0] cancel
と[1] all
です。
1を入力すると、
候補となるすべての関数のそれぞれの定義に対してブレイクポイントを設定します。
また、
0を入力すると、
新たにブレイクポイントを設定することなく
break
コマンドを終了します。
例えば、
以下に示すセッションの抜粋は、
オーバーロードされたシンボルString::after
に対してブレイクポイントを設定しようとした場合を示しています。
ここでは、
この関数名を持つ関数定義の中から3つを選択しています。
(gdb) b String::after [0] cancel [1] all [2] file:String.cc; line number:867 [3] file:String.cc; line number:860 [4] file:String.cc; line number:875 [5] file:String.cc; line number:853 [6] file:String.cc; line number:846 [7] file:String.cc; line number:735 > 2 4 6 Breakpoint 1 at 0xb26c: file String.cc, line 867. Breakpoint 2 at 0xb344: file String.cc, line 875. Breakpoint 3 at 0xafcc: file String.cc, line 846. Multiple breakpoints were set. Use the "delete" command to delete unwanted breakpoints. (gdb)
継続実行とは、
ユーザ・プログラムの実行を再開して、
それが正常に終了するまで実行させることを指します。
一方、
ステップ実行とは、
ユーザ・プログラムを1「ステップ」だけ実行することを指します。
ここで「ステップ」とは、
(使用されるコマンドによって)
1行のソース・コードを指すこともありますし、
1マシン命令を指すこともあります。
継続実行の場合でもステップ実行の場合でも、
ブレイクポイントやシグナル
が原因となって、
正常終了する前にユーザ・プログラムが停止することがあります
(シグナルによってプログラムが停止した場合、
実行を再開するには
handle
コマンドまたはsignal 0
コマンドを使用するとよいでしょう。
See Signals)
。
continue [ignore-count]
c [ignore-count]
fg [ignore-count]
ignore
コマンドと似た効果を持ちます
(see Break conditions)。
引数ignore-countは、
ユーザ・プログラムがブレイクポイントによって停止した場合にのみ意味を持ちます。
これ以外の場合には、
continue
コマンドへの引数は無視されます。
c
およびfg
は、
簡便さのためだけに提供されている同義コマンドで、
continue
コマンドと全く同様の動作をします。
別の箇所で実行を再開するには、
呼び出し関数に戻るreturn
コマンド
(see Returning from a function)、
または、
ユーザ・プログラム内の任意の箇所へ移動するjump
コマンド
(see Continuing at a different address)
を使用することができます。
ステップ実行を使用する典型的なテクニックは、 問題があると思われる関数やプログラム部分の先頭にブレイクポイント (see Breakpoints; watchpoints; and catchpoints) を設定し、 ブレイクポイントで停止するまでプログラムを実行させた後、 問題が再現するまで、 関連しそうな変数の値を調べながら、 疑わしい部分を1行ずつ実行することです。
step
s
です。
注意: デバッグ情報なしでコンパイルされた関数の内部にいるときにstep
コマンドを使用すると、 デバッグ情報付きの関数に達するまでプログラムの実行は継続されます。 同様に、step
コマンドがデバッグ情報なしでコンパイルされた関数の内部へ入って、 停止することはありません。 デバッグ情報を持たない関数の内部でステップ実行を行うには、 後述のstepi
コマンドを使用してください。
step
コマンドは、
ソース・コード行の最初の命令においてのみ停止するようになりました。
これにより、
以前のバージョンで発生していた、
switch
文やfor
文などにおいて複数回停止してしまうという問題が回避されています。
同じ行の中にデバッグ情報を持つ関数への呼び出しがあると、
step
コマンドは続けて停止します。
さらに、
step
コマンドは、
サブルーチンが行番号情報を持つ場合に限り、
サブルーチンの内部に入り込むようになりました。
サブルーチンが行番号情報を持たない場合、
step
コマンドはnext
コマンドと同様の動作をします。
これにより、
MIPSマシン上でcc -gl
を使用した場合に発生していた問題が回避されています。
以前のバージョンでは、
サブルーチンが何らかのデバッグ情報を持っていれば、
その内部に入り込んでいました。
step count
step
コマンドによるステップ実行をcount回繰り返します。
ステップ実行をcount回繰り返し終わる前に、
ブレイクポイントに到達する
か、
あるいは、
ステップ実行とは関連のないシグナルが発生した
場合には、
ただちにステップ実行を中断して停止します。
next [count]
step
コマンドと似ていますが、
next
コマンドは、
ソース・コード上に関数呼び出しが存在すると、
その関数を停止することなく最後まで実行します。
プログラムが停止するのは、
next
コマンドを実行したときと同一のスタック・フレーム上において、
ソース・コード上の異なる行まで実行が継続されたときです。
このコマンドの省略形はn
です。
引数countは、
step
コマンドの場合と同様、
繰り返し回数です。
next
コマンドは、
ソース・コード行の最初の命令においてのみ停止するようになりました。
これにより、
以前のバージョンで発生していた、
switch
文やfor
文などにおいて複数回停止してしまうという問題が回避されています。
finish
return
コマンド
(see Returning from a function)
と比較してみてください。
until
u
next
コマンドに似ていますが、
唯一の相違点は、
until
コマンドによってジャンプ命令が実行された場合、
プログラム・カウンタの値がジャンプ命令のアドレスより大きくなるまで、
プログラムが継続実行されるという点です。
これは、
ステップ実行によってループ内の最後の行に到達した後にuntil
コマンドを実行することで、
ループから抜け出るまでプログラムを継続実行させることができるということを意味しています。
これに対して、
ループ内の最後の行でnext
コマンドを実行すると、
プログラムはループの先頭に戻ってしまうので、
ループ内の処理を繰り返すことを余儀なくされます。
until
コマンドの実行により、
プログラムがカレントなスタック・フレームから抜け出ようとすると、
そこでuntil
コマンドはプログラムを停止します。
実行されるマシン・コードの順序がソース行の順序と一致しない場合、
until
コマンドは直観にいくらか反するような結果をもたらすかもしれません。
例えば、
以下に挙げるデバッグ・セッションからの抜粋では、
f
(frame
)
コマンドによって、
プログラムが206
行めにおいて停止していることが示されています。
ところが、
until
コマンドを実行すると、
195
行めで停止してしまいます。
(gdb) f #0 main (argc=4, argv=0xf7fffae8) at m4.c:206 206 expand_input(); (gdb) until 195 for ( ; argc > 0; NEXTARG) {
これは、
コンパイラが、
実行の効率を高めるために、
C言語では
for
ループ本体の前に記述されているループ終了のための条件判定を、
ループの先頭ではなく末尾で行うコードを生成したためです。
この判定式にまで処理が進んだとき、
until
コマンドはあたかもループの先頭に戻ったかのように見えます。
しかしながら、
実際のマシン・コードのレベルでは、
前の命令に戻ったわけではありません。
引数のないuntil
コマンドは、
1命令ごとのステップ実行によって実現されるため、
引数付きの
until
コマンドに比べて処理性能が劣ります。
until location
u location
break
コマンドの受け付ける形式の引数です
(see Setting breakpoints)。
この形式によるuntil
コマンドはブレイクポイントを使用するため、
引数のないuntil
コマンドより処理性能が優れています。
stepi
si
マシン命令単位でステップ実行する場合、
display/i $pc
を使用すると便利なことがしばしばあります。
これは、
ユーザ・プログラムが停止するたびに、
次に実行される命令をGDBに自動的に表示させます。
See Automatic display。
引数として、
step
コマンドと同様、
繰り返し回数を取ります。
nexti
ni
引数として、next
コマンドと同様、
繰り返し回数を取ります。
シグナルは、
プログラム内で発生する非同期イベントです。
オペレーティング・システムによって、
使用可能なシグナルの種類が定義され、
それぞれに名前と番号が割り当てられます。
例えば、
UNIXにおいては、
割り込み
(通常は、Ctrlキーを押しながらCを押す)
を入力したときにプログラムが受信する
SIGINT
、
その使用領域からかけ離れたメモリ域を参照したときにプログラムが受信するSIGSEGV
、
アラームのタイムアウト時に発生する
(プログラムからアラームを要求した場合にのみ発生する)
SIGALRM
シグナルなどがあります。
SIGALRM
など、
いくつかのシグナルは、
プログラムの正常な機能の一部です。
SIGSEGV
などの他のシグナルは、
エラーを意味します。
これらのシグナルは、
プログラムが事前にそれを処理する何らかの方法を指定しないと、
致命的な
(プログラムを即座に終了させる)
ものとなります。
SIGINT
はユーザ・プログラム内部のエラーを意味するものではありませんが、
通常は致命的なものであり、
割り込みの目的であるプログラムの終了を実現することができます。
GDBは、
ユーザ・プログラム内部における任意のシグナル発生を検出することができます。
ユーザは、
個々のシグナルの発生時に何を実行するかを、
GDBに対して事前に指定することができます。
通常GDBは、
SIGALRM
のようなエラーではないシグナルを無視するよう
(これらのシグナルがユーザ・プログラムの中で持っている役割を妨害することのないよう)
設定されています。
その一方で、
エラーのシグナルが発生した場合にはすぐにユーザ・プログラムを停止させるよう設定されています。
これらの設定はhandle
コマンドによって変更することができます。
info signals
info handle
は、
info signals
に対して設定された新しい別名です。
handle signal keywords...
SIG
は省略可能)
を指定します。
キーワードkeywordsによって、
どのように変更するかを指定します。
handle
コマンドが受け付けるキーワードには省略形を使用することができます。
省略しない場合、
キーワードは以下のようになります。
nostop
stop
print
キーワードを暗黙のうちに含みます。
print
noprint
nostop
キーワードを暗黙のうちに含みます。
pass
nopass
シグナルによってユーザ・プログラムが停止した場合、
実行を継続するまでそのシグナルは検出されません。
その時点において、
そのシグナルに対してpass
キーワードが有効であれば、
ユーザ・プログラムは、
実行継続時にシグナルを検出します。
言い換えれば、
GDBがシグナルの発生を報告してきたとき、
handle
コマンドにpass
キーワードまたはnopass
キーワードを指定することで、
実行を継続したときにプログラムにそのシグナルを検出させるか否かを制御することができます。
また、
signal
コマンドを使用することによって、
ユーザ・プログラムがシグナルを検出できないようにしたり、
通常は検出できないシグナルを検出できるようにしたり、
あるいは任意の時点で任意のシグナルをユーザ・プログラムに検出させたりすることができます。
例えば、
ユーザ・プログラムが何らかのメモリ参照エラーによって停止した場合、
ユーザは、
さらに実行を継続しようとして、
問題のある変数に正しい値を設定して継続実行しようとするかもしれません。
しかし、
実行継続直後に検出される致命的なシグナルのために、
おそらくユーザ・プログラムはすぐに終了してしまうでしょう。
このようなことを回避したければ、
signal 0
コマンドによって実行を継続することができます。
See Giving your program a signal。
ユーザ・プログラムが複数のスレッド (see Debugging programs with multiple threads) を持つ場合、 すべてのスレッドにブレイクポイントを設定するか、 特定のスレッドにブレイクポイントを設定するかを選択することができます。
break linespec thread threadno
break linespec thread threadno if ...
break
コマンドに修飾子thread threadno
を使用することで、
ある特定のスレッドがこのブレイクポイントに到達したときだけGDBがプログラムを停止するよう、
指定することができます。
ここでthreadnoは、
GDBによって割り当てられるスレッド識別番号で、
info threads
コマンドによる出力の最初の欄に表示されるものです。
ブレイクポイントを設定する際にthread threadno
を指定しなければ、
そのブレイクポイントはユーザ・プログラム内部のすべてのスレッドに適用されます。
条件付きのブレイクポイントに対してもthread
識別子を使用することができます。
この場合、
以下のようにthread threadno
をブレイクポイント成立条件の前に記述してください。
(gdb) break frik.c:13 thread 28 if bartab > lim
いかなる理由によるのであれGDB配下においてユーザ・プログラムが停止した場合、 カレント・スレッドだけではなく、 すべての実行スレッドが停止します。 これにより、 知らないうちに状態の変化が発生することを心配することなく、 スレッドの切り替えも含めて、 プログラム全体の状態を検査することができます。
逆に、
プログラムの実行を再開したときには、
すべてのスレッドが実行を開始します。
これは、
step
コマンドやnext
コマンドによるシングル・ステップ実行の場合でも同様です。
特にGDBは、 すべてのスレッドの歩調を合わせてシングル・ステップ実行することはできません。 スレッドのスケジューリングは、 デバッグ対象のマシンのオペレーティング・システムに依存する (GDBが管理するわけではない) ので、 カレント・スレッドがシングル・ステップの実行を完了する前に、 他のスレッドは複数の文を実行してしまうかもしれません。 また、 プログラムが停止するとき、 他のスレッドは2つの文の間の境界のところでぴったり停止するよりも、 文の途中で停止してしまう方が一般的です。
また、 継続実行やステップ実行の結果、 プログラムが別のスレッド内で停止してしまうこともありえます。 最初のスレッドがユーザの要求した処理を完了する前に、 他のスレッドがブレイクポイントに到達した場合、 シグナルを受信した場合、 例外が発生した場合には、 常にこのようなことが発生します。
OSによっては、 OSスケジューラをロックすることによって、 ただ1つのスレッドだけが実行されるようにすることができます。
set scheduler-locking mode
off
の場合は、
ロックのメカニズムは機能せず、
任意の時点において、
どのスレッドも実行される可能性を持ちます。
on
の場合は、
再始動(resume)されるスレッドの優先順位が低い場合には、
カレント・スレッドだけが実行を継続することができます。
step
モードでは、
シングル・ステップ実行のための最適化が行われます。
ステップ実行をしている間、
他のスレッドが「プロンプトを横取りする」ことがないよう、
カレント・スレッドに占有権が与えられます。
また、
ステップ実行をしている間、
他のスレッドはきわめて稀にしか
(あるいは、
まったく)
実行するチャンスを与えられません。
next
コマンドによって関数呼び出しの次の行まで処理を進めると、
他のスレッドが実行される可能性は高くなります。
また、
continue
、
until
、
finish
のようなコマンドを使用すると、
他のスレッドは
完全に自由に実行されることができます。
しかし、
そのタイムスライスの中でブレイクポイントに到達しない限り、
他のスレッドが、
デバッグの対象となっているスレッドから、
GDBプロンプトを横取りすることはありません。
show scheduler-locking
ユーザ・プログラムが停止したとき、 まず最初に、 どこで停止したのか、 そして、 どのようにしてそこに到達したのかを知る必要があるでしょう。
ユーザ・プログラムが関数呼び出しを行うたびに、 その呼び出しに関する情報が生成されます。 その情報には、 ユーザ・プログラム内においてその呼び出しが発生した場所、 関数呼び出しの引数、 呼び出された関数内部のローカル変数などが含まれます。 その情報は、 スタック・フレームと呼ばれるデータ・ブロックに保存されます。 スタック・フレームは、 呼び出しスタックと呼ばれるメモリ域に割り当てられます。
ユーザ・プログラムが停止すると、 スタックを検査するGDBコマンドを使用して、 この情報をすべて見ることができます。 GDBは1つのスタック・フレームを選択していて、 多くのGDBコマンドはこの選択されたフレームを暗黙のうちに参照します。 特に、 GDBに対してユーザ・プログラム内部の変数の値を問い合わせると、 GDBは選択されたフレームの内部においてその値を探そうとします。 関心のあるフレームを選択するための特別なGDBコマンドが提供されています。 See Selecting a frame。
ユーザ・プログラムが停止すると、
GDBはその時点において実行中のフレームを自動的に選択し、
frame
コマンド
(see Information about a frame)
のように、
そのフレームに関する情報を簡潔に表示します。
呼び出しスタックは、 スタック・フレーム、 または短縮してフレームと呼ばれる、 連続した小部分に分割されます。 個々のフレームは、 ある関数に対する1回の呼び出しに関連するデータです。 フレームには、 関数への引数、 関数のローカル変数、 関数の実行アドレスなどの情報が含まれます。
ユーザ・プログラムが起動されたとき、
スタックにはmain
関数のフレームが1つ存在するだけです。
これは、
初期フレームまたは「最上位のフレーム」と呼ばれます。
関数が呼び出されるたびに、
新たにフレームが作成されます。
関数が復帰すると、
その関数を呼び出したときに生成されたフレームが取り除かれます。
関数が再帰的に呼び出される場合、
1つの関数に対して多くのフレームが生成されるということもありえます。
実際に実行中の関数に対応するフレームは、
「最下位のフレーム」と呼ばれます。
これは、
存在するすべてのスタック・フレームの中で、
最も新しく作成されたものです。
ユーザ・プログラムの内部においては、 スタック・フレームはアドレスによって識別されます。 スタック・フレームは多くのバイトから構成され、 それぞれがそれ自身のアドレスを持っています。 そのアドレスがフレームのアドレスとなるような1バイトを選択する慣習的な方法を、 すべての種類のコンピュータが提供しています。 通常、 あるフレーム内部で実行中は、 そのフレームのアドレスがフレーム・ポインタ・レジスタと呼ばれるレジスタに格納されています。 GDBは、 既存のスタック・フレームのすべてに番号を割り当てます。 最下位のフレームは0で、 それを呼び出したフレームは1となります。 以下、 最下位のフレームを起点として、 順番に値を割り当てていきます。 これらの番号はユーザ・プログラム内部には実際には存在しません。 これらの番号は、 GDBコマンドでスタック・フレームを指定することができるように、 GDBによって割り当てられたものです。
コンパイラによっては、
スタック・フレームを使用しなくても実行可能なように関数をコンパイルする方法を提供しているものもあります
(例えば、
gcc
のオプション-fomit-frame-pointer
を指定すると、
フレームを持たない関数が生成されます)。
これは、
フレームをセットアップする時間を節約するために、
頻繁に利用されるライブラリ関数に対してしばしば適用されます。
これらの関数の呼び出しを処理するためにGDBが提供する機能は限られています。
最下位のフレームの関数呼び出しがスタック・フレームを持たない場合、
GDBは、
あたかもそれが通常どおりに番号0のフレームを持つものとみなして、
関数呼び出しの連鎖を跡づけることができるようにします。
しかしながら、
最下位以外のスタック位置に存在する、
フレームを持たない関数に対しては、
GDBは特別な処置を取りません。
frame args
frame
コマンドによって、
あるスタック・フレームから別のスタック・フレームに移動し、
選択したスタック・フレームを表示させることができます。
argsは、
フレームのアドレスまたはスタック・フレーム番号です。
引数なしで実行すると、
frame
コマンドはカレントなスタック・フレームを表示します。
select-frame
select-frame
コマンドによって、
フレームを表示することなく、
あるスタック・フレームから別のスタック・フレームに移動することができます。
これは、
frame
コマンドから、
表示処理を取り除いたものです。
バックトレースとは、 ユーザ・プログラムが現在いる箇所にどのようにして到達したかを示す要約情報です。 複数のフレームが存在する場合、 1フレームの情報を1行に表示します。 現在実行中のフレーム (番号0のフレーム) を先頭に、 それを呼び出したフレーム (番号1のフレーム) を次行に、 以降、 同様にスタックをさかのぼって情報を表示します。
backtrace
bt
システムの割り込み文字
(通常は、Ctrlキーを押しながらCを押す)
によって、
いつでもバックトレースを停止することができます。
backtrace n
bt n
backtrace
コマンドと似ていますが、
最下位のフレームから数えてn個のフレームだけが表示されます。
backtrace -n
bt -n
backtrace
コマンドと似ていますが、
最上位のフレームから数えてn個のフレームだけが表示されます。
backtrace
の別名としては、
ほかにwhere
やinfo stack
(省略形はinfo s
)
があります。
backtrace
コマンドの出力結果の各行に、
フレーム番号と関数名が表示されます。
set print address off
コマンドを実行していなければ、
プログラム・カウンタの値も表示されます。
backtrace
コマンドの出力結果では、
関数への引数に加えて、
ソース・ファイル名や行番号も表示されます。
プログラム・カウンタが、
行番号で指定される行の最初のコードを指している場合、
その値は省略されます。
以下にbacktrace
の例を示します。
これは、
bt 3
の出力であり、
したがって最下位のフレームから3フレームが表示されています。
#0 m4_traceon (obs=0x24eb0, argc=1, argv=0x2b8c8) at builtin.c:993 #1 0x6e38 in expand_macro (sym=0x2b600) at macro.c:242 #2 0x6840 in expand_token (obs=0x0, t=177664, td=0xf7fffb08) at macro.c:71 (More stack frames follow...)
番号0のフレームを表示する行の先頭には、
プログラム・カウンタの値がありません。
これは、
builtin.c
の993
行めの最初のコードにおいて
ユーザ・プログラムが停止したことを表わしています。
スタックやユーザ・プログラム内の他のデータを調べるためのほとんどのコマンドは、 それが実行された時点において選択されているスタック・フレーム上で動作します。 以下に、 スタック・フレームを選択するためのコマンドを列挙します。 どのコマンドも、 それによって選択されたスタック・フレームに関する簡単な説明を最後に表示します。
frame n
f n
main
のフレームです。
frame addr
f addr
SPARCアーキテクチャでは、
フレームを任意に選択するには、
フレーム・ポインタ、
スタック・ポインタの2つのアドレスをframe
に指定する必要があります。
MIPS、 Alphaの両アーキテクチャでは、 スタック・ポインタ、 プログラム・カウンタの2つのアドレスが必要です。
29kアーキテクチャでは、
レジスタ・スタック・ポインタ、
プログラム・カウンタ、
メモリ・スタック・ポインタの3つのアドレスが必要です。
up n
down n
down
の省略形はdo
です。
これらのコマンドはいずれも、 最後にフレームに関する情報を2行で表示します。 1行めには、 フレーム番号、 関数名、 引数、 ソース・ファイル名、 そのフレーム内において実行停止中の行番号が表示されます。 2行めには、 実行停止中のソース行が表示されます。
以下に、 例を示します。
(gdb) up #1 0x22f0 in main (argc=1, argv=0xf7fffbf4, env=0xf7fffbfc) at env.c:10 10 read_input_file (argv[i]);
この情報が表示された後で、
list
コマンドを引数なしで実行すると、
フレーム内で実行停止中の行を中心に10行のソース行が表示されます。
See Printing source lines。
up-silently n
down-silently n
up
コマンド、
down
コマンドの変種です。
相違点は、
ここに挙げた2つのコマンドが、
新しいフレームに関する情報を表示することなく実行されるという点にあります。
これらは、
情報の出力が不必要で邪魔ですらある、
GDBのコマンド・スクリプトの中での使用を主に想定したものです。
既に挙げたもの以外にも、 選択されたフレームに関する情報を表示するコマンドがいくつかあります。
frame
f
f
です。
引数付きの場合、
このコマンドはスタック・フレームを選択するのに使用されます。
See Selecting a frame。
info frame
info f
これらの詳細な情報は、
何か問題が発生して、
スタックの形式が通常の慣習に合致しなくなった場合に、
役に立ちます。
info frame addr
info f addr
frame
コマンドに指定するのと同様のアドレスを
(アーキテクチャによっては複数)
指定する必要があります。
See Selecting a frame。
info args
info locals
info catch
up
コマンド、
down
コマンド、
frame
コマンドを使用して)
移動してから、
info catch
を実行します。
See Setting catchpoints。
AlphaベースのコンピュータとMIPSベースのコンピュータは、 変わったスタック・フレームを使用しています。 そのため、 関数の先頭を見つけるために、 GDBはときどきオブジェクト・コードを逆方向に検索する必要があります。
応答時間を改善するために (特に、 このような検索を実行するのに、 速度の遅いシリアル回線を使用するほかない、 組み込みアプリケーションの場合)、 以下に列挙するコマンドを使用して検索量を制限するとよいでしょう。
set heuristic-fence-post limit
show heuristic-fence-post
これらのコマンドは、 GDBが、 Alphaプロセッサ上、 または、 MIPSプロセッサ上においてプログラムをデバッグするよう構成されている場合に のみ使用することができます。
GNU Emacsインターフェイス経由でGDBを使用しているユーザは、 Emacsの提供する機能を使ってソース・ファイルを参照する方を好むかもしれません。 これについては、 See Using GDB under GNU Emacs。
ソース・ファイル内の行を表示するには、
list
コマンド
(省略形はl
)
を使用します。
デフォルトでは、
10行が表示されます。
ソース・ファイルのどの部分を表示するかを指定する方法がいくつかあります。
最もよく使われるlist
コマンドの形式を以下に示します。
list linenum
list function
list
list
コマンドによって表示されたのであれば、
その最後の行の次の行以降が表示されます。
しかし、
既に表示された最後の行が、
スタック・フレーム
(see Examining the Stack)
の表示の一部として1行だけ表示されたのであれば、
その行の前後の行が表示されます。
list -
list
コマンドを上記の形式のいずれかによって実行すると、
GDBはデフォルトでは10行のソース行を表示します。
これはset listsize
コマンドによって変更することができます。
set listsize count
list
コマンドで表示される行数をcountに設定します
(list
コマンドの引数で他の値が明示的に指定された場合は、
この設定は効力を持ちません)。
show listsize
list
コマンドが表示する行数を表示します。
list
コマンドを実行後、
<RET>キーによってlist
コマンドを実行した場合、
引数は破棄されます。
したがって、
これは単にlist
と入力して実行したのと同じことになります。
同じ行が繰り返し表示されるよりも、
この方が役に立つでしょう。
ただし、
引数-
は例外となります。
この引数は繰り返し実行の際にも維持されるので、
繰り返し実行することで、
ソース・ファイルの内容がさかのぼって表示されていきます。
一般的には、
list
コマンドは、
ユーザによって0個、
1個、
または2個の行指定(linespec)が与えられることを期待しています。
ここで行指定とは、
ソース行を指定するものです。
いくつかの記述方法がありますが、
いずれも結果的には何らかのソース行を指定するものです。
list
コマンドの引数として使用できる引数の完全な説明を以下に示します。
list linespec
list first,last
list ,last
list first,
list +
list -
list
以下に、 ソースの特定の1行を指定する方法を示します。 これは、 いずれも行指定です。
number
list
コマンドの引数に2つの行指定がある場合、
2つめの行指定は、
最初の行指定と同一のソース・ファイルを指定します。
+offset
list
コマンドにおいて、
これが2つめの行指定として使用される場合、
最初の行指定からoffsetで指定される行数だけ下の行を指定します。
-offset
filename:number
function
{
)
のある行を指します。
filename:function
{
)
のある行を指定します。
異なるソース・ファイルの中に同一の名前の関数が複数ある場合にのみ、
あいまいさを回避するために、
関数名とともにファイル名を指定する必要があります。
*address
カレントなソース・ファイル内において正規表現による検索を行うためのコマンドが2つあります。
forward-search regexp
search regexp
forward-search regexp
コマンドは、
最後にlist
コマンドによって表示された行の1つ下の行から、
1行ずつ正規表現regexpによる検索を行います。
正規表現にマッチするものが見つかると、
その行を表示します。
search regexp
という同義のコマンドを使うこともできます。
コマンド名は、
省略してfo
とすることができます。
reverse-search regexp
reverse-search regexp
コマンドは、
最後にlist
コマンドによって表示された行の1つ上の行から、
1行ずつ逆方向に向かって正規表現regexpによる検索を行います。
正規表現にマッチするものが見つかると、
その行を表示します。
コマンド名は、
省略してrev
とすることができます。
実行形式プログラムは、 それがコンパイルされたソース・ファイルの名前だけを記録して、 ソース・ファイルの存在するディレクトリ名を記録しないことがあります。 また、 ディレクトリ名が記録された場合でも、 コンパイル時とデバッグ時との間に、 そのディレクトリが移動してしまっている可能性があります。 GDBは、 ソース・ファイルを検索すべきディレクトリの一覧を持っています。 これは、 ソース・パスと呼ばれます。 GDBは、 ソース・ファイルが必要なときにはいつでも、 それが見つかるまで、 このリストの中のすべてのディレクトリを、 リストの中に記述されている順に探します。 実行ファイルのサーチ・パスは、 この目的では使用されないことに気をつけてください。 またカレントな作業ディレクトリも、 それがたまたまソース・パスの中にある場合を除けば、 この目的で使用されることはありません。 GDBがソース・パスの中でソース・ファイルを見つけることができない場合、 プログラムがディレクトリ名を記録してあれば、 そのディレクトリも検索されます。 ソース・パスにディレクトリの指定がなく、 コンパイルされたディレクトリの名前も記録されていない場合、 GDBは最後の手段としてカレント・ディレクトリを探します。
ソース・パスを空にした場合、
または、
再調整した場合、
ソース・ファイルを見つけた場所や個々の行のファイル内の位置のような、
GDBが内部でキャッシュしている情報は消去されます。
GDBを起動した時点では、
ソース・パスにはディレクトリの指定がありません。
ディレクトリをソース・パスに追加するには、
directory
コマンドを使用してください。
directory dirname ...
dir dirname ...
:
または空白で区切ることによって、
複数のディレクトリをこのコマンドに渡すことができます。
ソース・パスの中に既に存在するディレクトリを指定することもできます。
この場合、
そのディレクトリの、
ソース・パスの中での位置が前に移動するので、
GDBはそのディレクトリの中を以前よりも早く検索することになります。
(コンパイル時のディレクトリが記録されていれば)
それを指すのに文字列$cdir
を使うことができます。
また、
カレントな作業ディレクトリを指すには、
文字列$cwd
を使うことができます。
$cwd
と.
(ピリオド)
とは同じではありません。
前者は、
GDBセッション内においてカレントな作業ディレクトリが変更された場合、
変更されたディレクトリを指します。
これに対して後者は、
ソース・パスへの追加を行ったときに、
その時点におけるカレント・ディレクトリに展開されてしまいます。
directory
show directories
ソース・パスの中に、 不要となってしまったディレクトリが混在していると、 GDBが誤ったバージョンのソースを見つけてしまい、 混乱をもたらすことがあります。 以下の手順によって、 正常な状態にすることができます。
directory
コマンドを引数なしで実行します。
directory
コマンドに適切な引数を指定して実行します。
すべてのディレクトリを、
1回のコマンド実行で追加することができます。
info line
コマンドを使用してソース行をプログラム・アドレスに
(あるいは、
プログラム・アドレスをソース行に)
対応付けすることができます。
また、
disassemble
コマンドを使用して、
あるアドレス範囲をマシン命令として表示することもできます。
GNU Emacsモードで実行されている場合、
現在のinfo line
コマンドは、
指定された行を示す矢印を表示します。
また、
info line
コマンドは、
アドレスを16進形式だけではなくシンボリック形式でも表示します。
info line linespec
list
コマンド
(see Printing source lines)
が理解できる任意の形式によってソース行を指定することができます。
例えば、
info line
コマンドによって、
関数m4_changequote
の最初の行に対応するオブジェクト・コードの位置を知ることができます。
(gdb) info line m4_changecom Line 895 of "builtin.c" starts at pc 0x634c and ends at 0x6350.
また、
(linespecの形式として*addr
を使用することで)
ある特定のアドレスがどのソース行に含まれているのかを問い合わせることができます。
(gdb) info line *0x63ff Line 926 of "builtin.c" starts at pc 0x63e4 and ends at 0x6404.
info line
の実行後、
x
コマンドのデフォルト・アドレスは、
その行の先頭アドレスに変更されます。
これにより、
マシン・コードの調査を開始するにはx/i
を実行するだけで十分となります
(see Examining memory)。
また、
このアドレスはコンビニエンス変数$_
の値として保存されます
(see Convenience variables)。
disassemble
以下の例は、 あるアドレス範囲のHP PA-RISC 2.0コードを逆アセンブルした結果を示しています。
(gdb) disas 0x32c4 0x32e4 Dump of assembler code from 0x32c4 to 0x32e4: 0x32c4 <main+204>: addil 0,dp 0x32c8 <main+208>: ldw 0x22c(sr0,r1),r26 0x32cc <main+212>: ldil 0x3000,r31 0x32d0 <main+216>: ble 0x3f8(sr4,r31) 0x32d4 <main+220>: ldo 0(r31),rp 0x32d8 <main+224>: addil -0x800,dp 0x32dc <main+228>: ldo 0x588(r1),r26 0x32e0 <main+232>: ldil 0x3000,r31 End of assembler dump.
アーキテクチャによっては、 一般に使用される命令ニーモニックを複数持つものや、 異なる構文を持つものがあります。
set assembly-language instruction-set
disassemble
コマンドまたはx/i
コマンドによってプログラムの逆アセンブルを行う際に使用する
命令セットを選択します。
現在のところ、
このコマンドは、
Intel x86ファミリに対してのみ定義されています。
instruction-setは、
i386
とi8086
のいずれかにセットすることができます。
デフォルトはi386
です。
ユーザ・プログラムの中のデータを調べる通常の方法は、
print
コマンド
(省略形はp
)、
またはそれと同義のコマンドである
inspect
コマンドを使用することです。
これは、
ユーザ・プログラムが記述された言語
(see Using GDB with Different Languages)
による式を評価し、
その値を出力するものです。
print exp
print /f exp
/f
を指定することで、
他の形式を選択することも可能です。
/f
のfは形式を指定する文字です。
see Output formats。
print
print /f
データを調べるためのより低レベルの方法は、
x
コマンドを使うことです。
これは、
指定されたアドレスのメモリ上のデータを、
指定された形式で表示するものです。
See Examining memory。
型に関する情報に関心があるとき、
また、
構造体
やクラス
のフィールドがどのように宣言されているかという点に関心があるときは、
print
コマンドではなくptype exp
コマンドを使用してください。
See Examining the Symbol Table。
print
コマンド、
および、
ほかの多くのGDBコマンドは、
式を受け取って、
その値を評価します。
ユーザの使用しているプログラミング言語によって定義されている定数、
変数、
演算子は、
いずれもGDBにおける式の中で有効です。
これには、
条件式、
関数呼び出し、
キャスト、
文字列定数が含まれます。
しかし、
プリプロセッサの#define
コマンドによって定義されるシンボルは、
残念ながら含まれません。
現在のGDBは、
ユーザの入力する式において配列定数をサポートします。
その構文は、
{element, element...}です。
例えば、
コマンドprint {1, 2, 3}
を使用して、
ターゲット・プログラム内でmalloc()
によって獲得されたメモリ内に配列を作成することができます。
C言語は大変広汎に使用されているので、 このマニュアルの中で示される例の中の式はC言語で記述されています。 他の言語での式の使い方に関する情報については、 See Using GDB with Different Languages。
この節では、 プログラミング言語によらずGDBの式で使用できる演算子を説明します。
キャストは、 C言語のみならず、 すべての言語でサポートされています。 これは、 メモリ内のあるアドレスにある構造体を調べるのに、 数値をポインタにキャストするのが大変便利であるからです。
プログラミング言語によらず共通に使用可能な演算子に加えて、 GDBは以下の演算子をサポートしています。
@
@
は、
メモリの一部を配列として処理するための2項演算子です。
詳細については、
See Artificial arrays。
::
::
によって、
それを定義している関数またはファイルを特定して、
変数を指定することができます。
See Program variables。
{type} addr
最も一般的に使用される式は、 ユーザ・プログラム内部の変数名です。
式の中の変数は、 選択されたスタック・フレーム (see Selecting a frame) 内において解釈されます。 これは、 以下の2つのいずれかとなります。
あるいは
つまり、
以下の例において、
ユーザ・プログラムが関数foo
を実行中は、
変数a
を調べたり使用したりすることができますが、
変数b
を使用したり調べたりすることができるのは、
b
が宣言されているブロックの内部をユーザ・プログラムが実行中である場合に限られます。
foo (a) int a; { bar (a); { int b = test (); bar (b); } }
ただし、 これには1つ例外があります。 特定の1ソース・ファイルをスコープとする変数や関数は、 たとえ現在の実行箇所がそのファイルの中ではなくても、 参照することができます。 しかし、 このような変数または関数が (異なるソース・ファイル中に) 同じ名前で複数個存在するということがありえます。 このような場合、 その名前を参照すると予期できない結果をもたらします。 2つのコロンを並べる記法によって、 特定の関数またはファイルの中の静的変数を指定することができます。
file::variable function::variable
ここでfileまたはfunctionは、
静的変数variableのコンテキスト名です。
ファイル名の場合は、
引用符を使用することによって、
GDBがファイル名を確実に1つの単語として解釈するようにさせることができます。
例えば、
ファイルf2.c
の中で定義されたグローバル変数x
の値を表示するには、
(gdb) p 'f2.c'::x
のようにします。
このような::
の用途が、
これと非常によく似ているC++における::
の用途と衝突することは非常に稀です。
GDBは、
式の内部においてC++のスコープ解釈演算子の使用もサポートしています。
注意: ときどき、 新しいスコープに入った直後やスコープから出る直前に、 関数内部の特定の箇所から見ると、 ローカル変数の値が正しくないように見えることがあります。マシン命令単位でステップ実行を行っているときに、 このような問題を経験することがあるかもしれません。 これは、 ほとんどのマシンでは、 (ローカル変数定義を含む) スタック・フレームのセットアップに複数の命令が必要となるからです。 マシン命令単位でステップ実行を行う場合、 スタック・フレームが完全に構築されるまでの間は、 変数の値が正しくないように見えることがあります。 スコープから出るときには、 スタック・フレームを破棄するのに、 通常複数のマシン命令が必要とされます。 それらの命令群の中をステップ実行し始めた後には、 ローカル変数の定義は既に存在しなくなっているかもしれません。
このようなことは、 コンパイラが重要な最適化を実施する場合にも、 発生する可能性があります。 常に正確な値が見えることを確実にするためには、 コンパイルの際に、 すべての最適化を行わないようにします。
メモリ内に連続的に配置されている同一型のオブジェクトを表示することが役に立つことがよくあります。 配列の一部や動的にサイズの決定される配列にアクセスするのに、 そこへのポインタしかプログラム内部に存在しないような場合です。
これは、
2項演算子@
を使用して、
連続したメモリ範囲を人工配列として参照することで可能です。
@
の左側のオペランドは、
参照したい配列の最初の要素で、
かつ、
1個のオブジェクトでなければなりません。
また、
右側のオペランドは、
その配列の中の参照したい部分の長さでなければなりません。
結果は、
その要素がすべて左側の引数と同型である配列の値です。
第1の要素は左側の引数そのものです。
第2の要素は、
第1の要素を保持するメモリ域の直後のメモリ上から取られます。
これ以降の要素も同様です。
以下に例を示します。
プログラムが以下のようになっているとしましょう。
int *array = (int *) malloc (len * sizeof (int));
以下を実行することで、
array
の内容を表示することができます。
p *array@len
@
の左側のオペランドは、
メモリ上に実在するものでなければなりません。
このような方法で@
によって作成された配列の値は、
配列の添字付けの見地からは他の配列と同様に振る舞い、
式の中で使用された場合は強制的にポインタとして扱われます。
人工配列は、
一度表示された後、
値ヒストリ
(see Value history)
を通して式の中に現れることがよくあります。
人工配列を作成するもう1つの方法は、 キャストを使用することです。 これによって、 ある値を配列として解釈し直します。 この値は、 メモリ上に実在するものでなくてもかまいません。
(gdb) p/x (short[2])0x12345678 $1 = {0x1234, 0x5678}
ユーザの便宜を考慮して、
(例えば、
(type[])value
のように)
配列の長さが省略された場合
その値を満たすサイズを
(sizeof(value)/sizeof(type)
のように)
GDBが計算します。
(gdb) p/x (short[])0x12345678 $2 = {0x1234, 0x5678}
ときには、
人工配列の機構では十分でないことがあります。
かなり複雑なデータ構造では、
関心のある要素が連続的に並んでいないことがあります。
例えば、
配列の中のポインタの値に関心がある場合です。
このような状況において役に立つ回避策の1つに、
関心のある値のうち最初のものを表示する式の中のカウンタとしてコンビニエンス変数
(see Convenience variables)
を使用し、
<RET>キーによってその式を繰り返し実行することです。
例えば、
構造体へのポインタの配列dtab
があり、
個々の構造体のフィールドfv
の値に関心があるとしましょう。
以下に、
この場合の例を示します。
set $i = 0 p dtab[$i++]->fv <RET> <RET> ...
デフォルトでは、 GDBはデータの型にしたがって値を表示します。 ときには、 これが望ましくない場合もあります。 例えば、 数値を16進で表示したい場合やポインタを10進で表示したい場合があるでしょう。 あるいは、 メモリ内のある特定のアドレスのデータを文字列や命令として表示させたい場合もあるでしょう。 このようなことをするためには、 値を表示するときに出力フォーマットを指定します。
出力フォーマットの最も単純な使用方法は、
既に評価済みの値の表示方法を指定することです。
これは、
print
コマンドの最初の引数をスラッシュとフォーマット文字で開始することで行います。
サポートされているフォーマット文字は、
以下のとおりです。
x
d
u
o
t
t
はtwoを省略したものです。
1
a
(gdb) p/a 0x54320 $3 = 0x54320 <_initialize_vx+396>
c
f
例えば、 プログラム・カウンタの値を16進数で表示する (see Registers) には、 以下を実行してください。
p/x $pc
スラッシュの前にはスペースが必要ではないことに注意してください。 これは、 GDBのコマンド名にはスラッシュを含めることができないからです。
値ヒストリの最後の値を異なる形式で再表示するには、
print
コマンドに対して式を指定せずにフォーマットだけを指定して実行します。
例えば、
p/x
を実行すると最後の値を16進で再表示します。
コマンドx
(examineのx)
を使用することで、
ユーザ・プログラム内のデータ型にかかわらず、
メモリ上の値をいくつかの形式で調べることができます。
x/nfu addr
x addr
x
x
コマンドを使用してください。
n、
f、
uはいずれも、
どれだけのメモリをどのようにフォーマットして表示するかを指定するための、
必須ではないパラメータです。
addrは、
メモリの表示を開始するアドレスを指定する式です。
nfuの部分にデフォルトを使用するのであれば、
スラッシュ/
は必要ありません。
いくつかのコマンドによって、
addrに対して便利なデフォルト値を指定することができます。
print
コマンドによって使用されるフォーマット、
s
(NULL文字で終了する文字列)、
i
(マシン命令)
のいずれかを指定します。
初期状態では、
デフォルトはx
(16進)
です。
デフォルトは、
x
コマンドまたはprint
コマンドを実行するたびに変更されます。
b
h
w
g
x
コマンド実行時に単位の大きさを指定するたびに、
その大きさが、
次にx
コマンドを実行する際のデフォルトになります
(フォーマットs
および
i
については、
単位の大きさは無視されます。
これらについては、
通常、
単位の大きさを指定しません)。
info breakpoints
(デフォルトは、
最後に表示されたブレイクポイントのアドレスに設定されます)、
info line
(デフォルトは、
行の先頭アドレスに設定されます)、
およびprint
コマンド
(メモリ内の値を表示するのに使用した場合)
です。
例えば、
x/3uh 0x54320
は、
先頭アドレス0x54320
から始めて、
メモリ上の3個のハーフ・ワード
(h
)
の値を、
符号なし10進整数値
(u
)
としてフォーマットして表示するよう求める要求です。
また、
x/4xw $sp
は、
スタック・ポインタ
($sp
については、
see Registers)
の上位4ワード
(w
)
のメモリの内容を16進
(x
)
で表示します。
単位の大きさを示す文字と出力フォーマットを指定する文字とは異なるので、
単位の大きさとフォーマットのどちらが前にくるべきかを記憶しておく必要はありません。
どちらを先に記述しても動作します。
4xw
という出力指定と4wx
という出力指定とは、
全く同一の意味を持ちます
(ただし、
繰り返し回数nは最初に指定しなければなりません。
wx4
ではうまく動きません)。
単位の大きさuは、
フォーマットs
およびi
については無視されますが、
繰り返し回数nを使用したいことがあるかもしれません。
例えば、
3i
はオペランドも含めて3つのマシン命令を表示したいということを指定しています。
disassemble
コマンドは、
マシン命令を調べる別の方法を提供してくれます。
See Source and machine code。
x
コマンドへの引数のデフォルトはすべて、
x
コマンドを使用してメモリ上を連続的に参照するために最少の情報だけを指定すればよいように設計されています。
例えば、
x/3i addr
によってマシン命令を調べた後、
x/7
とするだけで、
続く7個のマシン命令を調べることができます。
<RET>キーによってx
コマンドを繰り返し実行する場合は、
前回の繰り返し回数nが再度使用されます。
その他の引数も、
後続のx
コマンド使用時のデフォルトになります。
x
コマンドによって表示されるアドレスや内容は、
値ヒストリに保存されません。
これらの数がしばしば膨大になり、
邪魔になるからです。
その代わりにGDBは、
これらの値をコンビニエンス変数$_
および$__
の値として、
後続の式の内部で使用できるようにします。
x
コマンドを実行後、
最後に調べられたアドレスは、
コンビニエンス変数$_
の値として式の中で使用することができます。
また、
GDBによって調べられたそのアドレスの内容は、
コンビニエンス変数$__
の値として使用可能です。
x
コマンドに繰り返し回数が指定されている場合、
保存されるのは、
最後に表示されたメモリ単位のアドレスとその内容です。
これは、
最後の出力行にいくつかのメモリ単位が表示されている場合は、
最後に表示されたアドレス値と一致しません。
ある1つの式の値を (それがどのように変化するかを見るために) 頻繁に表示したい場合は、 その式を自動表示リストに加えて、 ユーザ・プログラムが停止するたびに、 GDBがその値を表示するようにするとよいでしょう。 リストに加えられた個々の式には、 それを識別するための番号が割り当てられます。 ある式をリストから削除する際に、 その番号を指定します。 自動表示は、 例えば以下のように表示されます。
2: foo = 38 3: bar[5] = (struct hack *) 0x3804
ここでは、
項目番号、
式、
および、
その式の現在の値が表示されます。
x
コマンドやprint
コマンドによって手動で表示を要求する場合と同様、
好みの出力フォーマットを指定することができます。
実は、
display
コマンドは、
ユーザのフォーマットの指定の詳細度によって、
print
コマンドとx
コマンドのいずれを使用するかを決定しています。
単位の大きさが指定された場合や、
x
コマンドでしかサポートされていない2つのフォーマット
(i
とs
)
のいずれかが指定された場合には、
x
コマンドが使用されます。
それ以外の場合は、
print
コマンドが使用されます。
display exp
コマンドの実行後に<RET>キーを押しても、
display
コマンドは繰り返し実行されません。
display/fmt exp
display/fmt addr
i
、
s
を指定した場合、
あるいは、
単位の大きさ、
単位の数を指定した場合は、
ユーザ・プログラムが停止するたびに調べるメモリ・アドレスとして式addrを追加します。
ここで「調べる」というのは、
実際にはx/fmt addr
を実行することを意味します。
See Examining memory。
例えば、
display/i $pc
は、
ユーザ・プログラムが停止するたびに、
次に実行されるマシン命令を見るのに便利です
($pc
は、
プログラム・カウンタを指すのに一般に使用される名前です。
see Registers)。
undisplay dnums...
delete display dnums...
undisplay
コマンドを実行後に<RET>キーを押しても、
コマンドは再実行されません
(仮に再実行されてしまうとすると、
No display number ...
というエラーになるだけです)。
disable display dnums...
enable display dnums...
display
info display
表示される式がローカル変数への参照を含む場合、
そのローカル変数がセットアップされているコンテキストの範囲外では、
その式は無意味です。
このような式は、
その中の変数の1つでも定義されないコンテキストが実行開始されると表示不可になります。
例えば、
引数last_char
を取る関数の内部でdisplay last_char
コマンドを実行すると、
その関数の内部でユーザ・プログラムが実行を停止し続ける間は、
GDBはこの引数を表示します。
ほかの箇所
(last_char
という変数が存在しない箇所)
で停止したときには、
自動的に表示不可となります。
次にユーザ・プログラムがlast_char
が意味を持つ箇所で停止したときには、
再びその式の表示を可能にすることができます。
これらの設定は、どのプログラミング言語で記述されたプログラムのデバッグにも便利です。
set print address
set print address on
on
です。
例として、
set print address on
のときのスタック・フレームの表示結果を示します。
(gdb) f #0 set_quotes (lq=0x34c78 "<<", rq=0x34c88 ">>") at input.c:530 530 if (lquote != def_lquote)
set print address off
set print address off
のときに前の例と同一のスタック・フレームを表示すると、
以下のようになります。
(gdb) set print addr off (gdb) f #0 set_quotes (lq="<<", rq=">>") at input.c:530 530 if (lquote != def_lquote)
set print address off
を使用することで、
GDBのインターフェイスからマシンに依存する表示を取り除くことができます。
例えば、
print address off
を指定してあれば、
ポインタ引数の有無にかかわらず、
すべてのマシン上において同一のバックトレース情報を得るはずです。
show print address
info line *0x4537
のように、
info line
コマンドを実行することです。
または、
シンボリックなアドレスを表示するときに、
一緒にソース・ファイルや行番号を表示するようGDBを設定する方法もあります。
set print symbol-filename on
set print symbol-filename off
show print symbol-filename
シンボルのソース・ファイル名と行番号を表示するのが役に立つもう1つの状況として、 コードを逆アセンブルする場合があります。 GDBが、 個々の命令に対応する行番号とソース・ファイルを表示してくれます。
また、 アドレスをシンボリック形式で表示させるのは、 そのアドレスと、 そのアドレスより前にあるシンボルのうち、 そのアドレスに最も近い位置にあるものとの間が適度に接近している場合に限定させたい こともあるもでしょう。
set print max-symbolic-offset max-offset
show print max-symbolic-offset
あるポインタがどこを指しているか定かではない場合には、
set print symbol-filename on
を試みてください。
こうすれば、
p/a pointer
を使用して、
そのポインタが指している変数の名前とソース・ファイル上の位置が分かります。
これは、
アドレスをシンボリック形式で解釈します。
例えば以下の例では、
ある変数ptt
がファイルhi2.c
内で定義された別の変数t
を指していることを、
valueGDBNが教えてくれています。
(gdb) set print symbol-filename on (gdb) p/a ptt $4 = 0xe008 <t in hi2.c>
注意: ローカル変数を指すポインタについては、 たとえ適切なset print
オプションが有効になっていても、p/a
はそのポインタによって参照される変数のシンボル名やファイル名を表示しません。
異なる種類のオブジェクトについては、 他の設定によって表示方法が制御されます。
set print array
set print array on
off
です。
set print array off
show print array
set print elements number-of-elements
set print elements
コマンドで設定された数に達すると、
そこで表示が停止されます。
この上限は、
文字列の表示にも適用されます。
number-of-elementsに0をセットすると、
要素は無制限に表示されます。
show print elements
set print null-stop
set print pretty on
$1 = { next = 0x0, flags = { sweet = 1, sour = 1 }, meat = 0x54 "Pork" }
set print pretty off
$1 = {next = 0x0, flags = {sweet = 1, sour = 1}, \ meat = 0x54 "Pork"}
これがデフォルトの形式です。
show print pretty
set print sevenbit-strings on
\
nnnという表記法で表示します。
この設定は、英語
(ASCII)
環境において、
文字の最上位ビットをマーカや「メタ」ビットとして使用する場合に最適です。
set print sevenbit-strings off
show print sevenbit-strings
set print union on
set print union off
show print union
例えば、 以下のように宣言されている場合、
typedef enum {Tree, Bug} Species; typedef enum {Big_tree, Acorn, Seedling} Tree_forms; typedef enum {Caterpillar, Cocoon, Butterfly} Bug_forms; struct thing { Species it; union { Tree_forms tree; Bug_forms bug; } form; }; struct thing foo = {Tree, {Acorn}};
set print union on
が有効な場合、
p foo
は以下のような表示を行います。
$1 = {it = Tree, form = {tree = Acorn, bug = Cocoon}}
また、
set print union off
が有効な場合、
p foo
は以下のような表示を行います。
$1 = {it = Tree, form = {...}}
以下の設定は、 C++プログラムをデバッグしているときに関係があります。
set print demangle
set print demangle on
on
です。
show print demangle
set print asm-demangle
set print asm-demangle on
off
です。
show print asm-demangle
set demangle-style style
auto
gnu
g++
)エンコーディング・アルゴリズムに基づいてデコードします。
これが、
デフォルトです。
hp
aCC
)エンコーディング・アルゴリズムに基づいてデコードします。
lucid
lcc
)エンコーディング・アルゴリズムに基づいてデコードします。
arm
cfront
によって生成された実行モジュールをデバッグするのに十分ではありません。
これを可能にするためには、
GDBをさらに拡張する必要があります。
show demangle-style
set print object
set print object on
set print object off
show print object
set print static-members
set print static-members on
on
です。
set print static-members off
show print static-members
set print vtbl
set print vtbl on
off
です。
set print vtbl off
show print vtbl
print
コマンドにより表示された値は、
GDBの
値ヒストリに保存されます。
これによりユーザは、
これらの値をほかの式の中で参照することができます。
値は、
シンボル・テーブルが
(例えば、
file
コマンドやsymbol-file
コマンドにより)
再読み込みされるか破棄されるまで、
維持されます。
シンボル・テーブルが変更されると、
値ヒストリが破棄されるのは、
その中の値が、
シンボル・テーブル内で定義されている型を参照しているかもしれないからです。
表示される値はヒストリ番号を与えられ、
この番号によって参照することができます。
この番号は1から始まる連続した整数です。
print
コマンドは、
値に割り当てられたヒストリ番号を、
値の前に$num =
という形で表示します。
ここで、
numがそのヒストリ番号です。
値ヒストリの中の任意の値を参照するには、
$
に続けてヒストリ番号を指定します。
print
コマンドが出力に付加するラベルは、
ユーザにこのことを知らせるためのものです。
$
単体では、
ヒストリ内の最も新しい値を参照し、
$$
はその1つ前の値を参照します。
$$n
は、
最新のものから数えてn番目の値を参照します。
$$2
は$$
の1つ前の値を参照し、
$$1
は$$
と同一、
$$0
は$
と同一です。
例えば、 ユーザがたった今、 構造体へのポインタを表示し、 今度はその構造体の内容を見たいと考えているとしましょう。 この場合は、
p *$
を実行すれば十分です。
また、
連結された構造体があり、
そのメンバのnext
が次の構造体を指すポインタであるとすると、
次の構造体の内容を表示するには、
p *$.next
とします。
このように連結された構造体を次々に表示するには、 このコマンドを繰り返し実行すればよく、 それは<RET>キーによって可能です。
このヒストリは、
式ではなく、
値を記録するという点に注意してください。
x
の値が4のときに、
以下のコマンドを実行すると、
print
コマンドによって値ヒストリに記録される値は、
x
の値が変化したにもかかわらず4のままです。
print x set x=5
show values
p $$9
を10回実行するようなものですが、
両者の違いは、
show values
がヒストリを変更しないという点にあります。
show values n
show values +
show values n
を繰り返し実行するのに<RET>キーを押すことは、
show values +
を実行するのと全く同じ結果をもたらします。
コンビニエンス変数名は、
先頭が$
で始まります。
$
で始まる名前は、
あらかじめ定義されたマシン固有のレジスタ名
(see Registers)
と一致しない限り、
コンビニエンス変数の名前として使用することができます
(これに対して、
値ヒストリの参照名では$
に続けて番号を記述します。
See Value history)。
ユーザ・プログラムの中で変数に値を設定するのと同じように、
代入式を使用してコンビニエンス変数に値を保存することができます。
例えば、
object_ptr
が指すオブジェクトが保持する値を$foo
に保存するには、
以下のようにします。
set $foo = *object_ptr
コンビニエンス変数は、
最初に使用されたときに生成されますが、
新しい値を割り当てるまで、
その値は空
(void
)
です。
値は、
いつでも代入することによって変更可能です。
コンビニエンス変数には決まった型はありません。 コンビニエンス変数には、 既に異なる型のデータが割り当てられている場合でも、 構造体や配列を含めた任意の型のデータを割り当てることができます。 コンビニエンス変数は、 式として使用される場合には、 その時点における値の型を持ちます。
show convenience
show con
です。
コンビニエンス変数の1つの使い方に、 インクリメントされるカウンタや先へ進んでいくポインタとしての使い方があります。 例えば、 構造体配列の中の連続する要素のあるフィールドの値を表示したい場合、 以下のコマンドを<RET>キーで繰り返し実行します。
set $i = 0 print bar[$i++]->contentsGDBによって、 いくつかのコンビニエンス変数が自動的に作成され、 役に立ちそうな値が設定されます。
$_
$_
変数には、
x
コマンドによって最後に調べられたアドレスが自動的に設定されます
(see Examining memory)。
x
コマンドによって調べられるデフォルトのアドレスを提供する他のコマンドも、
$_
にそのアドレスを設定します。
このようなコマンドには、
info line
やinfo breakpoint
があります。
$_
の型は、
x
コマンドによって設定された場合は$__
の型へのポインタであり、
それ以外の場合はvoid *
です。
$__
$__
変数には、
x
コマンドによって最後に調べられたアドレス位置にある値が自動的に設定されます。
型は、
データが表示されたフォーマットに適合するように選択されます。
$_exitcode
$_exitcode
変数には、
デバッグされているプログラムが終了した際の終了コードが自動的に設定されます。
マシン・レジスタの内容は、
先頭が$
で始まる名前を持つ変数として、
式の中で参照することができます。
レジスタの名前は、
マシンによって異なります。
info registers
コマンドを使用することで、
そのマシンで使用されているレジスタの名前を知ることができます。
info registers
info all-registers
info registers regname ...
$
は、
あってもなくてもかまいません。
$pc
と$sp
は、
プログラム・カウンタ・レジスタとスタック・ポインタを指すために使われます。
$fp
は、
カレントなスタック・フレームへのポインタを保持するレジスタを指すために使われます。
$ps
は、
プロセッサの状態を保持するレジスタを指すために使われます。
例えば、
プログラム・カウンタの値を16進数で表示するには、
以下のように実行します。
p/x $pc
また、 次に実行される命令を表示するには、 以下のように実行します。
x/i $pc
さらに、 スタック・ポインタ 2 に4を加えるには、 以下のように実行します。
set $sp += 4
可能な場合にはいつでも、
これら4つの標準的なレジスタ名が使用可能です。
ユーザのマシンが異なる正規のニーモニックを使用している場合でも、
名前の衝突さえ起こらなければ、
使用可能です。
info registers
コマンドにより、
正規名を見ることができます。
例えば、
SPARC上で
info registers
コマンドを実行すると、
プロセッサ・ステータス・レジスタは$psr
と表示されますが、
このレジスタを$ps
として参照することもできます。
レジスタがこの方法で調べられるとき、
GDBは普通のレジスタの内容を常に整数値とみなします。
マシンによっては、
浮動小数点値以外を保持できないレジスタを持つものがあります。
このようなレジスタは、
浮動小数点値を持つものとみなされます。
普通のレジスタの内容を浮動小数点値として参照する方法はありません
(print/f $regname
により、
浮動小数点値として値を表示することはできます)。
レジスタには、
rawとvirtualの2つの異なるデータ形式を取るものがあります。
これは、
オペレーティング・システムによってレジスタの内容が保存されるときのデータ形式が、
ユーザ・プログラムが通常認識しているものと同じではないことを意味しています。
例えば、
68881浮動小数点コプロセッサのレジスタの値は常にextended
(raw)形式で保存されていますが、
C言語によるプログラムは通常double
(virtual)形式を想定しています。
このような場合、
GDBは通常
(ユーザ・プログラムにとって意味のある形式である)
virtual形式だけを扱いますが、
info registers
コマンドはデータを両方の形式で表示してくれます。
通常、
レジスタの値は、
選択されたスタック・フレーム
(see Selecting a frame)
と関係を持つ相対的な値です。
これは、
ユーザにレジスタの値として見えるものは、
選択されたフレームから呼び出されているすべてのスタック・フレームが終了し、
退避されたレジスタの値が復元されたときに、
そのレジスタが持つであろう値です。
ハードウェア・レジスタの本当の値を知りたければ、
最下位のフレームを
(frame 0
で)
選択しなければなりません。
しかし、 GDBは、 コンパイラが生成したコードから、 どこにレジスタが保存されているかを推論する必要があります。 退避されていないレジスタがある場合や、 GDBが退避されたレジスタを見つけることができない場合は、 どのスタック・フレームを選択していても結果は同じです。
set rstack_high_address address
set rstack_high_address
コマンドによってレジスタ・スタックの最終アドレスを指定することによって、
この問題を回避することができます。
引数はアドレスでなければなりません。
0x
を先頭に記述することで、
アドレスを16進数で指定することができます。
show rstack_high_address
構成によっては、 GDBは浮動小数ハードウェアの状態について、 より詳しい情報を提供することができます。
info float
info float
はARMマシンとx86マシンにおいてサポートされています。
異なるプログラミング言語であっても共通点があるのが普通ですが、
その表記法が全く同様であるということはめったにありません。
例えば、
ポインタ
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はその言語を以下に示すものと推定します。
.c
.C
.cc
.cp
.cpp
.cxx
.c++
.f
.F
.ch
.c186
.c286
.mod
.s
.S
さらに、 言語に対してファイル名の拡張子を関連付けすることも可能です。 See Displaying the language。
もしそうしたければ、
言語を手作業で設定することもできます。
そのためには、
コマンド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
型の値を出力することを意味します。
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が自動的にチェックを行うか否かを、
ユーザ・プログラムのソース言語によって決定することもできます。
サポートされている言語のデフォルトの設定については、
See Supported languages。
いくつかの言語、 例えば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では、 列挙型とポインタは数値として表わすことができますので、 これらは算術演算子への正当な引数となります。 特定の言語に関する詳細については、 See Supported languages。 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
になります。
これも個々の言語に固有な性質であり、 場合によっては、 個々のコンパイラやマシンに固有な性質であることもあります。 特定の言語に関する詳細については、 See Supported languages。 GDBは、 範囲チェック機能を制御するためのコマンドをさらにいくつか提供しています。
set check range auto
set check range on
set check range off
set check range warn
show range
@
演算子、
::
演算子、
および{type}addr
(see Expressions)
は、
サポートされている任意の言語において使用することができます。
次節以降で、 個々のソース言語がGDBによってどの程度までサポートされているのかを詳しく説明します。 これらの節は、 言語についてのチュートリアルやリファレンスとなることを意図したものではありません。 むしろ、 GDBの式解析機能が受け付ける式や、 異なる言語における正しい入出力フォーマットのリファレンス・ガイドとしてのみ役に立つものです。 個々の言語については良い書籍が数多く出ています。 言語についてのリファレンスやチュートリアルが必要な場合は、 これらの書籍を参照してください。
CとC++は密接に関連しているので、 GDBの機能の多くは両方の言語に適用できます。このようなものについては、2つの言語を一緒に議論します。
C++のデバッグ機能は、
C++コンパイラとGDBによって協同で実装されています。
したがって、
C++のコードを効率よくデバッグするには、
GNU g++
、
HP ANSI C++コンパイラ(aCC
)などの、
サポートされているC++コンパイラで、
C++のプログラムをコンパイルする必要があります。
GNU C++を使用する場合、
最高の結果を引き出すには、
stabsデバッグ・フォーマット
を使用してください。
g++
のコマンドライン・オプション-gstabs
、
または、
-gstabs+
によって、
このフォーマットを明示的に選択することができます。
詳細については、
Debugging Options
の部分を参照してください。
演算子は、
特定の型の値に対して定義されなければなりません。
例えば、
+
は数値に対しては定義されていますが、
構造体に対しては定義されていません。
演算子は、
型のグループに対して定義されることがよくあります。
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
)に対して定義されています。
::
::
と同一の優先順位を持ちます。
0
(ゼロ)
により指定されます。
16進数定数は、
先頭の0x
または0X
により指定されます。
定数は、
文字l
(エル)
により終わることもあります。
この場合、
定数がlong
型の値として扱われるべきことを意味します。
e[[+]|-]nnn
という形式を取ります。
ここで、
nnnは連続した数字です。
+
は、
正の指数を示す記号で、
必ずしも必要ではありません。
'
)
によって囲まれた単一の文字、
あるいは、
その文字に対応する序数
(通常は、
ASCII値)
です。
引用符の中の単一文字は、
文字またはエスケープ・シーケンスによって表わすことができます。
エスケープ・シーケンスには2つの表記方法があります。
第1の形式は\nnn
で、
nnnはその文字の序数を表わす8進数です。
第2の形式は\x
で、
x
はあらかじめ定義された特別な文字です。
例えば、
\n
は改行を表わします。
"
)
で囲まれたものです。
&
演算子を使用して記述することができます。
{
と}
で囲まれ、
カンマで区切られたリストです。
例えば、
{1,2,3}
は3つの整数値を要素として持つ配列です。
{{1,2}, {3,4}, {5,6}}
は、
3×2の配列です。
また、
{&"hi", &"there", &"fred"}
は3つのポインタを要素として持つ配列です。
注意:
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
への暗黙の参照を許します。
set print address off
を指定しない限り、
常に表示されます。
::
をサポートしています。
プログラム中と同様に、
式の中でこれを使用することができます。
あるスコープが別のスコープの中で定義されることがありえるため、
必要であれば::
を繰り返し使用することができます。
例えば、
scope1::scope2::name
という具合です。
GDBはまた、
CおよびC++のデバッグにおいて、
ソース・ファイルを指定することで名前のスコープを解決することを許します
(see Program variables)。
off
になります。
これは、
作業言語を選択したのがユーザであってもGDBであっても同様です。
GDBが自動的に言語の設定を行うことを許すと、
GDBは、
名前が.c
、
.C
、
.cc
などで終わるソース・ファイルを認識していて、
これらのファイルからコンパイルされたコードの実行を開始するときに、
作業言語をCまたはC++に設定します。
詳細については、
See Having GDB infer the source language。
デフォルトでは、 GDBがCやC++の式を解析するときには、 型チェックは行われません。 しかし、 ユーザが型チェックを有効にすると、 GDBは以下の条件が成立するときに、 2つの変数の型が一致しているとみなします。
typedef
によって同一の型に宣言されている型を持つ。
範囲チェックは、 onに設定されている場合、 数学的演算において実行されます。 配列のインデックスは、 それ自体は配列ではないポインタのインデックスとして使用されることが多いため、 チェックされません。
set print union
コマンドとshow print union
コマンドは共用体型
(union
)
に適用されます。
on
に設定されると、
構造体
(struct
)
やクラス
(class
)
の内部にある共用体
(union
)
はすべて表示されます。
on
でない場合、
それは{...}
と表示されます。
@
オペレータは、
ポインタとメモリ割り当て関数によって作られた動的配列のデバッグに役に立ちます。
See Expressions。
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コマンドラインの単語補完機能を使用して、
利用可能な選択肢を一覧表示させたり、
型のリストを完結させたりすることができます。
この機能の使用方法の詳細については、
See Command completion。
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はエラーとして扱います。
H
を付加することで、
また、
8進数の整数は末尾にB
を付加することで指定されます。
E[+|-]nnn
で、
[+|-]nnn
の部分で希望する指数を指定します。
浮動小数点型定数のすべての数字は、
有効な10進数値でなければなりません。
'
)または2重引用符("
)で囲まれた単一文字より成ります。
文字型定数は、
その文字の序数値
(通常はASCII値)
の後ろにC
を付加することで表現することもできます。
'
)または2重引用符("
)で囲まれた連続する文字から成ります。
C言語のスタイルでのエスケープ・シーケンスも使用できます。
エスケープ・シーケンスに関する簡単な説明については、
See C and C++ constants。
TRUE
およびFALSE
から成ります。
型チェックと範囲チェックがGDBにより自動的に設定される場合、
作業言語がModula-2に変わるたびに、
それらはデフォルトでon
に設定されます。
これは、
作業言語を選択したのがユーザであろうとGDBであろうと同様です。
GDBに自動的に言語を設定させると、
ファイル名の末尾が.mod
であるファイルからコンパイルされたコードに入るたびに、
作業言語はModula-2に設定されます。
詳細については、
See Having GDB set the language automatically。
Modula-2プログラムのデバッグを容易にするために2、 3の修正が施されています。 これは主に、 型に対する厳密性を緩めることによって実現されています。
CHR(nnn)
という形式で表示されます。
:=
)
は、
右側の引数の値を返します。
注意: 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が識別子でない場合は、
エラーになります。
set print
、
show print
の5つのサブ・コマンドvtbl
、
demangle
、
asm-demangle
、
object
、
union
はC/C++にのみ適用されます。
最初の4つはC++に適用され、
最後の1つはCの共用体
(union
)
に適用されます。
これらは、
Modula-2において直接類似するものが存在しません。
@
演算子
(see Expressions)
は、
どの言語においても使用することができますが、
Modula-2においてはあまり役に立ちません。
この演算子は、
動的配列のデバッグを支援することを目的とするものですが、
C/C++では作成できる動的配列は、
Modula-2では作成できません。
しかし、
整数値定数によってアドレスを指定することができるので、
{type}adrexp
は役に立ちます
(see Expressions)。
GDBスクリプトの中では、
Modula-2の不等価演算子#
はコメントの開始記号として解釈されます。
代わりに<>
を使用してください。
ここで説明するコマンドによって、 ユーザ・プログラムの中で定義されているシンボル情報 (変数名、 関数名、 型名) に関する問い合わせを行うことができます。 この情報はユーザ・プログラムのテキストに固有のもので、 プログラムの実行時に変わるものではありません。 GDBはこの情報を、 ユーザ・プログラムのシンボル・テーブルの中、 または、 GDB起動時に指定されたファイル (see Choosing files) の中で見つけるか、 ファイル管理コマンド (see Commands to specify files) の実行によって見つけます。
ときには、
参照する必要のあるシンボルの中に、
GDBが通常は単語の区切り文字として扱う文字が含まれていることがあるかもしれません。
特に多いのが、
他のソース・ファイルの中の静的変数を参照する場合です
(see Program variables)。
ファイル名は、
オブジェクト・ファイルの中にデバッグ・シンボルとして記録されていますが、
GDBは通常、
典型的なファイル名、
例えばfoo.c
を解析して、
3つの単語
foo
、
.
(ピリオド)、
c
であるとみなします。
GDBがfoo.c
を単一のシンボルであると認識できるようにするには、
それを単一引用符で囲みます。
例えば、
p 'foo.c'::x
は、
x
の値をファイルfoo.c
のスコープの中で検索します。
info address symbol
print &symbol
との相違に注意してください。
print &symbol
はレジスタ変数に対しては機能しませんし、
スタック内のローカル変数に対して実行すると、
その変数のカレントなインスタンスの存在するアドレスそのものが表示されます。
whatis exp
whatis
$
のデータ型を表示します。
ptype typename
class class-name
、
struct struct-tag
、
union union-tag
、
enum enum-tag
という形式を取ることができます。
ptype exp
ptype
ptype
はwhatis
と異なります。
例えば、 変数宣言
struct complex {double real; double imag;} v;
に対して、
whatis
、
ptype
はそれぞれ以下のような出力をもたらします。
(gdb) whatis v type = struct complex (gdb) ptype v type = struct complex { double real; double imag; }
whatis
と同様、
引数なしでptype
を使用すると、
値ヒストリの最後の値である$
の型を参照することになります。
info types regexp
info types
i type value
は、
ユーザ・プログラムの中で、
その名前が文字列value
を含むすべての型に関する情報を表示し、
i type ^value$
は、
名前がvalue
そのものである型に関する情報だけを表示します。
このコマンドはptype
とは2つの点で異なります。
まず第1にwhatis
と同様、
詳細な情報を表示しません。
第2に、
型が定義されているすべてのソース・ファイルを一覧表示します。
info source
info sources
info functions
info functions regexp
info fun step
は、
その名前が文字列step
を含むすべての関数を見つけ、
info fun ^step
は、
名前が文字列step
で始まるすべての関数を見つけます。
info variables
info variables regexp
いくつかのシステムにおいては、 ユーザ・プログラムの停止・再起動を伴うことなく、 そのユーザ・プログラムを構成する個々のオブジェクト・ファイルを更新することができます。 例えば、 VxWorksでは、 欠陥のあるオブジェクト・ファイルを再コンパイルして、 実行を継続することができます。 このようなマシン上でプログラムを実行しているのであれば、 自動的に再リンクされたモジュールのシンボルをGDBに再ロードさせることができます。
set symbol-reloading on
set symbol-reloading off
symbol-reloading
の設定はoffのままにするべきです。
さもないと、
(異なるディレクトリやライブラリの中にある)
同じ名前を持ついくつかのモジュールを含むような大きなプログラムをリンクする際に、
GDB
はシンボルを破棄してしまうかもしれません。
show symbol-reloading
symbol-reloading
のカレントな設定
(on
またはoff
)
を表示します。
maint print symbols filename
maint print psymbols filename
maint print msymbols filename
maint print symbols
を使用すると、
GDBは、
完全な詳細情報を入手済みのすべてのシンボルの情報をダンプに含めます。
つまり、
ファイルfilenameには、
GDBがそのシンボルを読み込み済みのファイルに対応するシンボルが反映されます。
info sources
コマンドを使用することで、
これらのファイルがどれであるかを知ることができます。
代わりにmaint print psymbols
を使用すると、
GDB
が部分的にしか知らないシンボルに関する情報もダンプの中に含まれます。
これは、
GDBがざっと読みはしたものの、
まだ完全には読み込んでいないファイルに定義されているシンボルに関する情報です。
最後にmaint print msymbols
では、
GDBが何らかのシンボル情報を読み込んだオブジェクト・ファイルから、
最小限必要とされるシンボル情報がダンプされます。
GDBがどのようにしてシンボルを読み込むかについては、
Commands to specify files
(のsymbol-file
の説明の部分)
を参照してください。
ユーザ・プログラムの中に誤りのある箇所を見つけると、 その明らかな誤りを訂正することで、 その後の実行が正しく行われるかどうかを知りたくなるでしょう。 GDBにはプログラムの実行に変化を与える機能があり、 これを使って実験することで、 その答を知ることができます。
例えば、 変数やメモリ上のある箇所に新しい値を格納すること、 ユーザ・プログラムにシグナルを送ること、 ユーザ・プログラムを異なるアドレスで再起動すること、 関数が完全に終了する前に呼び出し元に戻ることなどが可能です。
ある変数の値を変更するには、 代入式を評価します。 See Expressions。 例えば、
print x=4
は、
変数x
に値4を格納してから、
その代入式の値
(すなわち4)
を表示します。
サポートされている言語の演算子の詳細情報については、
See Using GDB with Different Languages。
代入の結果を表示させることに関心がなければ、
print
コマンドの代わりにset
コマンドを使用してください。
実際のところset
コマンドは、
式の値が表示もされず、
値ヒストリ
(see Value history)
にも入らないということを除けば、
print
コマンドと同等です。
式は、
その結果の入手だけを目的として評価されます。
set
コマンドの引数となる文字列の先頭の部分が、
set
コマンドのサブ・コマンドの名前と一致してしまうような場合には、
ただのset
コマンドではなくset variable
コマンドを使用してください。
このコマンドは、
サブ・コマンドを持たないという点を除けば、
set
コマンドと同等です。
例えば、
ユーザ・プログラムにwidth
という変数がある場合、
set width=13
によってこの変数に値を設定しようとするとエラーになります。
これは、
GDBがset width
というコマンドを持っているためです。
(gdb) whatis width type = double (gdb) p width $4 = 13 (gdb) set width=47 Invalid syntax in expression.
ここで不正な表現となっているのは、
もちろん=47
の部分です。
プログラム内の変数width
に値を設定するには、
以下のようにしてください。
(gdb) set var width=47GDBは、 代入時の暗黙の型変換をC言語よりも多くサポートしています。 整数値を自由にポインタ型変数に格納できますし、 その逆もできます。 また、 任意の構造体を、 同じサイズの別の構造体、 または、 より小さいサイズの別の構造体に変換することができます。
メモリ上の任意の箇所に値を格納するには、
指定されたアドレスにおいて指定された型の値を生成するために、
{...}
を使用します
(see Expressions)。
例えば{int}0x83040
は、
メモリ・アドレス0x83040
を整数値として参照します
(メモリ上における、
ある特定のサイズと表現を示唆しています)。
また、
set {int}0x83040 = 4
は、 そのメモリ・アドレスに値4を格納します。
通常、
ユーザ・プログラムを継続実行するには、
continue
コマンドを使用して、
停止した箇所から継続実行させます。
以下のコマンドを使用することで、
ユーザが選択したアドレスにおいて実行を継続させることができます。
jump linespec
jump
コマンドは、
tbreak
コマンドと組み合わせて使用されます。
See Setting breakpoints。
jump
コマンドは、
カレントなスタック・フレーム、
スタック・ポインタ、
メモリ内の任意の箇所の内容、
プログラム・カウンタを除くレジスタの内容を変更しません。
linespecで指定される行が、
現在実行されている関数とは異なる関数の中にある場合、
それら2つの関数が異なるパターンの引数やローカル変数を期待していると、
奇妙な結果が発生するかもしれません。
このため、
指定された行が、
現在実行されている関数の中にない場合、
jump
コマンドは実行の確認を求めてきます。
しかし、
ユーザがプログラムのマシン言語によるコードを熟知していたとしても、
奇妙な結果の発生することが予想されます。
jump *address
レジスタ$pc
に新しい値を設定することで、
jump
コマンドとほとんど同等の効果を実現することができます。
両者の違いは、
レジスタ$pc
に値を設定しただけでは、
ユーザ・プログラムの実行は再開されないという点にあります。
ユーザが実行を継続するときに、
プログラムが実行を再開するアドレスが変更されるだけです。
例えば、
set $pc = 0x485
を実行すると、
次にcontinue
コマンドやステップ実行を行うコマンドが実行されるとき、
ユーザ・プログラムが停止したアドレスにある命令ではなく、
アドレス0x485
にある命令から実行されることになります。
See Continuing and stepping。
jump
コマンドが最も一般的に使用されるのは、
既に実行されたプログラム部分を、
さらに多くのブレイクポイントを設定した状態で再実行する場合でしょう。
これにより、
実行される処理の内容をさらに詳しく調べることができます。
signal signal
signal 2
とsignal SIGINT
はどちらも、
割り込みシグナルを通知する方法です。
一方、
signalが0であれば、
シグナルを通知することなく実行を継続します。
ユーザ・プログラムがシグナルのために停止し、
通常であれば、
continue
コマンドによって実行を再開するとそのシグナルを検知してしまうような場合に便利です。
signal 0
を実行すると、
プログラムはシグナルを受信することなく実行を再開します。
signal
を実行した後、
<RET>キーを押しても、
繰り返し実行は行われません。
signal
コマンドを実行することは、
シェルからkill
ユーティリティを実行するのと同じではありません。
kill
によってシグナルを送ると、
GDBはシグナル処理テーブルによって何をするべきかを決定します
(see Signals)。
一方、
signal
コマンドは、
ユーザ・プログラムに直接シグナルを渡します。
return
return expression
return
コマンドによって、
呼び出されている関数の実行をキャンセルすることができます。
式expressionを引数に指定すると、
その値が関数の戻り値として使用されます。
return
を実行すると、
GDBは選択されているスタック・フレーム
(および、
その下位にあるすべてのフレーム)
を破棄します。
破棄されたフレームは、
実行を完結する前に復帰したのだと考えればよいでしょう。
戻り値を指定したいのであれば、
その値をreturn
への引数として渡してください。
このコマンドは、 選択されているスタック・フレーム (see Selecting a frame)、 および、 その下位にあるすべてのフレームをポップして、 もともと選択されていたフレームを呼び出したフレームを、 最下位のフレームにします。 つまり、 そのフレームが選択されることになります。 指定された値は、 関数から戻り値を返すのに使用されるレジスタに格納されます。
return
コマンドは実行を再開しません。
関数から復帰した直後の状態で、
プログラムを停止したままにします。
これに対して、
finish
コマンド
(see Continuing and stepping)は、
選択されているスタック・フレームが自然に復帰するまで、
実行を再開、
継続します。
call expr
void
型の戻り値を表示することなく、
式exprを評価します。
ユーザ・プログラムの中からある関数を呼び出したいが、
void型の戻り値を出力させたくない場合、
このprint
コマンドの変種を使用することができます。
void
型でない戻り値は表示され、
値ヒストリに保存されます。
A29Kでは、
ユーザに制御される変数call_scratch_address
によって、
GDBがデバッグ対象の関数を呼び出すときに使用するスクラッチ領域が指定されます。
通常はスクラッチ領域をスタック上に置きますが、
この方法は命令空間とデータ空間を別々に持つシステム上では機能しないため、
これが必要になります。
デフォルトでは、 GDBはユーザ・プログラムの実行コードを持つファイル (あるいは、 コア・ファイル) を書き込み不可の状態でオープンします。 これにより、 マシン・コードを誤って変更してしまうことを防ぐことができます。 しかし、 ユーザ・プログラムのバイナリに意図的にパッチを適用することもできなくなってしまいます。
バイナリにパッチを適用したいのであれば、
set write
コマンドによって明示的にそのことを指定することができます。
例えば、
内部的なデバッグ・フラグを立てたり、
緊急の修正を行いたいということがあるでしょう。
set write on
set write off
set write on
を指定すると、
GDBは実行ファイル
やコア・ファイル
を、
読み込み、
書き込みともに可能な状態でオープンします。
set write off
(デフォルト)
を指定すると、
GDBはこれらのファイルを読み込みしかできない状態でオープンします。
既にファイルをロード済みの場合、
set write
の設定を変更後、
その変更を反映させるためには、
(exec-file
コマンド
、
core-file
コマンド
を使用して)、
そのファイルを再ロードしなければなりません。
show write
実行ファイルやコア・ダンプ・ファイルの名前を指定したい場合があります。 これは通常、 GDBの起動コマンドへの引数を利用して、 起動時に行います (see Getting In and Out of GDB)。
ときには、 GDBのセッション中に、 異なるファイルに切り替える必要がでてくることがあります。 あるいは、 GDBを起動するときに、 使いたいファイルの名前を指定するのを忘れたということもあるかもしれません。 このような場合に、 新しいファイルを指定するGDBコマンドが便利です。
file filename
run
コマンドを使用したときに実行されます。
ユーザがディレクトリを指定せず、
そのファイルがGDBの作業ディレクトリに見つからない場合、
シェルが実行すべきファイルを探すときと同様、
GDBは、
ファイルを探すべきディレクトリのリストとして環境変数PATH
の値を使用します。
path
コマンドによって、
GDB、
ユーザ・プログラムの両方について、
この変数の値を変更することができます。
ファイルをメモリにマップすることのできるシステムでは、
補助的なファイルfilename.syms
に、
ファイルfilenameのシンボル・テーブル情報が格納されることがあります。
このような場合、
GDBは、
filename.syms
というファイルからシンボル・テーブルをメモリ上にマップすることで、
起動に要する時間を短くします。
詳細については、
(以下に説明するfile
コマンド、
symbol-file
コマンド、
add-symbol-file
コマンドを実行する際にコマンドライン上で使用可能な)
ファイル・オプションの-mapped
、
-readnow
の説明を参照してください。
file
file
コマンドを引数なしで実行すると、
GDBは実行ファイル、
シンボル・テーブルに関して保持している情報をすべて破棄します。
exec-file [ filename ]
PATH
を使用します。
filenameを指定しないと、
実行ファイルに関して保持している情報を破棄するよう指示したことになります。
symbol-file [ filename ]
PATH
が検索されます。
同一のファイルから、
シンボル・テーブルと実行プログラムの両方を獲得する場合には、
file
コマンドを使用してください。
symbol-file
を引数なしで実行すると、
GDBがユーザ・プログラムのシンボル・テーブルに関して持っている情報は消去されます。
symbol-file
コマンドが実行されると、
それまでGDBが保持していたコンビニエンス変数、
値ヒストリ、
すべてのブレイクポイント、
自動表示式は破棄されます。
その理由は、
これらの情報の中に、
GDBが破棄した古いシンボル・テーブルのデータの一部である、
シンボルやデータ型を記録する内部データへのポインタが含まれているかもしれないからです。
symbol-file
を一度実行した後に<RET>キーを押しても、
symbol-file
の実行は繰り返されません。
GDBは、
特定の環境用に構成されると、
その環境において生成される標準フォーマットのデバッグ情報を理解するようになります。
GNUコンパイラを使うこともできますし、
ローカルな環境の規約に従う他のコンパイラを使用することもできます。
通常は、
GNUコンパイラを使用しているときに最高の結果を引き出すことができます。
例えばgcc
を使用すると、
最適化されたコードに対してデバッグ情報を生成することができます。
COFFを使用する古いSVR3システムを除外すれば、
ほとんどの種類のオブジェクト・ファイルでは、
symbol-file
コマンドを実行しても、
通常は、
ただちにシンボル・テーブルの全体が読み込まれるわけではありません。
実際に存在するソース・ファイルとシンボルを知るために、
シンボル・テーブルを素早く調べるだけです。
詳細な情報は、
後にそれが必要になったときに、
一度に1ソース・ファイルずつ読み込まれます。
2段階に分けて読み込むという手法は、
GDBの起動時間の短縮を目的としています。
ほとんどの場合、
このような手法が採用されているということに気付くことはありません。
せいぜい、
特定のソース・ファイルに関するシンボル・テーブルの詳細が読み込まれている間、
たまに停止するくらいです
(もしそうしたいのであれば、
set verbose
コマンドを使うことによって、
このようにして停止しているときにはメッセージを表示させることもできます。
See Optional warnings and messages)。
COFFについては、
まだこの2段階方式を実装していません。
シンボル・テーブルが
COFFフォーマットで格納されている場合、
symbol-file
コマンドはシンボル・テーブル・データの全体をただちに読み込みます。
COFFのstabs拡張フォーマット(stabs-in-COFF)では、
デバッグ情報が実際にはstabsフォーマットの内部に存在するため、
2段階方式が実装されていることに注意してください。
symbol-file filename [ -readnow ] [ -mapped ]
file filename [ -readnow ] [ -mapped ]
-readnow
オプションを使用することで、
2段階によるシンボル・テーブル読み込み方式を使わないようにさせることができます。
mmap
システム・コールによるファイルのメモリへのマッピングがシステム上において有効な場合、
もう1つのオプション
-mapped
を使って、
GDBに対して、
再利用可能なファイルの中にユーザ・プログラムのシンボルを書き込ませることができます。
後のGDBデバッグ・セッションは、
(プログラムに変更がない場合)
実行プログラムからシンボル・テーブルを読み込むのに時間を費やすことなく、
この補助シンボル・ファイルからシンボル情報をマップします。
-mapped
オプションを使用することは、
コマンドライン・オプション-mapped
を指定してGDBを起動するのと同じ効果を持ちます。
補助シンボル・ファイルがユーザ・プログラムのシンボル情報をすべて確実に持つように、 両方のオプションを同時に指定することもできます。
myprogという名前のプログラムの補助シンボル・ファイルは、
myprog.syms
という名前になります。
このファイルが存在すると、
(それが、
対応する実行ファイルよりも新しい限り)
ユーザがmyprogをデバッグしようとすると、
GDBは常にそのファイルを使おうとします。
特別なオプションやコマンドは必要ありません。
.syms
ファイルは、
GDBを実行したホスト・マシンに固有のものです。
それは、
GDB内部におけるシンボル・テーブルの正確なイメージを保持しています。
複数のホスト・プラットフォーム間で共用することはできません。
core-file [ filename ]
core-file
を引数なしで実行すると、
コア・ファイルを一切使用しないことを指定したことになります。
ユーザ・プログラムが実際にGDBの管理下で実行中の場合は、
コア・ファイルは無視されることに注意してください。
したがって、
ある時点までユーザ・プログラムを実行させた後に、
コア・ファイルをデバッグしたくなったような場合、
プログラムを実行しているサブ・プロセスを終了させなければなりません。
サブ・プロセスの終了は、
kill
コマンドで行います
(see Killing the child process)。
add-symbol-file filename address
add-symbol-file filename address [ -readnow ] [ -mapped ]
add-symbol-file
コマンドは、
filenameで指定されるファイルから追加的なシンボル・テーブル情報を読み込みます。
filenameで指定されるファイルが
(何か別の方法によって)
実行中のプログラムの中に動的にロードされた場合に、
このコマンドを使用します。
addressは、
ファイルがロードされたメモリ・アドレスでなければなりません。
GDBは独力でこのアドレスを知ることはできません。
addressは式として指定することもできます。
filenameで指定されるファイルのシンボル・テーブルは、
もともとsymbol-file
コマンドによって読み込まれたシンボル・テーブルに追加されます。
add-symbol-file
コマンドは何回でも使用することができます。
新たに読み込まれたシンボル・テーブルのデータは、
古いデータに追加されていきます。
古いシンボル・データをすべて破棄するには、
symbol-file
コマンドを使用してください。
add-symbol-file
コマンドを実行した後に<RET>キーを押しても、
add-symbol-file
コマンドは繰り返し実行されません。
symbol-file
コマンドと同様、
-mapped
オプションと-readnow
オプション使用して、
filenameで指定されるファイルのシンボル・テーブル情報をGDBがどのように管理するかを変更することができます。
add-shared-symbol-file
add-shared-symbol-file
コマンドは、
Motorola 88k用のHarris' CXUXオペレーティング・システム上でのみ使用することができます。
GDBは自動的に共有ライブラリを探しますが、
GDBがユーザの共有ライブラリを見つけてくれない場合には、
add-shared-symbol-file
コマンドを実行できます。
このコマンドは引数を取りません。
section
section
コマンドは、
実行ファイルのsectionセクションのベース・アドレスをaddrに変更します。
これは、
(a.outフォーマットのように)
実行ファイルがセクション・アドレスを保持していない場合や、
ファイルの中で指定されているアドレスが誤っている場合に使うことができます。
個々のセクションは、
個別に変更されなければなりません。
info files
コマンドによって、
すべてのセクションとそのアドレスを一覧表示することができます。
info files
info target
info files
とinfo target
は同義です。
両方とも、
カレント・ターゲット
(see Specifying a Debugging Target)
に関する情報を表示します。
表示される情報には、
GDBが現在使用中の
実行ファイルやコア・ダンプ・ファイル
の名前、
シンボルがそこからロードされたファイルの名前を含みます。
help target
コマンドは、
カレントなターゲットではなく、
すべての可能なターゲットを一覧表示します。
ファイルを指定するすべてのコマンドは、
引数として、
絶対パスによるファイル名と相対パスによるファイル名のどちらでも受け付けます。
GDBは、
常にファイル名を絶対パス名に変換して、
絶対パスの形で記憶します。
GDBは、
HP-UX、
SunOS、
SVr4、
Irix 5、
IBM RS/6000の共有ライブラリをサポートします。
ユーザがrun
コマンドを実行したり、
コア・ファイルを調べようとすると、
GDBは自動的に共有ライブラリからシンボル定義をロードします
(ユーザがrun
コマンドを発行するまでは、
共有ライブラリ内部の関数への参照があっても、
GDBにはそれを理解することができません。
コア・ファイルをデバッグしている場合は、
この限りではありません)。
info share
info sharedlibrary
sharedlibrary regex
share regex
run
コマンド実行時に必要とされる共有ライブラリだけがロードされます。
regexが省略されると、
ユーザ・プログラムによって必要とされるすべての共有ライブラリがロードされます。
シンボル・ファイルの読み込み中に、
GDBはときどき問題にぶつかることがあります。
例えば、
認識できないシンボル・タイプを見つけたり、
コンパイラの出力に既知の問題を発見することがあります。
デフォルトでは、
このようなエラーがあったことを、
GDBはユーザに知らせません。
なぜなら、
このようなエラーは比較的よく見られるものであり、
コンパイラのデバッグをしているような人々だけが関心を持つようなものだからです。
もし、
正しく構築されていないシンボル・テーブルに関する情報を見ることに関心があれば、
set complaints
コマンドを使用することで、
何回問題が発生しようと個々のタイプの問題について1回だけメッセージを出力するよう指示することができますし、
また、
何回問題発生したかを見るためにより多くのメッセージを表示するよう指示することもできます
(see Optional warnings and messages)。
現在のバージョンで表示されるメッセージとその意味を以下に記します。
inner block not inside outer block in symbol
(don't know)
のように表示されることがあります。
block at address out of order
set verbose on
を指定することで、
どのソース・ファイルが関係しているかを知ることができます。
See Optional warnings and messages)。
bad block start address patched
bad string table offset in symbol n
foo
という名前を持つものとみなすことによって、
この問題を回避します。
この結果、
多くのシンボルがfoo
という名前を持つことになってしまうと、
他の問題が発生する可能性があります。
unknown symbol type 0xnn
0xnn
は理解できなかったシンボルの型を16進数で表わしたものです。
GDBは、
このようなシンボル情報を無視することによって、
このエラーを回避します。
通常、
プログラムのデバッグを行うことは可能になりますが、
ある特定のシンボルにアクセスすることができなくなります。
このような問題にぶつかり、
それをデバッグしたいのであれば、
gdb
自身を使ってgdb
をデバッグすることができます。
この場合、
シンボルcomplain
にブレイクポイントを設定し、
関数read_dbx_symtab
まで実行してから、
*bufp
によってシンボルを参照します。
stub type has NULL name
const/volatile indicator missing (ok if using g++ v1.x), got...
info mismatch between compiler and debugger
ターゲットとは、
ユーザ・プログラムが持つ実行環境を指します。
多くの場合、
GDBはユーザ・プログラムと同一のホスト環境上で実行されます。
この場合には、
file
コマンドやcore
コマンドを実行すると、
その副作用としてデバッグ・ターゲットが指定されます。
例えば、
物理的に離れた位置にあるホスト・マシン上でGDBを実行したい場合や、
シリアル・ポート経由でスタンドアロン・システムを制御したい場合、
または、
TCP/IP接続を利用してリアルタイム・システムを制御したい場合などのように、
より多くの柔軟性が必要とされる場合、
target
コマンドを使うことによって、
GDBに設定されたターゲットの種類の中から1つを指定することができます
(see Commands for managing targets)。
ターゲットには3つのクラスがあります。 プロセス、コア・ファイル、 そして、 実行ファイルです。 GDBは同時に、 1クラスにつき1つ、 全体で最高で3つまでアクティブなターゲットを持つことができます。 これにより、 (例えば) コア・ファイルに対して行ったデバッグ作業を破棄することなく、 プロセスを起動してその動作を調べることができます。
例えば、
gdb a.out
を実行すると、
実行ファイルa.out
が唯一のアクティブなターゲットになります。
コア・ファイル
(おそらくは、
前回実行したときにクラッシュしてコア・ダンプしたもの)
を併せて指定すると、
GDBは2つのターゲットを持ち、
メモリ・アドレスを知る必要がある場合には、
それを知るために2つのターゲットを並行して使用します。
この場合、
まずコア・ファイルを参照し、
次に実行ファイルを参照します。
(典型的には、
これら2つのクラスのターゲットは相互に補完的です。
というのも、
コア・ファイルには、
プログラムが持っている変数などの読み書き可能なメモリ域の内容とマシン・ステータスだけがあり、
実行ファイルには、
プログラムのテキストと初期化されたデータだけがあるからです)。
run
コマンドを実行すると、
ユーザの実行ファイルはアクティブなプロセス・ターゲットにもなります。
プロセス・ターゲットがアクティブな間は、
メモリ・アドレスを要求するすべてのGDBコマンドは、
プロセス・ターゲットを参照します。
アクティブなコア・ファイル・ターゲットや
実行ファイル・ターゲットの中のアドレスは、
プロセス・ターゲットがアクティブな間は、
隠された状態になります。
新しいコア・ファイル・ターゲットや実行ファイル・ターゲットを選択するには、
core-file
コマンドやexec-file
コマンドを使用します
(see Commands to specify files)。
既に実行中のプロセスをターゲットとして指定するには、
attach
コマンドを使用します
(see Debugging an already-running process)。
target type parameters
parametersはターゲット・プロトコルによって解釈されるものですが、 典型的には、 接続すべきデバイス名やホスト名、 プロセス番号、 ボーレートなどが含まれます。
target
コマンドを実行した後に<RET>キーを押しても、
target
コマンドは再実行されません。
help target
info target
コマンドまたはinfo files
コマンドを使用します
(see Commands to specify files)。
help target name
set gnutarget args
set gnutarget
コマンドを使用して、
ファイルのフォーマットを指定することもできます。
ほとんどのtarget
コマンドとは異なり、
gnutarget
におけるtarget
は、
マシンではなくプログラムです。
注意:
set gnutarget
でファイル・フォーマットを指定するには、
実際のBFD名を知っている必要があります。
show gnutarget
gnutarget
がどのようなファイル・フォーマットを読むよう設定されているかを表示させるには、
show gnutarget
コマンドを使用します。
gnutarget
を設定していない場合、
個々のファイルのフォーマットをGDBが自動的に決定します。
この場合、
show gnutarget
を実行すると
The current BDF target is "auto"
と表示されます。
以下に、 一般的なターゲットをいくつか示します (GDBの構成によって、 利用可能であったり利用不可であったりします)。
target exec program
target exec program
はexec-file program
と同じです。
target core filename
target core filename
はcore-file filename
と同じです。
target remote dev
/dev/ttya
)
を指定します。
See Remote debugging。
target remote
は、
load
コマンドもサポートするようになりました。
これは、
スタブをターゲット・システム上に持っていく方法が別にあり、
かつ、
ダウンロードが実行されたときに破壊されないようなメモリ域にそれを置くことができる場合にのみ役に立ちます。
target sim
以下のターゲットはすべて、 特定のCPUに固有のものであり、 特定の構成においてのみ利用可能です。
target abug dev
target adapt dev
target amd-eb dev speed PROG
target remote
の場合と同様、
devはシリアル装置です。
speedによって回線速度を指定することができます。
PROGは、
デバッグ対象となるプログラムをPC上のDOSから見た場合の名前です。
See The EBMON protocol for AMD29K。
target array dev
target bug dev
target cpu32bug dev
target dbug dev
target ddb dev
target dink32 dev
target e7000 dev
target es1800 dev
target est dev
target hms dev
device
とspeed
によって、
使用されるシリアル回線と通信速度を制御します。
See GDB and Hitachi Microprocessors。
target lsi dev
target m32r dev
target mips dev
target mon960 dev
target nindy devicename
/dev/ttya
です。
See GDB with a remote i960 (Nindy)。
target nrom dev
target op50n dev
target pmon dev
target ppcbug dev
target ppcbug1 dev
target r3900 dev
target rdi dev
target rdp dev
target rom68k dev
target rombug dev
target sds dev
target sparclite dev
target sh3 dev
target sh3e dev
target st2000 dev speed
target udi keyword
target vxworks machinename
target w89k dev
多くのリモート・ターゲットでは、 接続に成功すると、 実行プログラムのコードをダウンロードすることが必要となります。
load filename
load
コマンドが使用可能になります。
これが利用可能な場合、
実行ファイルfilenameが
(例えば、
ダウンロードやダイナミック・リンクによって)
リモート・システム上でデバッグできるようになることを意味します。
また、
load
コマンドはadd-symbol-file
コマンドと同様、
ファイルfilenameのシンボル・テーブルをGDB内に記録します。
GDBがload
コマンドを提供していない場合、
それを実行しようとすると
「You can't do that when your target is ...
」
というエラー・メッセージが表示されます。
実行ファイルの中で指定されたアドレスに、 ファイルはロードされます。 オブジェクト・ファイルのフォーマットによっては、 プログラムをリンクするときに、 ファイルをロードするアドレスを指定できるものもあります。 これ以外のフォーマット (例えば、 a.out) では、 オブジェクト・ファイルのフォーマットによって固定的にアドレスが指定されます。
VxWorksでload
コマンドを実行すると、
filenameで指定される実行ファイルがカレントなターゲット・システム上で動的にリンクされ、
シンボルがGDBに追加されます。
Intel 960ボードのNindyインターフェイスでは、
load
コマンドはfilenameで指定されるファイルを960側にダウンロードし、
そのシンボルをGDBに追加します。
日立のSH、
H8/300、
H8/500ボード
(see GDB and Hitachi Microprocessors)
に対するリモート・デバッグを選択すると、
load
コマンドはユーザ・プログラムを日立ボードにダウンロードし、
(file
コマンドと同様)
ユーザのホスト・マシン上のGDBのカレントなターゲット実行ファイルとしてオープンします。
load
コマンドを実行した後に<RET>キーを押しても、
load
コマンドは繰り返し実行されません。
MIPS、 PowerPC、 Hitachi SHなどのプロセッサは、 ビッグ・エンディアン、 リトル・エンディアンのどちらのバイト・オーダでも実行することができます。 通常は、 実行ファイルまたはシンボルの中に、 エンディアン種別を指定するビットがあるので、 どちらを使用するかを気にする必要はありません。 しかし、 GDBの認識しているプロセッサのエンディアン種別を手作業で調整することができれば、 便利なこともあるでしょう。
set endian big
set endian little
set endian auto
show endian
これらのコマンドは、 ホスト上でのシンボリック・データの解釈を調整するだけであり、 ターゲット・システムに対しては全く何の影響も持たないということに注意してください。
通常の方法でGDBを実行させることのできないマシン上で実行中のプログラムをデバッグするには、
リモート・デバッグ機能を使うのが便利です。
例えば、
オペレーティング・システムのカーネルのデバッグや、
フル機能を持つデバッガを実行するのに十分な機能を持つ汎用的なオペレーティング・システムを持たない小規模なシステムでのデバッグでは、
ユーザはリモート・デバッグ機能を使うことになるかもしれません。
GDBは、
その構成によっては、
特別なシリアル・インターフェイスやTCP/IPインターフェイスを持ち、
これを特定のデバッグ・ターゲット用に使用することができます。
さらに、
GDBには汎用的なシリアル・プロトコルが組み込まれており
(GDB固有のもので、
特定のターゲット・システムに固有なものではありません)、
リモート・スタブを作成すれば、
これを使用することができます。
リモート・スタブとは、
GDBと通信するためにリモート・システム上で動作するコードです。
GDBの構成によっては、
他のリモート・ターゲットが利用可能な場合もあります。
利用可能なリモート・ターゲットを一覧表示させるには、
help target
コマンドを使用します。
他のマシン上で実行中のプログラムをデバッグするには (ターゲット・マシンをデバッグするには)、 そのプログラムを単独で実行するために通常必要となる事前条件をすべて整える必要があります。 例えば、 Cのプログラムの場合、
crt0
のような名前を持っています。
スタートアップ・ルーチンは、
ハードウェアの供給元から提供されることもありますし、
ユーザが自分で書かなければならないこともあります。
次に、ユーザ・プログラムがシリアル・ポートを使って、GDBを実行中のマシン (ホスト・マシン) と通信できるように準備します。 一般的には、以下のような形になります。
target remote
コマンドを使用するだけです
(see Specifying a Debugging Target)。
特定のリモート・ターゲットでは、
ユーザ・プログラムにスタブをリンクする代わりに、
gdbserver
という補助プログラムを使うこともできます。
詳細については、
See Using the gdbserver
program。
デバッグ・スタブはリモート・マシンのアーキテクチャに固有のものです。
例えば、
SPARCボード上のプログラムをデバッグするにはsparc-stub.c
を使います。
以下に実際に使えるスタブを列挙します。 これらは、 GDBとともに配布されています。
i386-stub.c
m68k-stub.c
sh-stub.c
sparc-stub.c
sparcl-stub.c
各アーキテクチャ用のデバッグ・スタブは、 3つのサブルーチンを提供します。
set_debug_traps
handle_exception
が実行されるよう設定します。
ユーザ・プログラムは、
その先頭付近でこのサブルーチンを明示的に呼び出さなければなりません。
handle_exception
handle_exception
が実行されるよう設定されます。
ユーザ・プログラムが実行中に
(例えば、ブレイクポイントで)
停止すると、
handle_exception
が制御権を獲得し、
ホスト・マシン上のGDBとの通信を行います。
これが、
通信プロトコルが実装されている部分です。
handle_exception
は、
ターゲット・マシン上でGDBの代理として機能します。
それはまず、
ユーザ・プログラムの状態に関する情報を要約して送ることから始めます。
次に、
GDBが必要とする情報を入手して転送する処理を継続します。
これは、
ユーザ・プログラムの実行を再開させるようなGDBコマンドが実行されるまで続きます。
そのようなコマンドが実行されると、
handle_exception
は、
制御をターゲット・マシン上のユーザ・コードに戻します。
breakpoint
handle_exception
に、
つまり事実上GDBに渡されます。
マシンによっては、
シリアル・ポートから文字を受け取るだけでトラップが発生することもあります。
このような場合には、
ユーザ・プログラム自身からbreakpoint
を呼び出す必要はなく、
ホストのGDBセッションからtarget remote
を実行するだけで制御を得ることができます。
これらのどのケースにも該当しない場合、
あるいは、
デバッグ・セッションの開始箇所としてあらかじめ決めてあるところでユーザ・プログラムが停止することを
単に確実にしたいのであれば、
breakpoint
を呼び出してください。
まず最初に、 どのようにしてシリアル・ポートと通信するかをスタブに教えてやる必要があります。
int getDebugChar()
getchar
と同一かもしれません。
これら2つを区別したい場合を考慮して、
異なる名前が使われています。
void putDebugChar(int)
putchar
と同一かもしれません。
これら2つを区別したい場合を考慮して、
異なる名前が使われています。
実行中のユーザ・プログラムをGDBが停止できるようにしたいのであれば、
割り込み駆動型のシリアル・ドライバを使用して、
^C
(control-C文字、
すなわち\003
)
を受信したときに停止するよう設定する必要があります。
GDBはこの文字を使って、
リモート・システムに対して停止するよう通知します。
デバッグ・ターゲットが適切なステータス情報をGDBに対して返せるようにするためには、
おそらく標準のスタブを変更する必要があるでしょう。
最も美しくなく、
しかし最も手っ取り早くこれを実現する方法は、
ブレイクポイント命令を実行することです
(この方法が「美しくない」のは、
GDBがSIGINT
ではなくSIGTRAP
を報告してくる点にあります)。
ユーザが提供する必要のあるルーチンには、 ほかに以下のようなものがあります。
void exceptionHandler (int exception_number, void *exception_address)
386では、
ハンドラが実行されているときに割り込みがマスクされるよう、
exception_addressは割り込みゲートとして組み込まれる必要があります。
そのゲートは特権レベル0
(最も高いレベル)
でなければなりません。
SPARC用のスタブや68k用のスタブは、
exceptionHandler
の助けを借りなくても自分で割り込みをマスクすることができます。
void flush_i_cache()
命令キャッシュを持つターゲット・マシン上のGDBは、 ユーザ・プログラムが安定した状態にあることが この関数によって保証されることを必要とします。
また、次のライブラリ・ルーチンが使用可能であることを確かめなければなりません。
void *memset(void *, int, int)
memset
です。
フリーのlibc.a
を持っていれば、
そこにmemset
があります。
フリーのlibc.a
がなければ、
memset
をハードウェアの供給元から入手するか、
自分で作成する必要があります。
GNU Cコンパイラを使っていないのであれば、
他の標準ライブラリ・サブルーチンも必要になるかもしれません。
これは、
スタブによっても異なりますが、
一般的にスタブは、
gcc
がインライン・コードとして生成する共通ライブラリ・サブルーチンを使用する可能性があります。
要約すると、 ユーザ・プログラムをデバッグする準備が整った後、 以下の手順に従わなければなりません。
getDebugChar
,putDebugChar
,flush_i_cache
,memset
,exceptionHandler
.
set_debug_traps(); breakpoint();
exceptionHook
という変数を提供する必要があります。
通常は、
以下のように使います。
void (*exceptionHook)() = 0;
しかし、
set_debug_traps
が呼び出される前に、
ユーザ・プログラム内のある関数を指すようこの変数を設定すると、
トラップ
(例えば、
バス・エラー)
で停止した後にGDBが処理を継続実行するときに、
その関数が呼び出されます。
exceptionHook
によって指される関数は、
1つの引数付きで呼び出されます。
それは、
int
型の例外番号です。
次にtarget remote
コマンドを使って通信を確立します。
引数には、
シリアル回線に接続された装置名または
(通常はターゲットと接続されたシリアル回線を持つ端末サーバの)
TCPポートを指定することで、
ターゲット・マシンとの通信方法を指定します。
例えば、
/dev/ttyb
という名前の装置に接続されているシリアル回線を使うには、
target remote /dev/ttyb
とします。
TCP接続を使うには、
host:port
という形式の引数を使用します。
例えば、
manyfarms
という名前の端末サーバのポート2828に接続するには、
target remote manyfarms:2828
とします。
ここまでくると、 データの値の調査、 変更、 リモート・プログラムのステップ実行、 継続実行に通常使用するすべてのコマンドを使用することができます。
リモート・プログラムの実行を再開し、
デバッグするのをやめるには、
detach
コマンドを使います。
GDBがリモート・プログラムを待っているときにはいつでも、
割り込み文字
(多くの場合
<C-C>)
を入力すると、
GDBはそのプログラムを停止しようとします。
これは成功することも失敗することもありますが、
その成否は、
リモート・システムのハードウェアやシリアル・ドライバにも依存します。
割り込み文字を再度入力すると、
GDBは以下のプロンプトを表示します。
Interrupted while waiting for the program. Give up (and stop debugging it)? (y or n)
ここでyを入力すると、
GDBはリモート・デバッグ・セッションを破棄します
(後になって再実行したくなった場合には、
接続するためにtarget remote
を再度使用します)。
nを入力すると、
GDBは再び待ち状態になります。
remote.c
に実装されています。
通常は、
これらのサブルーチンに通信処理を任せて、
詳細を無視することができます
(独自のスタブ・ファイルを作成するときでも、
詳細については無視して、
既存のスタブ・ファイルをもとにして作成を始めることができます。
sparc-stub.c
が最もよく整理されており、
したがって最も読みやすくなっています)。
しかし、 場合によっては、 プロトコルについて何かを知る必要が出てくることもあるでしょう。 例えば、 ターゲット・マシンにシリアル・ポートが1つしかなく、 GDBに対して送られてきたパケットを検出したときに、 ユーザ・プログラムが何か特別なことをするようにしたい場合です。
(単一文字による確認メッセージを除く)
すべてのGDBコマンドとそれに対する応答は、
チェックサムを含むパケットとして送信されます。
パケットは、
文字$
で始まり、
文字#
に2桁のチェックサム値が続いて終わります。
$packet info#checksum
ここで、 checksumはpacket infoのすべての文字の値を合計したものを256で割った余りとして計算されます。
ホスト・マシンまたはターゲット・マシンがパケットを受信したとき、
最初に期待される応答は確認メッセージです。
これは単一文字で、
(パッケージが正しく受信されたことを示す)
+
または
(再送要求を示す)
-
です。
ホスト (GDB) がコマンドを送信し、 ターゲット (ユーザ・プログラムに組み込まれたデバッグ・スタブ) が応答としてデータを送信します。 ターゲットは、ユーザ・プログラムが停止したときにも、 データを送信します。
コマンド・パケットは最初の文字で区別されます。 最初の文字がコマンドの種類を表わします。
以下に、
現在サポートされているコマンドをいくつか列挙します
(コマンドの完全なリストについてはgdb/remote.c
を参照してください)。
g
G
maddr,count
Maddr,count:...
c
caddr
s
saddr
k
?
T
現在のGDBは、 レジスタへのライト・スルー・キャッシュを実装していて、 ターゲットが実行された場合のみ、 レジスタを再度読み込みます。
シリアル接続に問題がある場合には、
set remotedebug
コマンドを使うことができます。
これによりGDBは、
シリアル回線経由でリモート・マシンとの間で送受信したすべてのパケットを報告するようになります。
パケット・デバッグ用の情報はGDBの標準出力ストリームに表示されます。
set remotedebug off
によってこの設定が解除され、
show remotedebug
によって現在の設定が表示されます。
gdbserver
プログラムの使用gdbserver
は、
UNIX系システム用の制御プログラムで、
これにより、
通常のデバッグ用スタブをリンクすることなく、
target remote
コマンドによって、
ユーザ・プログラムをリモートのGDBに接続することができます。
gdbserver
は、
デバッグ用スタブに完全に取って代わるものではありません。
gdbserver
は、
GDBが必要とするのと同様のオペレーティング・システムの機能を基本的には必要とするからです。
実際、
リモートのGDBと接続するためにgdbserver
を実行できるシステムであれば、
GDBをローカルに実行することも可能です。
それでも、
gdbserver
はGDBと比較するとかなりサイズが小さいので、
便利なことがあります。
また、
gdbserver
の移植はGDB全体の移植よりも簡単なので、
gdbserver
を使うことで、
新しいシステムでの作業をより早く開始することができます、
最後に、
リアル・タイム・システムの開発をしている場合、
リアル・タイムな操作に関わるトレードオフのために、
例えばクロス・コンパイルなどによって、
他のシステム上で可能な限り多くの開発作業を行ったほうが便利であるということがあるでしょう。
デバッグ作業に関しても、
gdbserver
を使うことでこれと同じような選択を行うことができます。
GDBとgdbserver
は、
シリアル回線またはTCP接続を経由して、
標準的なGDBリモート・シリアル・プロトコルによって通信します。
gdbserver
はユーザ・プログラムのシンボル・テーブルを必要とはしませんので、
スペースの節約が必要であれば、
プログラムをストリップすることができます。
ホスト・システム上のGDBが、
シンボルに関するすべての処理を実行します。
gdbserver
を使うには、
GDBとの通信方法、
ユーザ・プログラムの名前、
ユーザ・プログラムへの引数を教えてやる必要があります。
構文は、
以下のとおりです。
target> gdbserver comm program [ args ... ]
commは
(シリアル回線を使うための)
装置名、
あるいは、
TCPのホスト名とポート番号です。
例えば、
foo.txt
という引数を指定してEmacsをデバッグし、
シリアル・ポート/dev/com1
経由でGDBと通信するには、
以下のように実行します。
target> gdbserver /dev/com1 emacs foo.txt
gdbserver
は、
ホスト側のGDBが通信してくるのを受動的に待ちます。
シリアル回線の代わりにTCP接続を使うには、 以下のようにします。
target> gdbserver host:2345 emacs foo.txt
前の例との唯一の違いは第1引数です。
これは、
ホストのGDBとTCPによって接続することを指定しています。
host:2345
は、
マシンhost
からローカルのTCPポート2345へのTCP接続をgdbserver
が期待していることを意味します
(現在のバージョンでは、
host
の部分は無視されます)。
ターゲット・システム上で既に使われているTCPポートでなければ、
任意の番号をポート番号として選択できます
(例えば、
23
はtelnet
に予約されています)
3。
ここで指定したのと同じポート番号を、
ホスト上のGDBのtarget remote
コマンドで使わなければなりません。
--baud
オプションも必要になります)。
その後、
target remote
コマンドによってgdbserver
との通信を確立します。
引数には、
装置名
(通常は/dev/ttyb
のようなシリアル装置)、
または、
host:PORT
という形式でのTCPポート記述子を指定します。
例えば、
(gdb) target remote /dev/ttyb
では、
シリアル回線/dev/ttyb
を介してgdbserver
と通信します。
また、
(gdb) target remote the-target:2345
では、
ホストthe-target
上のポート2345に対するTCP接続によって通信します。
TCP接続を使う場合には、
target remote
コマンドを実行する前に、
gdbserver
を起動しておかなければなりません。
そうしないと、エラーになります。
エラー・テキストの内容はホスト・システムによって異なりますが、
通常はConnection refused
のような内容です。
gdbserve.nlm
プログラムの使用gdbserve.nlm
はNetWareシステムでの制御プログラムです。
これによって、
target remote
コマンドでユーザ・プログラムをリモートのGDBに接続することができます。
GDBとgdbserve.nlm
は、
標準のGDBリモート・シリアル・プロトコルを使って、
シリアル回線経由で通信します。
gdbserve.nlm
はユーザ・プログラムのシンボル・テーブルを必要とはしませんので、
スペースの節約が必要であれば、
プログラムをストリップすることができます。
ホスト・システム上のGDBが、
シンボルに関わるすべての処理を実行します。
gdbserve.nlm
を使うには、
GDBとの通信方法、
ユーザ・プログラムの名前、
ユーザ・プログラムの引数を教えてやる必要があります。
構文は、
以下のとおりです。
load gdbserve [ BOARD=board ] [ PORT=port ] [ BAUD=baud ] program [ args ... ]
boardとportがシリアル回線を指定します。 baudは接続に使われるボーレートを指定します。 portとnodeのデフォルト値は0、 baudのデフォルト値は9600 bpsです。
例えば、
foo.txt
という引数を指定してEmacsをデバッグし、
シリアル・ポート番号2、
ボード1を経由して19200 bpsの接続でGDBと通信するには、
以下のように実行します。
load gdbserve BOARD=1 PORT=2 BAUD=19200 emacs foo.txt
--baud
オプションも必要になります)。
その後、
target remote
コマンドによって
gdbserve.nlm
との通信を確立します。
引数には、
装置名
(通常は/dev/ttyb
のようなシリアル装置)
を指定します。
例えば、
(gdb) target remote /dev/ttyb
は、
シリアル回線/dev/ttyb
を経由してgdbserve.nlm
と通信します。
Nindyは、 Intel 960ターゲット・システム用のROM Monitorプログラムです。 Nindyを使ってリモートのIntel 960を制御するようGDBが構成されている場合、 いくつかの方法によってGDBに960との接続方法を教えることができます。
target
コマンドを使う方法
(See Commands for managing targets)
コマンドライン・オプションを一切使わずにgdb
を起動すると、
通常のGDBプロンプトが表示される前に、
使用するシリアル・ポートを指定するよう促されます。
Attach /dev/ttyNN -- specify NN, or "quit" to quit:
このプロンプトに対して、
使いたいシリアル・ポートを示す
(/dev/tty
の後ろの)
サフィックスを入力します。
もしそうしたいのであれば、
プロンプトに空行で答えることによって、
Nindyとの接続を確立せずに起動することもできます。
この場合、
後にNindyと接続したいときにはtarget
コマンドを使います
(see Commands for managing targets)。
接続されたNindy-960ボードとのGDBセッションを開始するための 起動オプションを以下に示します。
-r port
-r /dev/ttya
)、
/dev
配下のデバイス名
(例:-r ttya
)、
tty
固有の一意なサフィックス
(例:-r a
)
のいずれによっても指定することができます。
-O
注意:-O
を指定したにもかかわらず、
実際にはより新しいプロトコルを期待しているターゲット・システムに接続しようとした場合、
接続は失敗します。
この失敗は、
あたかも通信速度の不一致が原因であるかのように見えてしまいます。
GDBは、
異なる回線速度によって再接続を繰り返し試みます。
割り込みによって、
この処理を中断させることができます。
-brk
BREAK
信号を送信するよう、
GDBに対して指定します。
注意:多くのターゲット・システムは、 このオプションが必要とするハードウェアを備えていません。 このオプションは、 少数のボードでしか機能しません。
標準の-b
オプションが、
シリアル・ポート上で使用される回線速度を制御します。
reset
MONTIP
プログラムが必要になります。
また、
AMD社から入手可能なUDI準拠のa29kシミュレータ・プログラムISSTIP
とともにGDBを使うこともできます。
target udi keyword
udi_soc
内のエントリです。
このファイルには、
a29kターゲットに接続するときに使われるパラメータを指定する
キーワード・エントリが含まれます。
udi_soc
ファイルが作業ディレクトリにない場合には、
環境変数UDICONF
にそのパス名を設定しなければなりません。
AMD社は、
PC組み込み用の29K開発ボードを、
DOS上で動作するEBMON
というモニタ・プログラムとともに配布しています。
この開発システムは、
省略してEB29Kと呼ばれます。
UNIXシステム上のGDBを使ってEB29Kボード上でプログラムを実行するには、
まず
(EB29Kを組み込んだ)
PCとUNIXシステムのシリアル・ポートの間をシリアル回線で接続しなければなりません。
以下の節では、
PCのCOM1
ポートとUNIXシステムの/dev/ttya
との間をケーブルで接続してあるものと仮定します。
PC上のDOSで以下のように実行することによって、 PCのポートをセットアップします。
C:\> MODE com1:9600,n,8,1,none
MS DOS 4.0上で実行されているこの例では、 PCポートを通信速度9600 bps、 パリティ・ビットなし、 データ・ビット数8、 ストップ・ビット数1、 リトライなしに設定しています。 UNIX側を設定する際には、 同一の通信パラメータを使わなければなりません。
シリアル回線のUNIX側にPCの制御権を与えるには、 DOSコンソール上で以下のように実行します。
C:\> CTTY com1
(後に、
DOSコンソールに制御を戻したいときには、
CTTY con
コマンドを使うことができます。
ただし、
制御権を持っている装置からこのコマンドを送信する必要があります。
ここでの例では、
COM1
に接続されているシリアル回線を通して送信することになります)。
UNIXのホストからは、
PCと通信するのにtip
やcu
のような通信プログラムを使います。
以下に例を示します。
cu -s 9600 -l /dev/ttya
ここで示されているcu
オプションはそれぞれ、
使用する回線速度とシリアル・ポートを指定しています。
tip
コマンドを使った場合は、
コマンドラインは以下のようなものになるでしょう。
tip -9600 /dev/ttya
ここでtip
への引数として指定した/dev/ttya
の部分には、
システムによって異なる名前を指定する必要があるかもしれません。
使用するポートを含む通信パラメータは、
"remote"記述ファイルにおいてtip
コマンドへの引数と関連付けられます。
通常このファイルは、
システム・テーブル/etc/remote
です。
tip
接続またはcu
接続を使用して
DOSの作業ディレクトリを29Kプログラムが存在するディレクトリに変更し、
PCプログラムEBMON
(AMD社からボードとともに提供されるEB29K制御プログラム)
を起動します。
以下に示す例によく似た、
EBMON
プロンプト#
で終わるEBMON
の初期画面が表示されるはずです。
C:\> G: G:\> CD \usr\joe\work29k G:\USR\JOE\WORK29K> EBMON Am29000 PC Coprocessor Board Monitor, version 3.0-18 Copyright 1990 Advanced Micro Devices, Inc. Written by Gibbons and Associates, Inc. Enter '?' or 'H' for help PC Coprocessor Type = EB29K I/O Base = 0x208 Memory Base = 0xd0000 Data Memory Size = 2048KB Available I-RAM Range = 0x8000 to 0x1fffff Available D-RAM Range = 0x80002000 to 0x801fffff PageSize = 0x400 Register Stack Size = 0x800 Memory Stack Size = 0x1800 CPU PRL = 0x3 Am29027 Available = No Byte Write Available = Yes # ~.
続いて、
cu
プログラムまたはtip
プログラムを終了させます
(上の例では、
EBMON
プロンプトにおいて~.
を入力することで終了させています)。
EBMON
は、
GDBが制御権を獲得できる状態で、
実行を継続します。
この例では、
PCとUNIXシステムの両方に同一の29Kプログラムが確実に存在するようにするのに、
おそらく最も便利であろうと思われる方法を使うことを仮定しました。
それは、
PC/NFSによる接続で、
UNIXホストのファイル・システムの1つをPCのG:
ドライブとする方法です。
PC/NFS、
あるいは、
2つのシステム間を接続する類似の方法がない場合、
フロッピ・ディスクによる転送など、
UNIXシステムからPCへ29Kプログラムを転送するための他の手段を準備する必要があります。
GDBは、
シリアル回線経由で29Kプログラムをダウンロードすることはしません。
最後に、
UNIXシステム上の29Kプログラムが存在するディレクトリにcd
コマンドによって移動して、
GDBを起動します。
引数には、
29Kプログラムの名前を指定します。
cd /usr/joe/work29k gdb myfoo
これでtarget
コマンドが使えるようになります。
target amd-eb /dev/ttya 9600 MYFOO
この例では、
ユーザ・プログラムはmyfoo
と呼ばれるファイルであると仮定しています。
target amd-eb
に対して最後の引数として指定するファイル名は、
DOS上でのプログラム名でなければならない点に注意してください。
この例では単にMYFOO
となっていますが、
DOSのパス名を含むこともできますし、
転送メカニズムによっては、
UNIX側での名前とは似ても似つかないものになることもあるでしょう。
ここまでくると、
好きなようにブレイクポイントを設定することができます。
29Kボード上でのプログラムの実行を監視する準備が整えば、
GDBのrun
コマンドを使います。
リモート・プログラムのデバッグを停止するには、
GDBのdetach
コマンドを使います。
PCの制御をPCコンソールに戻すには、GDBセッションが終了した後に、
EBMON
にアタッチするために、
もう一度tip
またはcu
を使います。
その後、
q
コマンドによってEBMON
をシャットダウンし、
DOSのコマンドライン・インタープリタに制御を戻します。
CTTY con
と入力して、
入力されたコマンドがメインのDOSコンソールによって受け取られるようにし、
~.を入力してtip
またはcu
を終了させます。
target amd-eb
コマンドは、
接続に関わる問題のデバッグを支援するため、
カレントな作業ディレクトリにeb.log
というファイルを作成します。
eb.log
は、
EBMON
に送信されたコマンドのエコーを含む、
EBMON
からのすべての出力を記録します。
別のウィンドウ内でこのファイルに対してtail -f
を実行すると、
EBMON
に関わる問題やPC側での予期せぬイベントを理解する助けになることがよくあります。
ST2000をホスト・システムに接続する方法については、 製造元のマニュアルを参照してください。 ST2000が物理的に接続されれば、 それをデバッグ環境として確立するには、以下を実行します。
target st2000 dev speed
devは通常、
シリアル回線によってST2000と接続される/dev/ttya
のようなシリアル装置の名前です。
代わりに、
hostname:portnumber
という構文を使って
(例えば、端末多重化装置経由で接続されたシリアル回線への)
TCP接続としてdevを指定することもできます。
このターゲットに対して、
load
コマンドとattach
コマンドは定義されていません。
通常スタンドアロンで操作している場合と同様、
ST2000にユーザ・プログラムをロードしなければなりません。
GDBは
(シンボルのような)
デバッグ用の情報を、
ホスト・コンピュータ上にある別のデバッグ・バージョンのプログラムから読みとります。
ST2000での作業を支援するために、 以下の補助的なGDBコマンドが利用可能です。
st2000 command
connect
開発者は、
GDBを使用することによって、
ネットワークに接続されたVxWorks端末上のタスクを、
UNIXのホストから起動してデバッグすることができます。
VxWorksシェルから起動され、
既に実行中の状態のタスクをデバッグすることもできます。
GDBは、
UNIXホスト上で実行されるコードとVxWorksターゲット上で実行されるコードの両方を使います。
gdb
は、
UNIXホスト上にインストールされて実行されます
(ホスト上のプログラムをデバッグするのに使うGDBと区別するために、
vxgdb
という名前でインストールされることもあります)。
VxWorks-timeout args
vxworks-timeout
オプションをサポートするようになりました。
このオプションはユーザによってセットされるもので、
argsは、
GDBがRPCの応答を待つ秒数を表わします。
実際のVxWorksターゲットが速度の遅いソフトウェア・シミュレータであったり、
帯域の小さいネットワーク回線を介して遠距離にある場合などに使うとよいでしょう。
VxWorksとの接続に関する以下の情報は、 このマニュアルの作成時における最新の情報です。 新しくリリースされたVxWorksでは、 手順が変更されているかもしれません。
VxWorks上でGDBを使うためには、
VxWorksカーネルを再構築して、
VxWorksライブラリrdb.a
の中のリモート・デバッグ用のインターフェイス・ルーチンを組み込む必要があります。
そのためには、
VxWorksのコンフィギュレーション・ファイルconfigAll.h
の中でINCLUDE_RDB
を定義して、
VxWorksカーネルを再構築します。
この結果として生成されるカーネルにはrdb.a
が組み込まれ、
VxWorksの起動時にソース・デバッグ用のタスクtRdbTask
が起動されます。
VxWorksの構成や再構築に関する詳細については、
製造元のマニュアルを参照してください。
VxWorksシステム・イメージへのrdb.a
の組み込みが終わり、
UNIXの実行ファイル・サーチ・パスにGDBの存在するパスを加えれば、
GDBを実行するための準備は完了です。
UNIXホストからgdb
(インストールの方法によってはvxgdb
)
を実行します。
GDBが起動されて、
以下のプロンプトを表示します。
(vxgdb)
target
コマンドによって、
ネットワーク上のVxWorksターゲットに接続します。
tt
というホスト名を持つターゲットに接続するには、
以下のようにします。
(vxgdb) target vxworks ttGDBは以下のようなメッセージを表示します。
Attaching remote machine across net... Connected to tt.
続いてGDBは、 最後にVxWorksターゲットが起動されたときより後にロードされた オブジェクト・モジュールのシンボル・テーブルを読み込もうと試みます。 GDBは、 コマンドのサーチ・パスに含まれているディレクトリを探索することによって、 これらのファイルを見つけます (see Your program's environment)。 オブジェクト・ファイルを見つけることができない場合には、 以下のようなメッセージを表示します。
prog.o: No such file or directory.
このような場合には、
GDBのpath
コマンドによって適切なディレクトリを検索パスに加えてから、
再度target
コマンドを実行します。
VxWorksターゲットに接続済みの状態で、
まだロードされていないオブジェクトをデバッグしたい場合には、
GDBのload
コマンドを使ってUNIXからVxWorksへ追加的にファイルをダウンロードすることができます。
load
コマンドの引数として指定されたオブジェクト・ファイルは、
実際には2回オープンされます。
まず、
コードをダウンロードするためにVxWorksターゲットによってオープンされ、
次にシンボル・テーブルを読み込むためにGDBによってオープンされます。
2つのシステム上のカレントな作業ディレクトリが異なると、
問題が発生します。
両方のシステムが同一のファイル・システムをNFSマウントしているのであれば、
絶対パスを使うことで問題を回避することができます。
そうでない場合は、
両方のシステム上で、
オブジェクト・ファイルが存在するディレクトリを作業ディレクトリにして、
パスを一切使わずにファイル名だけでファイルを参照するのが、
最も簡単でしょう。
例えば、
プログラムprog.o
が、
VxWorksではvxpath/vw/demo/rdb
に存在し、
ホストではhostpath/vw/demo/rdb
に存在するとしましょう。
このプログラムをロードするには、
VxWorks上で以下のように実行します。
-> cd "vxpath/vw/demo/rdb"GDB上では、 以下のように実行します。
(vxgdb) cd hostpath/vw/demo/rdb (vxgdb) load prog.oGDBは次のような応答を表示します。
Reading symbol data from wherever/vw/demo/rdb/prog.o... done.
ソース・ファイルを編集して再コンパイルした後に、
load
コマンドを使ってオブジェクト・モジュールを再ロードすることもできます。
ただし、
これを行うと、
GDBはその時点で定義されているすべてのブレイクポイント、
自動表示設定、
コンビニエンス変数を削除し、
値ヒストリを初期化してしまいますので、
注意してください
(これは、
ターゲット・システムのシンボル・テーブルを参照するデバッガのデータ構造の完全性を保つために必要です)。
以下のようにattach
コマンドを使うことで、
既存のタスクにアタッチすることも可能です。
(vxgdb) attach task
taskは、 VxWorksの16進数のタスクIDです。 アタッチするときに、 タスクは実行中であってもサスペンドされていても構いません。 実行中であったタスクは、 アタッチされたときにサスペンドされます。
開発者は、
GDBを使うことによって、
Sparcletターゲット上で実行中のタスクをUnixホストからデバッグできるようになります。
GDBは、
Unixホスト上で実行されるコードとSparcletターゲット上で実行されるコードの両方を使用します。
gdb
は、
Unixホスト上にインストールされて実行されます。
timeout args
remotetimeout
をサポートするようになりました。
このオプションはユーザによって設定されるもので、
argsはGDBが応答を待つ秒数を表わします。
デバッグ用にコンパイルする際には、 デバッグ情報を得るために"-g"オプションを、 また、 ターゲット上でロードしたい位置にプログラムを再配置するために"-Ttext"オプションを指定します。 各セクションのサイズを小さくするために、 "-n"または"-N"オプションを加えるのも良いでしょう。
sparclet-aout-gcc prog.c -Ttext 0x12010000 -g -o prog -N
アドレスが意図したものと一致しているかどうかを検証するのに、 objdumpを使うことができます。
sparclet-aout-objdump --headers --syms progGDBが見つかるようにUnixの実行サーチ・パスを設定すれば、 GDBを実行するための準備は完了です。 Unixホストから
gdb
(インストールの方法によっては、
sparclet-aout-gdb
)
を実行します。
GDBが起動されて、
以下のプロンプトを表示します。
(gdbslet)
file
コマンドによって、
デバッグするプログラムを選択することができます。
(gdbslet) file prog
このコマンドを実行すると、
GDBはprog
のシンボル・テーブルを読み込もうとします。
GDBは、
コマンド・サーチ・パスに含まれるディレクトリを探索することによって、
そのファイルを見つけます。
そのファイルがデバッグ情報付き
(オプション"-g")
でコンパイルされた場合は、
ソース・ファイルも探します。
GDBは、
ディレクトリ・サーチ・パス
(see Your program's environment)
に含まれるディレクトリを探索することによって、
そのソース・ファイルを見つけます。
ファイルが見つからない場合には、
次のようなメッセージを表示します。
prog: No such file or directory.
このメッセージが表示された場合には、
GDBのpath
コマンドとdir
コマンドを使って適切なディレクトリをサーチ・パスに加えてから、
target
コマンドを再実行します。
target
コマンドによってSparcletターゲットに接続することができます。
シリアル・ポート"ttya
"でターゲットに接続するには、
以下のように入力します。
(gdbslet) target sparclet /dev/ttya Remote target sparclet connected to /dev/ttya main () at ../prog.c:3GDBは以下のようなメッセージを表示します。
Connected to ttya.
Sparcletターゲットへの接続が完了すると、
GDBのload
コマンドを使って、
ホストからターゲットへファイルをダウンロードすることができます。
ファイル名とロード・オフセットを、
load
コマンドへの引数として渡さなければなりません。
ファイル形式はaoutですので、
プログラムはその開始アドレスにロードされなければなりません。
開始アドレスの値を知るにはobjdumpを使うことができます。
ロード・オフセットとは、
ファイルの個々のセクションのVMA(仮想メモリ・アドレス)に加算されるオフセットのことです。
例えば、
プログラムprog
が、
textセクションのアドレス0x12010000、
dataセクションのアドレス0x12010160、
bssセクションのアドレス0x12010170にリンクされているとすると、
GDBでは以下のように入力します。
(gdbslet) load prog 0x12010000 Loading section .text, size 0xdb0 vma 0x12010000
プログラムがリンクされたアドレスとは異なるアドレスにコードがロードされた場合、
どこにシンボル・テーブルをマップするかをGDBに通知するために、
section
コマンドとadd-symbol-file
コマンドを使う必要があるかもしれません。
以上により、
GDBの実行制御コマンドであるb
、
step
、
run
などを使ってタスクのデバッグを開始することができます。
コマンドの一覧については、
GDBのマニュアルを参照してください。
(gdbslet) b main Breakpoint 1 at 0x12010000: file prog.c, line 3. (gdbslet) run Starting program: prog Breakpoint 1, main (argc=1, argv=0xeffff21c) at prog.c:3 3 char *symarg = 0; (gdbslet) step 4 char *execarg = "hello!"; (gdbslet)
日立のSH、 H8/300、 H8/500と通信するためには、 GDBは以下の情報を知っている必要があります。
target hms
と、
日立SHや日立300Hのインサーキット・エミュレータであるtargete7000
のどちらを使用したいかということ
(GDBが日立SH、
H8/300、
H8/500用に特に構成されている場合には、
target hms
がデフォルトです)。
シリアル装置を明示的に指定する必要があれば、
そのための専用コマンドである、
gdb
のdevice port
コマンドを使用します。
portのデフォルトは、
ホスト上で最初に利用可能なポートです。
これはUNIXホスト上でのみ必要であり、
そこでは典型的には/dev/ttya
という名前になります。
gdb
には、
通信速度を設定するための専用コマンドspeed bps
があります。
このコマンドもまた
UNIXホストからのみ使用されるものです。
DOSホストでは通常どおり、
GDBからではなくDOSのmodeコマンドによって回線速度を設定します
(例えば、
9600 bpsの接続を確立するにはmode com2:9600,n,8,1,p
のように実行します)。
device
コマンドとspeed
コマンドは、
日立マイクロ・プロセッサ・プログラムのデバッグにUNIXホストを使う場合のみ利用可能です。
DOSホストを使う場合、
GDBは、
PCのシリアル・ポート経由で開発ボードと通信するのに、
asynctsr
と呼ばれる補助的な常駐プログラムに依存します。
DOS側でシリアル・ポートの設定をする場合にも、
DOSのmode
コマンドを使わなければなりません。
E7000インサーキット・エミュレータを使って、
日立SHまたはH8/300H用のコードを開発することができます。
target e7000
コマンドを以下のいずれかの形式で使って、
GDBをE7000に接続します。
target e7000 port speed
com2
)。
3番目の引数は、
秒あたりのビット数による回線速度です
(例えば、
9600
)。
target e7000 hostname
telnet
を使います。
いくつかのGDBコマンドは、 H8/300またはH8/500用に構成された場合にのみ利用可能です。
set machine h8300
set machine h8300h
set machine
コマンドによって、
2種類のH8/300アーキテクチャのどちらか一方にあわせてGDBを調整します。
show machine
コマンドによって、
現在有効なアーキテクチャを調べることができます。
set memory mod
show memory
set memory
コマンドによって、
使用中のH8/500メモリ・モデル
(mod)
を指定します。
show memory
コマンドによって、
現在有効なメモリ・モデルを調べます。
modに指定可能な値は、
small
、
big
、
medium
、
compact
のいずれかです。
--target=mips-idt-ecoff
によって構成することによって、
利用することができます。
ターゲット・ボードとの接続を指定するには、 以下のGDBコマンドを使用します。
target mips port
gdb
を起動します。
ボードに接続するには、
target mips port
コマンドを使用します。
portは、
ボードに接続されているシリアル・ポートの名前です。
プログラムがまだボードにダウンロードされていないのであれば、
load
コマンドを使ってダウンロードすることができます。
その後、
通常利用できるすべてのGDBコマンドを使うことができます。
例えば以下の手順では、 デバッガを使うことによって、 シリアル・ポートを経由してターゲット・ボードに接続した後に、 progと呼ばれるプログラムをロードして実行しています。
host$ gdb prog GDB is free software and ... (gdb) target mips /dev/ttyb (gdb) load prog (gdb) run
target mips hostname:portnumber
hostname:portnumber
という構文を使うことで、
シリアル・ポートの代わりに
(例えば、
端末多重化装置によって管理されているシリアル回線への)
TCP接続を指定することができます。
target pmon port
target ddb port
target lsi port
set processor args
show processor
set processor
コマンドを使ってMIPSプロセッサの種類を設定します。
例えば、
set processor r3041
は、
3041チップで有効なCPOレジスタを使うよう、
GDBに対して通知します。
GDBが使っているMIPSプロセッサの種類を知るには、
show processor
コマンドを使います。
GDBが使っているレジスタを知るには、
info reg
コマンドを使います。
set mipsfpu double
set mipsfpu single
set mipsfpu none
show mipsfpu
set mipsfpu none
コマンドを使う必要があります
(このようなことが必要な場合には、
初期化ファイルの中にそのコマンドを入れてしまってもよいでしょう)。
これによって、
浮動小数値を返す関数の戻り値を見つける方法をGDBに知らせます。
またこれにより、
ボード上で関数を呼び出すときに、
GDBは浮動小数点レジスタの内容を退避する必要がなくなります。
R4650プロセッサ上にあるような、
単精度浮動小数だけをサポートする浮動小数点コプロセッサを使っている場合には、
set mipsfpu single
コマンドを使います。
デフォルトの倍精度浮動小数点コプロセッサは、
set mipsfpu double
によって選択することができます。
以前のバージョンでは、
有効な選択肢は、
倍精度浮動小数コプロセッサを使う設定と浮動小数点コプロセッサを使わない設定だけでした。
したがって、
set mipsfpu on
で倍精度浮動小数コプロセッサが選択され、
set mipsfpu off
で浮動小数点コプロセッサを使わないという設定が選択されていました。
他の場合と同様、
mipsfpu
変数に関する設定は、
show mipsfpu
によって問い合わせることができます。
set remotedebug n
show remotedebug
remotedebug
変数を設定することによって、
ボードとの通信に関するいくつかのデバッグ用の情報を見ることができます。
set remotedebug 1
によって値1
を設定すると、
すべてのパケットが表示されます。
値を2
に設定すると、
すべての文字が表示されます。
show remotedebug
コマンドによって、
いつでも現在の設定値を調べることができます。
set timeout seconds
set retransmit-timeout seconds
show timeout
show retransmit-timeout
set timeout seconds
コマンドで制御することができます。
デフォルトは5秒です。
同様に、
パケットに対する確認
(ACK)
を待っている状態でのタイムアウト時間を、
set retransmit-timeout seconds
コマンドで制御することができます。
デフォルトは3秒です。
それぞれの値をshow timeout
とshow retransmit-timeout
で調べることができます
(どちらのコマンドも、
GDBが--target=mips-idt-ecoff
用に構成されている場合のみ使用可能です)。
set timeout
で設定されたタイムアウト時間は、
ユーザ・プログラムが停止するのをGDBが待っている間は適用されません。
この場合には、
GDBは永遠に待ち続けます。
これは、
停止するまでにプログラムがどの程度長く実行を継続するのかを知る方法がないからです。
構成によっては、 ユーザ・プログラムをデバッグする際にハードウェアCPUの代わりに使うことのできるCPUシミュレータが、 GDBの中に組み込まれています。 現在のところ、 ARM、D10V、D30V、FR30、H8/300、H8/500、 i960、M32R、MIPS、MN10200、MN10300、 PowerPC、SH、Sparc、V850、W65、Z8000 用のシミュレータが利用できます。
Z8000系については、
target sim
によって、
Z8002
(Z8000アーキテクチャの、
セグメントを持たない変種)
またはZ8001
(セグメントを持つ変種)
をシミュレートします。
シミュレータは、
オブジェクト・コードを調べることで、
どちらのアーキテクチャが適切であるかを認識します。
target sim args
このターゲットを指定した後には、
ホスト・コンピュータ上のプログラムをデバッグするのと同様の方法で、
シミュレートされたCPU用のプログラムをデバッグすることができます。
新しいプログラムのイメージをロードするには
file
コマンドを使い、
ユーザ・プログラムを実行するにはrun
コマンドを使う、
という具合です。
Z8000シミュレータでは、
通常のマシン・レジスタ
(info reg
を参照)
がすべて利用可能であるだけでなく、
特別な名前を持つレジスタとして、
3つの追加情報が提供されています。
cycles
insts
time
これらの変数は、
GDBの式の中で普通に参照することができます。
例えば、
b fputc if $cycles>5000
は、
シミュレートされたクロック・ティックが最低5,000回発生した後に停止するような、
条件付きブレイクポイントを設定します。
set
コマンドによってGDBの操作方法を変更することができます。
GDBによるデータの表示方法を変更するコマンドについては、
see Print settings。
この章では、
その他の設定について説明します。
(gdb)
です。
set prompt
コマンドによって、
プロンプトの文字列を変更することができます。
例えば、
GDBを使ってGDB自体をデバッグしているときには、
どちらか一方のGDBセッションのプロンプトを変更して、
どちらのGDBとやりとりしているのか区別できるようにすると便利です。
注: 以前のバージョンとは異なり、
現在のset prompt
は、
ユーザが設定したプロンプトの後ろに空白を追加しません。
ユーザは、
空白で終わるプロンプト、
空白で終わらないプロンプトのいずれでも設定することができます。
set prompt newprompt
show prompt
Gdb's prompt is: your-prompt
という形式の1行を表示します
csh
スタイルのヒストリ代替、
複数のデバッグ・セッションにまたがるコマンド・ヒストリの保存と呼び出しができるようになることが挙げられます。
set
コマンドによって、
GDBにおけるコマンドライン編集の振る舞いを制御することができます。
set editing
set editing on
set editing off
show editing
デバッグ・セッション中にユーザが入力したコマンドをGDBに記録させることができるため、 ユーザは実際に何が実行されたかを確実に知ることができます。 以下のコマンドを使って、 GDBのコマンド・ヒストリ機能を管理します。
set history filename fname
GDBHISTFILE
の値になりますが、
この変数が設定されていない場合には./.gdb_history
になります。
set history save
set history save on
set history filename
コマンドで指定可能です。
デフォルトでは、
このオプションは使用不可の状態になっています。
set history save off
set history size size
HISTSIZE
の値に設定されますが、
この変数が設定されていない場合は256になります。
ヒストリ展開機能により、 文字!には特別な意味が割り当てられます。
!は、
C言語における論理NOTの演算子でもあるので、
ヒストリ展開機能はデフォルトではoffになっています。
set history expansion on
コマンドによってヒストリ展開を利用できるようにした場合には、
(!を式の中で論理NOTとして使うのであれば)
!の後ろに空白かタブを入れることによって、
それが展開されないようにする必要のある場合があります。
ヒストリ展開が有効になっている場合でも、
readlineのヒストリ機能は、
!=や!(という文字列を置き換えようとはしません。
ヒストリ展開を制御するコマンドには、 以下のようなものがあります。
set history expansion on
set history expansion
set history expansion off
readlineのコードには、
ヒストリ編集機能やヒストリ展開機能に関する、
より完全なドキュメントが付属しています。
GNU Emacsやvi
のことをよく知らない人は、
このドキュメントを読むとよいでしょう。
show history
show history filename
show history save
show history size
show history expansion
show history
を実行すると、
4つのパラメータの状態がすべて表示されます。
show commands
show commands n
show commands +
通常GDBは、
termcapデータベースとTERM
環境変数の値、
さらに、
stty rows
、
stty cols
の設定から、
画面の大きさを知っています。
この結果が正しくない場合、
set height
コマンドとset width
コマンドで画面の大きさの設定を変更することができます。
set height lpp
show height
set width cpl
show width
set
コマンドは、
画面の高さをlpp行に、
幅をcpl桁に指定します。
関連するshow
コマンドが、
現在の設定を表示します。
ゼロ行の高さを指定すると、 GDBは出力がどんなに長くても、 出力途中で一時停止することをしません。 これは、 出力先がファイルやエディタのバッファである場合に便利です。
同様に、
set width 0
を指定することによって、
GDBに行の折り返しを行わせないようにすることもできます。
0
で始まります。
10進数は.
で終わります。
16進数は0x
で始まります。
このどれにも該当しないものは、
デフォルトで10進数として入力されます。
同様に、
数値を表示するときも、
特定のフォーマットが指定されていなければ、
デフォルトで10進数として表示されます。
set radix
コマンドによって、
入力、
出力の両方のデフォルトを変更することができます。
set input-radix base
set radix 012 set radix 10. set radix 0xa
は基数を10進数に設定します。
一方、
set radix 10
は、
現在の基数を
(それがどれであれ)
変更しません。
set output-radix base
show input-radix
show output-radix
デフォルトでは、
GDBは内部の動作に関する情報を表示しません。
性能の遅いマシンで実行している場合には、
set verbose
コマンドを使うとよいでしょう。
これによって、
GDBは、
長い内部処理を実行するときにメッセージを出力することで、
クラッシュと勘違いされないようにします。
現在のところ、
set verbose
コマンドによって制御されるメッセージは、
ソース・ファイルのシンボル・テーブルを読み込み中であることを知らせるメッセージです。
Commands to specify filesのsymbol-file
を参照してください。
set verbose on
set verbose off
show verbose
set verbose
がon、
offのどちらの状態であるかを表示します。
デフォルトでは、 オブジェクト・ファイルのシンボル・テーブルに問題を検出しても、 GDBはメッセージを出力しません。 しかし、 コンパイラをデバッグしているようなときには、 このような情報があると便利かもしれません (see Errors reading symbol files)。
set complaints limit
show complaints
デフォルトでは、 GDBは慎重に動作し、 コマンドを本当に実行するのか確認するために、 ときには馬鹿げているとさえ思えるような質問を多く尋ねてきます。 例えば、 既に実行中のプログラムを実行しようとすると、 次のように質問してきます。
(gdb) run The program being debugged has been started already. Start it from the beginning? (y or n)
ユーザが、 実行したコマンドの結果を何がなんでも見てみたいのであれば、 この「機能」を抑止することができます。
set confirm off
set confirm on
show confirm
ブレイクポイント・コマンド (see Breakpoint command lists) とは別に、 一連のコマンドを一括して実行するために保存する2つの方法を、 GDBは提供しています。 ユーザ定義コマンドとコマンド・ファイルがそれです。
ユーザ定義コマンドとは、
一連のGDBコマンドに単一コマンドとしての名前を新たに割り当てたものです。
これは、
define
コマンドによって行われます。
ユーザ・コマンドは、
空白で区切られた引数を最高で10個まで受け取ることができます。
引数は、
ユーザ・コマンドの中で、
$arg0...$arg9としてアクセスすることができます。
簡単な例を以下に示します。
define adder print $arg0 + $arg1 + $arg2
このコマンドを実行するには、以下のようにします。
adder 1 2 3
上の例では、
adder
というコマンドを定義しています。
このコマンドは、
3つの引数の合計を表示します。
引数は文字列で代用されますので、
変数を参照することもできますし、
複雑な式を使うこともできます。
また、
下位関数の呼び出しを行うこともできます。
define commandname
コマンドの定義は、
define
コマンドに続いて与えられる、
他のGDBコマンド行から構成されます。
これらのコマンドの末尾は、
end
を含む行によって示されます。
if
else
行が続くことがあり、
この場合は、
else
行の後に、
式の評価結果が偽であった場合にだけ実行される一連のコマンドが続きます。
末尾は、
end
を含む行によって示されます。
while
if
と似ています。
引数として、
評価の対象となる式を1つだけ取ります。
その後には、
実行されるべきコマンドが1行に1つずつ続き、
最後にend
がなければなりません。
コマンドは、
式の評価結果が真である限り、
繰り返し実行されます。
document commandname
help
コマンドによってアクセスできます。
コマンドcommandnameは既に定義済みでなければなりません。
このコマンドは、
define
コマンドが一連のコマンド定義を読み込むのと同様に、
end
で終わる一連のドキュメントを読み込みます。
document
コマンドの実行が完了すると、
コマンドcommandnameに対してhelp
コマンドを実行すると、
ユーザの記述したドキュメントが表示されます。
document
コマンドを再度実行することによって、
コマンドのドキュメントを変更することができます。
define
コマンドによってコマンドを再定義しても、
ドキュメントは変更されません。
help user-defined
show user
show user commandname
ユーザ定義コマンドが実行されるときに、 定義内のコマンドは表示されません。 定義内のコマンドがどれか1つでもエラーになると、 ユーザ定義コマンドの実行が停止されます。
対話的に使われている場合には確認を求めてくるようなコマンドも、 ユーザ定義コマンドの内部で使われている場合には確認を求めることなく処理を継続します。 通常は実行中の処理に関してメッセージを表示するGDBコマンドの多くが、 ユーザ定義コマンドの中から呼び出されている場合にはメッセージを表示しません。
特別な種類のユーザ定義コマンドである、
フックを定義することができます。
hook-foo
というユーザ定義コマンドが存在すると、
foo
というコマンドを実行するときにはいつも、
foo
コマンドが実行される前に
(引数のない)
hook-foo
が実行されます。
また、
仮想コマンドであるstop
が存在します。
(hook-stop
を)
定義すると、
ユーザ・プログラムの実行が停止するたびに、
その定義内のコマンドが実行されます。
実行タイミングは、
ブレイクポイント・コマンドの実行、
自動表示対象の表示、
および、
スタック・フレームの表示の直前です。
例えば、
シングル・ステップ実行をしている際にはSIGALRM
シグナルを無視し、
通常の実行時には通常どおり処理したい場合には、
以下のように定義します。
define hook-stop handle SIGALRM nopass end define hook-run handle SIGALRM pass end define hook-continue handle SIGLARM pass endGDBのコマンドのうち、 その名前が1つの単語から成るものには、 フックを定義することができます。 ただし、 コマンド・エイリアスにフックを定義することはできません。 フックは、 コマンドの基本名に対して定義しなければなりません。 例えば、
bt
ではなくbacktrace
を使います。
フックの実行中にエラーが発生すると、
GDBコマンドは停止します。
(ユーザが実際に入力したコマンドが実行する機会を与えられる前に)
GDBはプロンプトを表示します。
既知のコマンドのいずれにも対応しないフックを定義しようとすると、
define
コマンドは警告メッセージを表示します。
.gdbinit
という名前のファイルであり、
DOS/Windows上ではgdb.ini
という名前のファイルです。
GDBは、
ユーザのホーム・ディレクトリに初期化ファイルがあればまずそれを読み込み、
続いてコマンンドライン・オプションとオペランドを処理した後、
カレントな作業ディレクトリに初期化ファイルがあればそれを読み込みます。
このように動くのは、
ユーザのホーム・ディレクトリに初期化ファイルを置くことで、
コマンドライン上のオプションやオペランドの処理に影響を与える
(set complaints
のような)
オプションを設定することができるようにするためです。
-nx
オプションを使用すると、
初期化ファイルは実行されません。
see Choosing modes。
GDBのいくつかの構成では、
初期化ファイルは異なる名前で知られています
(このような環境では、
特別な形式のGDBが他の形式のGDBと共存する必要があり、
そのために特別なバージョンのGDBの初期化ファイルには異なる名前が付けられます)。
特別な名前の初期化ファイルを持つ環境には、
以下のようなものがあります。
.vxgdbinit
.os68gdbinit
.esgdbinit
また、
source
コマンドによって、
コマンド・ファイルの実行を要求することもできます。
source filename
コマンド・ファイルの各行は順番に実行されます。 コマンドの実行時に、 そのコマンドは表示されません。 どれか1つでもコマンドがエラーになると、 コマンド・ファイルの実行は停止されます。
対話的に使われている場合には確認を求めてくるようなコマンドも、 コマンド・ファイル内で使われている場合は確認を求めることなく処理を継続します。 通常は実行中の処理についてメッセージを表示するGDBコマンドの多くが、 コマンド・ファイルの中から呼び出されている場合にはメッセージを表示しません。
コマンド・ファイルやユーザ定義コマンドの実行中には、 通常のGDBの出力は抑止されます。 唯一出力されるのは、 定義内のコマンドが明示的に表示するメッセージだけです。 ここでは、 ユーザが希望するとおりの出力を生成するのに役に立つ、 3つのコマンドについて説明します。
echo text
\n
を使います。
明示的に指定しない限り、
改行コードは表示されません。
標準的なCのエスケープ・シーケンスに加えて、
バックスラッシュの後ろに空白を置くことで、
空白が表わされます。
これは、
先頭や末尾に空白のある文字列を表示するのに便利です。
というのは、
こうしないと、
引数の先頭や末尾の空白は削除されるからです。
and foo =
を表示するには、
echo \ and foo = \
を実行してください。
Cと同様、 textの末尾にバックスラッシュを置くことで、 コマンドを次の行以降に継続することができます。 例えば、
echo This is some text\n\ which is continued\n\ onto several lines.\n
は
echo This is some text\n echo which is continued\n echo onto several lines.\n
と同じ出力をもたらします。
output expression
$nn =
も表示されません。
expressionの値は値ヒストリには入りません。
式の詳細については、
See Expressions。
output/fmt expression
print
コマンドと同じフォーマットを指定することができます。
詳細については、
See Output formats。
printf string, expressions...
printf (string, expressions...);
を実行した場合と同様に、 stringの指定にしたがって表示されます。
例えば、 次のようにして2つの値を16進数で表示することができます。
printf "foo, bar-foo = 0x%x, 0x%x\n", foo, bar-foo
フォーマットを指定する文字列の中で使えるバックスラッシュ・エスケープ・シーケンスは、 バックスラッシュとそれに続く単一文字から構成される簡単なものだけです。
このインターフェイスを使うには、 Emacsの中でM-x gdbコマンドを使います。 デバッグしたい実行ファイルを引数として指定してください。 このコマンドは、 GDBをEmacsのサブプロセスとして起動し、 新しく作成したEmacsバッファを通じて入出力を行います。
Emacsの中でのGDBの使い方は、 通常のGDBの使い方とほぼ同様ですが、 2つ相違点があります。
これは、 GDBコマンドとその出力、 および、 デバッグ対象のユーザ・プログラムによる入出力の両方に適用されます。
以前に実行したコマンド・テキストをコピーして再入力することができるので便利です。 出力された部分に関しても同様のことができます。
EmacsのShellモードで利用可能なすべての機能を、 ユーザ・プログラムとのやりとりで使うことができます。 特に、 通常どおりにシグナルを送信することができます。 例えば、 C-c C-cで割り込みシグナルを、 C-c C-zでストップ・シグナルを発生させることができます。
=>
)
を表示します。
Emacsはソース・コードを別バッファに表示し、
スクリーンを2つに分けて、
GDBセッションとソースをともに表示します。
GDBのlist
コマンドやsearch
コマンドを明示的に使えば、
通常どおりの出力を生成することもできますが、
これらをEmacsから使う理由はおそらくないでしょう。
注意: ユーザ・プログラムの存在するディレクトリがユーザのカレント・ディレクトリでない場合、 ソース・ファイルの存在場所についてEmacsは簡単に混乱に陥ります。 このような場合、 ソースを表示するための追加のディスプレイ・バッファは表示されません。 GDBは、 ユーザの環境変数PATH
のリストの中にあるディレクトリを探索してプログラムを見つけ出しますので、 GDBの入出力セッションは通常どおり進行します。 しかしEmacsは、 このような状況においてソース・ファイルを見つけ出すのに十分な情報をGDBから受け取っていません。 この問題を回避するには、 ユーザ・プログラムの存在するディレクトリからGDBモードを開始するか、 M-x gdbの引数の入力を求められたときに、 絶対パスでファイル名を指定します。Emacsの既存のGDBバッファから、 デバッグ対象をどこかほかの場所にあるプログラムに変更する目的でGDBの
file
コマンドを使うと、 同様の混乱の発生することがあります。
デフォルトでは、
M-x gdbはgdb
という名前のプログラムを呼び出します。
別の名前でGDBを呼び出す必要がある場合
(例えば、
異なる構成のGDBを別の名前で持っているような場合)
は、
Emacsのgdb-command-name
という変数を設定します。
例えば
(setq gdb-command-name "mygdb")
(をESC ESCに続けて入力するか、
あるいは、
*scratch*
バッファまたは.emacs
ファイルに入力することで)
Emacsはgdb
の代わりに「mygdb
」という名前のプログラムを呼び出します。
GDBのI/Oバッファでは、
標準的なShellモードのコマンドに加えて、
以下のような特別なEmacsコマンドを使うことができます。
step
コマンドのように、
ソース行を1行実行します。
さらに、
カレントなファイルとその中における位置を示すために、
表示ウィンドウを更新します。
next
コマンドのように、
関数呼び出しをすべてスキップして、
現在の関数内の次のソース行まで実行を進めます。
さらに、
カレントなファイルとその中における位置を示すために、
表示ウィンドウを更新します。
stepi
コマンドのように、
1命令を実行します。
必要に応じて表示ウィンドウを更新します。
nexti
コマンドを使って、
次の命令まで実行します。
必要に応じて表示ウィンドウを更新します。
finish
コマンドのように、
選択されたスタック・フレームを終了するまで実行を継続します。
continue
コマンドのように、
ユーザ・プログラムの実行を継続します。
注意: Emacs v19では、
このコマンドはC-c C-pです。
up
コマンドのように、
数値引数によって示される数だけ上位のフレームに移動します
(see Arguments
4)。
注意: Emacs v19では、
このコマンドはC-c C-uです。
down
コマンドのように、
数値引数によって示される数だけ下位のフレームに移動します。
注意: Emacs v19では、
このコマンドはC-c C-dです。
disassemble
への引数をC-x &で読み取ります。
gdb-print-command
リストの要素を定義することによって、
これをさらにカスタマイズすることができます。
これが定義されていると、
C-x &で入手した数値が挿入される前に、
それをフォーマットしたり、
処理したりすることができるようになります。
C-x &に数値引数を指定すると、
特別なフォーマット処理を必要としているという意味になり、
その数値がリストの要素を取得するためのインデックスとなります。
リストの要素が文字列の場合は、
挿入される数値はEmacsのformat
関数によってフォーマットされます。
リストの要素が文字列以外の場合は、
その数値が、
対応するリスト要素への引数として渡されます。
どのソース・ファイルが表示されている場合でも、
EmacsのC-x SPC(gdb-break
)コマンドは、
ポイントの置かれているソース行にブレイクポイントを設定するようGDBに対して指示します。
ソースを表示中のバッファを誤って削除してしまった場合に、
それを再表示させる簡単な方法は、
GDBバッファの中でf
コマンドを入力して、
フレーム表示を要求することです。
Emacs配下では、
カレント・フレームのコンテキストを表示するために必要であれば、
ソース・バッファが再作成されます。
Emacsによって表示されるソース・ファイルは、 通常どおりの方法でソース・ファイルにアクセスする、 普通のEmacsバッファによって表示されます。 そうしたいのであれば、 これらのバッファの中でファイルの編集を行うこともできますが、 GDBとEmacsの間で行番号に関する情報が交換されていることを頭に入れておいてください。 テキストに行を挿入したり、 削除したりすると、 GDBの認識しているソース行番号は、 実際のコードと正しく対応しなくなってしまいます。
ユーザからのバグ報告は、 GDBの信頼性を向上させるのに重要な役割を果たしています。
バグを報告することで、 その問題の解決につながり、 結果として報告者自ら利益を得ることができるかもしれません。 もちろん、 何の解決にもつながらないこともあります。 しかし、 いずれにしても、 バグ報告の主要な意義は、 次のバージョンのGDBをより良いものにすることで、 コミュニティ全体の役に立つという点にあります。 バグ報告は、 GDBの保守作業へのユーザからの貢献です。
バグ報告がその目的とするところを首尾よく達成できるようにするためには、 バグを修正することを可能にするような情報が提供されなければなりません。
発見した現象がバグかどうかよく分からない場合には、 以下のガイドラインを参照してください。
いくつかの企業や個人がGNUのソフトウェアをサポートしています。 こうしたサポート組織からGDBを入手したのであれば、 まずその組織に連絡することをお勧めします。
サポートを提供している多くの企業、
個人の連絡先情報が、
GNU Emacsディストリビューションのetc/SERVICE
ファイルに記載されています。
どのような場合でも、 GDBのバグ報告を (英語で) 以下のアドレスに送ることをお勧めします。 6
bug-gdb@prep.ai.mit.edu
info-gdb
、
help-gdb
、
および、
いかなるニュースグループにもバグ報告を送ることはしないでください。
GDBユーザのほとんどは、
バグ報告を受け取りたいと考えてはいません。
バグ報告を受け取りたいと思っている人は、
bug-gdb
の配信を受けるようにしているはずです。
メーリング・リストbug-gdb
には、
リピータとして機能するgnu.gdb.bug
というニュースグループがあります。
このメーリング・リストとニュースグループは、
全く同一のメッセージを配信しています。
メーリング・リストではなくニュースグループにバグ報告を流そうと考える人がよくいます。
これはうまく機能するように見えますが、
1つ重大な問題があります。
ニュースグループへの投稿では、
送信者へのメール・パスが分からないことがよくあります。
したがって、
もっと多くの情報が必要になったときに、
バグの報告者と連絡を取ることができない可能性があります。
こういうことがあるので、
メーリング・リストへのバグ報告の方が望ましいのです。
最後の手段として、 バグ報告を(英語で)紙に書いて下記に郵送するという方法があります。
GNU Debugger Bugs Free Software Foundation Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307 USA
役に立つバグ報告を行うための最も根本的な原則は、 すべての事実を報告することです。 ある事実を書くべきか省くべきかよく分からない場合は、 書くようにしてください。
事実が省略されてしまうことがよくありますが、 これはバグ報告者が、 自分には問題の原因は既に分かっていると考え、 いくつかの細かい点は関係がないと仮定してしまうからです。 したがって、 例の中で使った変数の名前などは重要ではないと、 報告者は考えます。 おそらくそうかもしれません。 しかし、 完全にそうであるとも言い切れません。 メモリの参照がデタラメな場所を指しているというバグで、 それがたまたまメモリ上においてその名前が置かれている箇所から値を取り出しているということがあるかもしれません。 名前が異なれば、 そこの内容は、 バグが存在するにもかかわらずデバッガが正しく動作してしまうような値になるかもしれません。 このようなことがないよう、 特定の完全な実例を提供してください。 バグの報告者にとっては、 このようにするのが最も簡単なはずであり、 かつ、 それが最も役に立つのです。
バグ報告の目的は、 そのバグを修正することができるようにすることにある、 という点を頭に入れておいてください。 そのバグが、 以前に報告されたものと同じであるという可能性もありますが、 バグ報告が完全なもので、 必要な情報がすべて含まれたものでなければ、 バグの報告者にも私たちにもそのことを知ることができません。
ときどき、 2、3の大雑把な事実だけを記述して、 「何か思い当たることはありますか?」と聞いてくる人がいます。 このようなバグ報告は役に立ちません。 このような報告には、 より適切なバグ報告を送るよう報告者に注意する場合を除いて、 返事をすることを拒否するよう強くお願いします。
バグを修正できるようにするためには、 報告者は以下の情報をすべて含めるべきです。
show version
コマンドで表示させることができます。
この情報がないと、 カレント・バージョンのGDBを使ってバグを探すことに意味があるのかどうかを知ることができません。
gcc --version
によってこの情報を知ることができます。
他のコンパイラについては、
そのドキュメントを参照してください。
-O
オプションを使ったか否かなど。
何か重要な点を省いてしまうことがないよう、
すべての引数を記述してください。
Makefile
のコピー
(あるいは、
make
からの出力)
を添付すれば十分でしょう。
引数が何であったのかを私たちが推測しようとしても、 おそらく誤った推測をしてしまうでしょう。 そうなると、 バグは再現しないかもしれません。
もちろん、 GDBが致命的なシグナルを受信するというバグであれば、 私たちも間違いなくそれに気がつくでしょう。 しかし、 出力が正しくないというバグであれば、 紛れもない誤りでなければ、 私たちはそれに気付かないかもしれません。 私たちが間違いをする可能性を排除するようにしてください。
たとえ致命的なシグナルを受信するような問題であっても、 報告者はそのことを明示的に報告するべきです。 何か奇妙なことが起こっていると仮定しましょう。 例えば、 報告者が使っているGDBにちぐはぐなところがあるとか、 報告者のシステム上にあるCライブラリのバグだった、 というような場合です (こういうことは、 実際にありました!)。 このような場合、 報告者のGDBはクラッシュしても、 私たちのところではクラッシュしません。 クラッシュするはずであると報告されていれば、 私たちのGDBがクラッシュしなくても、 「私たちのところではバグが発生しない」ということを知ることができます。 クラッシュするはずであるという報告がなければ、 実際の現象から何も結論を引き出すことができません。
私たちが開発中のソースの行番号は、 報告者の持っているソースの行番号とは一致しないでしょう。 報告者から見たソースの行番号は、 私たちにとって役に立つ情報を提供してくれません。
以下に、 バグ報告に必要ではない情報をいくつか列挙します。
バグを見つけると、 多くの時間をかけて、 入力ファイルをどのように変更するとバグが発生しなくなり、 どのように変更した場合はバグが発生し続けるかを調べる人がよくいます。
これは多くの場合、 時間のかかる作業であり、 しかもあまり役に立ちません。 というのは、 私たちがバグを見つけるのは、 デバッガでブレイクポイントを使いながら1つの実例を実行させることによってであり、 一連の実例からの純粋な演繹によってではないからです。 時間を無駄にせず、 何かほかのことに使うようお勧めします。
もちろん、 一番最初にバグを見つけたときの実例の代わりとなる、 もっと単純な実例を見つけることができるのであれば、 私たちにとっても便利です。 出力におけるエラーはより発見しやすいものですし、 デバッガ配下で実行させる方が時間がかかりません。
しかし、 単純化は絶対に必要というわけでもありません。 こういうことをしたくないのであれば、 バグを発見したときのテスト・ケース全体を送って、 バグの報告を行ってください。
バグに対するパッチは、 それが良いものであれば、 役に立ちます。 しかし、 パッチがあれば十分であるとみなして、 テスト・ケースのような必要な情報を送るのを省かないでください。 提供されたパッチに問題があり、 別の方法で問題を修正することにする場合もありますし、 提供されたパッチを全く理解できないということもあるかもしれません。 GDBのような複雑なプログラムでは、 コード中のある特定のパスを通るような実例を作成するのは困難なことがあります。 報告者が実例を送ってくれなければ、 私たちには実例を作成することができず、 したがって、 バグが修正されたことを検証することができなくなってしまいます。
また、 報告者の送ってくれたパッチがどのような問題を修正しようとしているのか私たちに理解できない場合、 あるいは、 なぜそのパッチが改善になるのか私たちが理解できない場合、 そのパッチを組み込むことはしません。 テスト・ケースが1つでもあれば、 そうしたことを理解するのに役立つでしょう。
このような推測は普通は間違っているものです。 私たちですら、 デバッガを使って事実を見出すまでは、 このような点に関して正しく推測することはできないのです。
この章では、 GNUのコマンドライン編集インターフェイスの基本的な特徴について説明します。
以下のパラグラフでは、 キー・ストロークを表わすために使用される表記法について説明します。
<C-k>は、 Control-Kという意味です。 これは、 コントロール・キーが押されたままの状態でキー<k>が押されたときに生成される文字を表わします。
<M-k>は、 Meta-Kという意味です。 これは、 メタ・キー (があるものとして、それ) が押されたままの状態でキー<k>が押されたときに生成される文字を表わします。 メタ・キーがない場合、 最初に<ESC>キーを押し、 次にキー<k>を押すことで、 同等のキー・ストロークを生成することができます。 どちらの手順も、 キー<k>をメタ化する、 といいます。
<M-C-k>は、 Meta-Control-Kという意味です。 これは、 <C-k>をメタ化することにより生成される文字を指します。
さらに、 いくつかのキーには名前があります。 <DEL>、 <ESC>、 <LFD>、 <SPC>、 <RET>、 <TAB>は、 この文章の中でも、 初期化ファイルの中でも、 各々のキーを表わします (see Readline Init File)。
対話的なセッションにおいて、 長いテキストを1行に記述した後で、 その行の先頭の単語のスペルが間違っていたことに気が付くことがよくあります。 Readlineライブラリは、 入力したテキストを操作するための一連のコマンドを提供しており、 これによって、 その行の大部分を入力し直すことなく、 タイプ・ミスしたところだけを修正することができます。 これらの編集コマンドを使って、 修正が必要なところにカーソルを移動させ、 テキストを削除したり、 修正テキストを挿入したりします。 その行の修正が終われば、 単に<RETURN>を押します。 <RETURN>を押すのに、 行末にいる必要はありません。 カーソルが行内のどこにあろうと、 その行全体が入力として受け付けられます。
行内に文字を入力するには、 単にその文字をタイプします。 タイプされた文字はカーソルの位置に表示され、 カーソルは1桁分右へ移動します。 1文字打ち間違えた場合は、 削除文字(erase character)を使って、 後退しながら打ち間違えた文字を削除することができます。
ときには、 本当は入力したかった文字を入力せず、 その誤りに気が付くことなく、 さらに数文字を入力してしまうということがあります。 このような場合には、 <C-b>によってカーソルを左に移動し、 誤りを訂正することができます。 訂正後、 <C-f>によってカーソルを右に移動することができます。
行の途中にテキストを追加すると、 挿入されたテキストのためのスペースを空けるために、 カーソルの右側にある文字が右方向に押しやられることに気がつくでしょう。 同様に、 カーソル位置にあるテキストを削除すると、 文字が削除されたために生じる空白を埋めるために、 カーソルの右側にある文字が左方向に引き戻されます。 入力行のテキストを編集するための最も基本的な操作の一覧を以下に示します。
上記の一覧は、 ユーザが入力行を編集するのに必要な、 最も基本的なキー・ストロークを説明したものです。 ユーザの利便を考慮して、 <C-b>、 <C-f>、 <C-d>、 <DEL>に加えて多くのコマンドが追加されてきました。 以下に、 行内をより迅速に動きまわるためのコマンドをいくつか示します。
<C-f>が1文字分先に進むのに対して、 <M-f>が1単語分先に進む点に注意してください。 大まかな慣例として、 コントロール・キーを使うと文字単位の操作になり、 メタ・キーを使うと単語単位の操作になります。
テキストをキル(kill)するとは、 行からテキストを削除し、 その際に、 そのテキストを後に引き出して行内に再挿入(yank)することができるように退避しておくことを指します。 あるコマンドの説明に「テキストをキル(kill)する」という記述があれば、 後に別の箇所 (あるいは同じ箇所) において、 そのテキストを再入手することができると考えて間違いありません。
キル(kill)コマンドを使うと、 テキストはキル・リング(kill-ring)に退避されます。 キル(kill)コマンドを任意の回数連続して実行すると、 キル(kill)されたテキストはすべて連結されて退避されます。 したがって、 再挿入(yank)を行うと、 そのすべてを入手することができます。 キル・リング(kill-ring)は個々の行に固有のものではありません。 以前入力した行においてキル(kill)したテキストを、 後になって別の行を入力しているときに再挿入(yank)することができます。
以下に、テキストをキル(kill)するためのコマンドを一覧で示します。
キル(kill)されたテキストを引き出して行内へ再挿入(yank)する方法を、 以下に示します。 再挿入(yank)とは、 最後にキルされたテキストを、 キル・バッファからコピーすることを意味しています。
Readlineコマンドには数値引数を渡すことができます。
数値引数は、
繰り返し回数として使われたり、
引数の符号として使われたりします。
通常は先に進むようなコマンドに負の数を引数として指定すると、
前に戻るようになります。
例えば、
行の先頭までのテキストをキル(kill)するには、
M-- C-k
としてもよいでしょう。
コマンドに数値引数を渡す通常の方法は、
コマンドの前にメタ化された数字を入力することです。
入力された最初の「数字」がマイナス記号(<->)の場合、
引数の符号は負になります。
引数を開始するためには、
メタ化された数字を1つだけ入力すればよく、
残りの数字はそのまま入力することができます。
そして最後にコマンドを入力します。
例えば、
<C-d>コマンドに引数として10を渡すためには、
M-1 0 C-d
と入力します。
readlineは、 コマンド・ヒストリ の中から、 指定された文字列を含む行を検索するコマンドを提供しています。 インクリメンタル(incremental)と 非インクリメンタル(non-incremental)の2つの検索モードがあります。
インクリメンタル(incremental)・モードでは、 ユーザが検索文字列を入力し終わる前から検索が始まります。 検索文字列の中の文字が1つ入力されるたびに、 readlineは、 それまで入力された文字列にマッチする、 ヒストリの中の次のエントリを表示します。 インクリメンタル・モードの検索では、 検索したいヒストリ・エントリを見つけるのに本当に必要となる文字だけを入力するだけで済みます。 インクリメンタル・モードの検索を中止するのには、 <ESC>文字を使います。 <C-j>でも、 検索は中止されます。 <C-g>は、 インクリメンタル・モードの検索を終了させて、 元の行を表示します。 検索が中止されると、 検索文字列を含むヒストリ・エントリがカレント行となります。 検索文字列にマッチする他のエントリをヒストリ・リストから見つけるためには、 必要に応じて<C-s>または<C-r>を入力します。 これによって、 それまでに入力された検索文字列にマッチする次のエントリをヒストリから見つけるために、 下の方向、 または、 上の方向に検索が行われます。 Readlineコマンドにバインドされているキー・シーケンスのうち上記以外のものを入力すると、 検索は中止され、 そのコマンドが実行されます。 例えば <RET>が入力されると、 検索は中止され、 そのときの行が受け入れられたことになります。 したがって、 ヒストリ・リストの中のそのコマンドが実行されます。
非インクリメンタル(non-incremental)・モードでは、 マッチするヒストリ行の検索を開始する前に、 検索文字列全体を読み込みます。 検索文字列は、 ユーザによって入力されたものでも構いませんし、 カレント行の内容の一部であっても構いません。
Readlineライブラリには、
emacs
スタイルのキー・バインディングがデフォルトで組み込まれていますが、
異なるキー・バインディングを使うこともできます。
ホーム・ディレクトリ内のファイルinputrcにコマンドを記述することで、
誰でもReadlineを使うプログラムをカスタマイズすることができます。
このファイルの名前は、
環境変数INPUTRC
の値から取られます。
この変数に値がセットされていない場合のデフォルトは、
~/.inputrc
です。
Readlineライブラリを使うプログラムが起動されると、 初期化ファイルが読み込まれ、 キー・バインディングが設定されます。
さらに、
C-x C-r
コマンドを実行すると、
この初期化ファイルが再読み込みされます。
初期化ファイルに変更が加えられていれば、
その変更が反映されます。
Readline初期化ファイルの中では、
ほんの少数の基本的な構文だけが使用できます。
空行は無視されます。
#
で始まる行はコメントです。
$
で始まる行は、
条件構文を表わします
(see Conditional Init Constructs)。
その他の行は、
変数設定とキー・バインディングを示します。
set
コマンドを使用してReadlineの変数の値を変更することによって、
Readlineの実行時の振る舞いを変更することができます。
デフォルトのEmacsスタイルのキー・バインディングを変更して、
vi
の行編集コマンドを使用できるようにするには、
以下のようにします。
set editing-mode vi
以下の変数によって、 実行時の振る舞いのかなりの部分が変更可能です。
bell-style
none
がセットされると、
Readlineはベル音を鳴らしません。
visible
がセットされると、
視覚的なベル7
が利用可能であれば、
それを使います。
audible
(デフォルト)がセットされると、
Readlineは、
端末のベル音を鳴らそうと試みます。
comment-begin
insert-comment
コマンドが実行されたときに、
行の先頭に挿入される文字列です。
デフォルトの値は"#"
です。
completion-ignore-case
on
がセットされると、
Readlineは、
大文字・小文字を区別せずに、
ファイル名のマッチングや補完を行います。
デフォルトの値はoff
です。
completion-query-items
100
です。
convert-meta
on
がセットされると、
Readlineは、
第8ビットがセットされている文字をASCIIのキー・シーケンスに変換します。
これは、
該当文字の第8ビットを落として、
その前に<ESC>文字を付加することで、
メタ・プレフィックス・キー・シーケンス(meta-prefixed key sequence)
に変換することによって行われます。
デフォルトの値はon
です。
disable-completion
On
がセットされると、
Readlineは単語補完を抑制します。
補完文字(completion character)は、
あたかもself-insert
にマップされたかのように、
行内に挿入されます。
デフォルトはoff
です。
editing-mode
editing-mode
変数は、
デフォルトで使用するキー・バインディングの種類を制御します。
Readlineは、
デフォルトの状態では、
Emacs編集モードで起動します。
このモードは、
キー・ストロークがEmacsに非常に良く似ています。
この変数は、
emacs
とvi
のどちらかに設定することができます。
enable-keypad
on
がセットされると、
Readlineは、
呼び出されたときに、
アプリケーション・キーパッド(application keypad)を有効にすることを試みます。
システムによっては、
矢印キーを使用できるようにするために、
これが必要となります。
デフォルトはoff
です。
expand-tilde
on
がセットされると、
Readlineが単語補完を試みる際に、
チルダの展開が行われます。
デフォルトはoff
です。
horizontal-scroll-mode
on
とoff
のどちらかに設定することができます。
これをon
に設定すると、
1行のテキストの長さがスクリーン幅よりも長い場合に、
編集中の行のテキストが次の行に折り返すことなく、
同じ行の上で水平方向にスクロールするようになります。
デフォルトでは、
この変数にはoff
がセットされています。
keymap
keymap
名は、
emacs
、
emacs-standard
、
emacs-meta
、
emacs-ctlx
、
vi
、
vi-command
、
vi-insert
です。
vi
はvi-command
と同等です。
また、
emacs
はemacs-standard
と同等です。
デフォルトの値は、
emacs
です。
editing-mode
変数の値も、
デフォルトのキーマップに影響を及ぼします。
mark-directories
on
がセットされると、
補完されたディレクトリ名の後ろにスラッシュが付加されます。
デフォルトはon
です。
mark-modified-lines
on
がセットされると、
Readlineは、
変更されたヒストリ行の先頭にアスタリスク(*
)を表示します。
この変数は、
デフォルトではoff
です。
input-meta
on
がセットされると、
Readlineは、
8ビット入力に対する端末側のサポートがどうであれ、
8ビット入力を有効にします
(読み込まれた文字の第8ビットを落としません)。
デフォルト値はoff
です。
meta-flag
は、
この変数の別名です。
output-meta
on
がセットされると、
Readlineは、
第8ビットがセットされている文字を、
メタ・プレフィックス・エスケープ・シーケンス
(meta-prefixed escape sequence)
としてではなく、
直接表示します。
デフォルトはoff
です。
print-completions-horizontally
on
がセットされると、
Readlineは、
マッチする補完候補をアルファベット順にソートして、
画面の下向きにではなく、
水平方向に並べて表示します。
デフォルトはoff
です。
show-all-if-ambiguous
on
がセットされると、
複数の補完候補を持つ単語は、
ベル音を鳴らすことなく、
直ちに補完候補を一覧表示させます。
デフォルト値はoff
です。
visible-stats
on
がセットされると、
補完候補を一覧表示する際に、
ファイル・タイプを示す文字がファイル名の後ろに付加されます。
デフォルトはoff
です。
コマンドの名前を知っていれば、 初期化ファイルの中で、 コマンドにバインドしたいキーの名前、 コロン、 そして最後にコマンドの名前を、 1行にして記述するだけです。 キーの名前は、 好みに応じて異なる方法で表現することができます。
Control-u: universal-argument Meta-Rubout: backward-kill-word Control-o: "> output"
上の例では、
<C-u>が関数universal-argument
にバインドされ、
<C-o>がその右側に記述されたマクロ
(行内に> output
というテキストを挿入するマクロ)
を実行するようバインドされます。
"\C-u": universal-argument "\C-x\C-r": re-read-init-file "\e[11~": "Function Key 1"
上の例では、
<C-u>が
(最初の例と同様)
関数universal-argument
に、
<C-x> <C-r>
が関数re-read-init-file
に、
<ESC> <[> <1> <1> <~>
がFunction Key 1
というテキストを挿入するよう、
それぞれバインドされています。
キー・シーケンスを指定する際には、 以下のGNU Emacsスタイルのエスケープ・シーケンスが利用できます。
\C-
\M-
\e
\\
\"
\'
GNU Emacsスタイルのエスケープ・シーケンスに加えて、 別のバックスラッシュ・エスケープ群が利用できます。
\a
\b
\d
\f
\n
\r
\t
\v
\nnn
\xnnn
マクロのテキストを入力する際には、
マクロ定義であることを示すために、
単一引用符または二重引用符を使わなければなりません。
引用符に囲まれないテキストは、
関数名であると見なされます。
マクロ本体においては、
上記のバックスラッシュ・エスケープは展開されます。
バックスラッシュとそれに続く文字の組み合わせがバックスラッシュ・エスケープに該当しない場合、
マクロのテキストの中のバックスラッシュは、
"
や'
も含めて、
直後にある文字を引用します。
例えば、
以下のバインディングによって、
C-x \
は、
行内に\
を1つ挿入することになります。
"\C-x\\": "\\"
Readlineは、 Cのプリプロセッサにおける条件コンパイル機能と質的に類似した機能を実装しています。 これによって、 あるテストの結果に応じてキー・バインディングや変数設定が実行されるようにすることができます。 4種類のパーサ指示子が使われます。
$if
$if
は、
編集モード、
使用されている端末、
あるいは、
Readlineを使用しているアプリケーションに応じてバインディングが行われるようにすることを可能にします。
$if
の後ろに、
テストされる内容が行末まで続きます。
テストされる内容をほかのものと分離するために特別に文字を使う必要はありません。
mode
emacs
モードとvi
モードのどちらで動作しているかをテストするために、
$if
指示子の一形式であるmode=
が使用されます。
例えば、
Readlineがemacs
モードで開始されている場合にのみ、
emacs-standard
やemacs-ctlx
のキーマップでバインディングをセットするようにするために、
これをset keymap
コマンドと組み合わせて使用することができます。
term
term=
という形式は、
端末のファンクション・キーによって特定のキー・シーケンスが出力されるようなバインディングを行うなどの目的で、
端末固有のキー・バインディングを組み込むために使用することができます。
=
の右側の単語は、
端末の完全名と、
端末の名前のうち最初の-
までの部分の両方に対してテストされます。
これにより、
例えばsun
は、
sun
とsun-cmd
の両方にマッチすることになります。
application
$if Bash # カレントな単語、または、1つ前の単語を引用符で囲む "\C-xq": "\eb\"\ef\"" $endif
$endif
$if
コマンドを終わらせます。
$else
$if
指示子から枝分かれしたこの部分に記述されたコマンドは、
テスト結果が偽であった場合に実行されます。
$include
$include /etc/inputrc
以下に、 inputrcファイルの実例を示します。 この中では、 キー・バインディング、 変数割り当て、 条件構文の例が示されています。
# このファイルは、Gnu Readlineライブラリを使うプログラムの行入力編集 # の振る舞いを制御する。Gnu Readlineライブラリを使うプログラムには、 # FTP、Bash、Gdbなどがある。 # # inputrcファイルは、C-x C-rによって再読み込みすることができる。 # '#'で始まる行は、コメントである。 # # 最初に、/etc/Inputrcからシステム全体のバインディングと変数割り当て # を取り込む。 $include /etc/Inputrc # # emacsモードにおける種々のバインディングをセットする。 set editing-mode emacs $if mode=emacs Meta-Control-h: backward-kill-word 関数名の後ろのテキストは無視される。 # # キーパッド・モードにおける矢印キー # #"\M-OD": backward-char #"\M-OC": forward-char #"\M-OA": previous-history #"\M-OB": next-history # # ANSIモードにおける矢印キー # "\M-[D": backward-char "\M-[C": forward-char "\M-[A": previous-history "\M-[B": next-history # # 8ビット・キーパッド・モードにおける矢印キー # #"\M-\C-OD": backward-char #"\M-\C-OC": forward-char #"\M-\C-OA": previous-history #"\M-\C-OB": next-history # # 8ビットANSIモードにおける矢印キー # #"\M-\C-[D": backward-char #"\M-\C-[C": forward-char #"\M-\C-[A": previous-history #"\M-\C-[B": next-history C-q: quoted-insert $endif # 旧スタイルのバインディング。これがたまたまデフォルトでもある。 TAB: complete # シェルとのやりとりにおいて便利なマクロ $if Bash # パス(PATH)の編集 "\C-xp": "PATH=${PATH}\e\C-e\C-a\ef\C-f" # 引用符で囲まれた単語を入力するための準備 -- 先頭と末尾の二重引用符 # を挿入して、先頭の引用符の直後に移動 "\C-x\"": "\"\"\C-b" # バックスラッシュを挿入 # (シーケンスやマクロにおいて、バックスラッシュ・エスケープをテストする) "\C-x\\": "\\" # カレントな単語、または、1つ前の単語を引用符で囲む "\C-xq": "\eb\"\ef\"" # バインドされていない行再表示コマンドにバインディングを追加 "\C-xr": redraw-current-line # カレント行において変数を編集 "\M-\C-v": "\C-a\C-k$\C-y\M-\C-e\C-a\C-y=" $endif # 視覚的なベルが利用可能であれば、それを使う set bell-style visible # 読み込みの際に、文字の第8ビットを落とさない set input-meta on # iso-latin1文字は、プレフィックス・メタ・シーケンスに変換せず、 # そのまま挿入する set convert-meta off # 第8ビットがセットされている文字を、メタ・プレフィックス文字として # ではなく、直接表示する set output-meta on # ある単語について、150を超える補完候補が存在する場合、ユーザに対して # すべてを表示させたいかどうかを問い合わせる set completion-query-items 150 # FTP用 $if Ftp "\C-xg": "get \M-?" "\C-xt": "put \M-?" "\M-.": yank-last-arg $endif
このセクションでは、 キー・シーケンスにバインドすることが可能なReadlineコマンドについて説明します。
beginning-of-line (C-a)
end-of-line (C-e)
forward-char (C-f)
backward-char (C-b)
forward-word (M-f)
backward-word (M-b)
clear-screen (C-l)
redraw-current-line ()
accept-line (Newline, Return)
previous-history (C-p)
next-history (C-n)
beginning-of-history (M-<)
end-of-history (M->)
reverse-search-history (C-r)
forward-search-history (C-s)
non-incremental-reverse-search-history (M-p)
non-incremental-forward-search-history (M-n)
history-search-forward ()
history-search-backward ()
yank-nth-arg (M-C-y)
yank-last-arg (M-., M-_)
yank-nth-arg
と同じように動作します。
yank-last-arg
を連続して実行すると、
ヒストリ・リストを遡って移動していきます。
したがって、
各行の最後の引数が順番に挿入されていきます。
delete-char (C-d)
delete-char
にバインドされていない場合は、
EOF
を返します。
backward-delete-char (Rubout)
quoted-insert (C-q, C-v)
tab-insert (M-TAB)
self-insert (a, b, A, 1, !, ...)
transpose-chars (C-t)
transpose-words (M-t)
upcase-word (M-u)
downcase-word (M-l)
capitalize-word (M-c)
kill-line (C-k)
backward-kill-line (C-x Rubout)
unix-line-discard (C-u)
kill-whole-line ()
kill-word (M-d)
forward-word
の場合と同様です。
backward-kill-word (M-DEL)
backward-word
の場合と同様です。
unix-word-rubout (C-w)
delete-horizontal-space ()
kill-region ()
copy-region-as-kill ()
copy-backward-word ()
backward-word
の場合と同様です。
デフォルトでは、
このコマンドはバインドされていません。
copy-forward-word ()
forward-word
の場合と同様です。
デフォルトでは、
このコマンドはバインドされていません。
yank (C-y)
yank-pop (M-y)
digit-argument (M-0, M-1, ... M--)
universal-argument ()
universal-argument
を再実行することによって、
その数字引数を終わらせることができます。
しかし、
このコマンドの後ろに数字が続かない場合の再実行は、
無視されます。
特殊なケースとして、
このコマンドの直後に数字でもマイナス記号でもない文字が続く場合、
次に実行されるコマンドの引数カウントは4倍されます。
引数カウントの初期値は1です。
したがって、
この関数を最初に実行した後には、
引数カウントは4になり、
2回目に実行した後には16になります。
以下、
同様です。
デフォルトでは、
キーへのバインドはされていません。
complete (TAB)
possible-completions (M-?)
insert-completions (M-*)
possible-completions
を実行すれば生成されたであろうテキストの補完候補をすべて、
ポイントの前に挿入します。
menu-complete ()
complete
に似ていますが、
補完されるべき単語を、
補完候補の一覧の中の1つと置き換えます。
menu-complete
を繰り返し実行すると、
補完候補の一覧から順番に1つずつ補完候補が挿入されていきます。
候補一覧の終端に達すると、
ベル音が鳴らされ、
補完前のテキストが復元されます。
引数nを指定すると、
補完候補の一覧の中でn個先に移動します。
一覧を逆方向に戻るために、
負の引数を指定することができます。
このコマンドは、
TAB
にバインドすることを意図したものですが、
デフォルトではバインドされていません。
start-kbd-macro (C-x ()
end-kbd-macro (C-x ))
call-last-kbd-macro (C-x e)
re-read-init-file (C-x C-r)
abort (C-g)
bell-style
の設定次第では)
端末のベル音を鳴らします。
do-uppercase-version (M-a, M-b, M-x, ...)
prefix-meta (ESC)
ESC f
を入力するのは、
M-f
を入力するのと同じことです。
undo (C-_, C-x C-u)
revert-line (M-r)
undo
コマンドを、
行を元の状態に戻すのに必要な回数繰り返して実行するようなものです。
tilde-expand (M-~)
set-mark (C-@)
exchange-point-and-mark (C-x C-x)
character-search (C-])
character-search-backward (M-C-])
insert-comment (M-#)
comment-begin
変数の値が挿入され、
挿入後の行が、
あたかも改行が入力されたかのように、
受け付けられます。
dump-functions ()
dump-variables ()
dump-macros ()
vi
モードReadlineライブラリは、
vi
の編集機能のフルセットを提供してはいませんが、
簡単な行編集を行うのに十分な機能は備えています。
Readlineのvi
モードは、
POSIX 1003.2標準にしたがって動作します。
emacs
編集モードとvi
編集モードを対話的に切り替えるには、
コマンドM-C-j(toggle-editing-mode)を使用してください。
Readlineのデフォルトはemacs
モードです。
vi
モードで行入力を行うときには、
あたかもi
を入力したかのように、
最初から「挿入」モードになっています。
<ESC>を押すと「コマンド」モードになり、
標準的なvi
の移動キーによって行のテキストを編集することができます。
すなわち、
k
により前のヒストリ行に移動すること、
j
によって後ろのヒストリ行に移動すること、
などが可能です。
ここでは、 ユーザの見地に立って、 GNUヒストリ・ライブラリの対話的な使い方を説明します。
ヒストリ・ライブラリは、
csh
のヒストリ展開機能に似た機能を提供します。
以下において、
ヒストリ情報を操作するための構文を説明します。
ヒストリ展開は2つの部分から構成されます。 第1の部分で、 過去のヒストリのどの行が代替処理に使用されるかが決まります。 この行をイベントと呼びます。 第2の部分で、 この行のうちどの部分がカレント行に挿入されるかが決まります。 この部分のことをワードと呼びます。 GDBは、 Bashシェルと同様の方法によって行をワードに分割します。 したがって、 引用符によって囲まれた複数の英単語(あるいはUNIX用語)は1つのワードとみなされます。
イベント指定子とは、 ヒストリ・リスト内のコマンド行エントリへの参照です。
!
!!
!-1
と同義です。
!n
!-n
!string
!?string
[?
]
コロン(<:>)が、 イベント指定子とワード指定子の区切り文字になります。 ワード指定子が<^>、 <$>、 <*>、 <%>で始まる場合は、 この区切り文字は省略することができます。 ワードは行の先頭から番号が付与され、 最初のワードは0(ゼロ)番になります。
0 (zero)
n
^
$
%
?string?
検索にマッチしたワードです。
x-y
-y
は、
0-y
の省略形です。
*
1-$
と同義です。
イベントの内部にワードが1つしかなくても、
<*>の使用はエラーにはなりません。
この場合には、
空の文字列が返されます。
必須ではないワード指定子に続けて、 以下の修飾子を1つ以上連続して追加することができます。 個々の修飾子の前にコロン(<:>)を付けます。
#
h
r
.
suffix形式の拡張子を削除したベース名です。
e
t
p
gdb
サブディレクトリにあります。
PostScriptまたはGhostscriptを使えるプリンタがあれば、
refcard.ps
を使ってすぐにリファレンス・カードを印刷することができます。
GDB 4には、
リファレンス・カードのソースも含まれています。
TeXを使えば、
以下のようにしてこれをフォーマットすることができます。
make refcard.dviGDBのリファレンス・カードは、 米国のレター・サイズの用紙にランドスケープ・モードで印刷するようにデザインされています。 レター・サイズは、 横幅が11インチ、 高さが8.5インチです。 DVI出力プログラムへのオプションとして、 この印刷形式を指定する必要があります。
すべてのGDBドキュメントは、
マシン上で読むことのできるディストリビューションの一部として提供されます。
ドキュメントはTexinfoフォーマットで記述されています。
これは、
単一のソースからオンライン・マニュアルとハードコピー・マニュアルの両方を生成するドキュメント・システムです。
Infoフォーマット・コマンドの1つを使ってオンライン・ドキュメントを作成することができ、
TeX
(またはtexi2roff
)
を使ってハード・コピーの組版ができます。
GDBには、
このマニュアルのフォーマット済みのオンラインInfoバージョンも含まれています。
これは、
gdb
サブディレクトリにあります。
メインのInfoファイルはgdb-4.18/gdb/gdb.info
で、
同じディレクトリにあるgdb.info*
にマッチする従属ファイルを参照します。
必要であれば、
これらのファイルを印刷したり、
任意のエディタで表示して読むこともできます。
しかし、
これらのファイルは、
GNU Emacsのinfo
サブシステムや
GNU Texinfoの一部として配布されるスタンドアロンのinfo
プログラムを使った方が読みやすいでしょう。
これらのInfoファイルを自分でフォーマットしたいのであれば、
texinfo-format-buffer
やmakeinfo
のようなInfoフォーマット・プログラムが必要になります。
makeinfo
がインストールされていて、
GDBソース・ディレクトリのトップ・レベル
(バージョン4.18ではgdb-4.18
)
にいる場合は、
以下のようにしてInfoファイルを作成することができます。
cd gdb make gdb.info
このマニュアルのコピーの組版を行って印刷するには、
TeX、
TeXのDVI出力ファイルを印刷するプログラム、
および、
Texinfo定義ファイルtexinfo.tex
が必要です。
TeXは組版プログラムです。
TeXは直接ファイルを印刷しませんが、
DVIファイルと呼ばれるものを生成します。
組版されたドキュメントを印刷するには、
DVIファイルを印刷するプログラムが必要です。
システム上にTeXがインストールされていれば、
DVIファイルを印刷するプログラムも入っている可能性があります。
印刷に使われるコマンドの正確な名前はシステムにより異なります。
lpr -dが一般によく使われます。
また
(PostScriptプリンタでは)
dvipsがよく使われます。
DVIプリント・コマンドを使う際には、
ファイル名に拡張子を付けないか、
あるいは、
.dvi
という拡張子を付ける必要があるかもしれません。
また、
TeXはtexinfo.tex
という名のマクロ定義ファイルを必要とします。
このファイルはTeXに対して、
Texinfoフォーマットで記述されたドキュメントをどのようにして組版するかを教えます。
TeXは自分自身では、
Texinfoファイルを読むことも組版することもできません。
texinfo.tex
はGDBととともに配布されていて、
gdb-version-number/texinfo
ディレクトリにあります。
TeXとDVI印刷プログラムがインストールされていれば、
このマニュアルを組版して、
印刷することができます。
メインのソース・ディレクトリの下のgdb
サブディレクトリ
(例えば、
gdb-4.18/gdb
)
に移動して、
以下のように実行します。
make gdb.dvi
その後、
gdb.dvi
をDVI印刷プログラムに渡します。
configure
スクリプトが付属しています。
configure
を実行した後にmake
を実行することで、
gdb
をビルドすることができます。
GDBディストリビューションには、
GDBをビルドするのに必要なすべてのソース・コードが、
単一のディレクトリの下に収められています。
このディレクトリの名前は通常、
gdb
の後ろにバージョン番号を付加したものです。
例えば、
バージョン4.18のGDBディストリビューションは、
gdb-4.18
というディレクトリに収められています。
このディレクトリには、
以下のものが含まれます。
gdb-4.18/configure (およびサポート・ファイル)
gdb-4.18/gdb
gdb-4.18/bfd
gdb-4.18/include
gdb-4.18/libiberty
-liberty
フリー・ソフトウェア・ライブラリのソース
gdb-4.18/opcodes
gdb-4.18/readline
gdb-4.18/glob
gdb-4.18/mmalloc
gdb-version-number
ソース・ディレクトリからconfigure
を実行することです。
ここでの例では、
このディレクトリはgdb-4.18
です。
もしまだgdb-version-number
ソース・ディレクトリにいないのであれば、
まずそこに移動してください。
続いてconfigure
を実行します。
GDBが実行されるプラットフォームの識別子を引数として渡します。
例えば、 以下のようにします。
cd gdb-4.18 ./configure host make
hostは、
GDBが実行されるプラットフォームを識別する識別子です。
例えばsun4
やdecstation
などです
(多くの場合hostは省略することができます。
この場合configure
は、
ユーザのシステムを調べることによって正しい値を推定しようとします)。
configure host
を実行した後にmake
を実行することで、
bfd
、
readline
、
mmalloc
、
libiberty
の各ライブラリがビルドされ、
最後にgdb
自体がビルドされます。
構成されたソース・ファイルやバイナリは、
対応するソース・ディレクトリに残されます。
configure
はBourneシェル
(/bin/sh
)
のスクリプトです。
ユーザが別のシェルを実行していて、
システムがこのことを自動的に認識してくれない場合は、
明示的にsh
にスクリプトを実行させる必要があるかもしれません。
sh configure host
バージョン4.18のソース・ディレクトリであるgdb-4.18
のように、
配下に複数のライブラリやプログラムのソース・ディレクトリを含むディレクトリからconfigure
を実行すると、
configure
は配下にあるそれぞれのディレクトリのための構成ファイルを作成します
(--norecursion
オプションによって、
そうしないよう指定した場合は別です)。
GDBディストリビューションの中の特定のサブディレクトリを構成したいだけの場合には、
そのサブディレクトリからconfigure
スクリプトを実行することができます。
ただし、
configure
スクリプトへのパスを必ず指定してください。
例えば、
バージョン4.18では、
bfd
サブディレクトリだけを構成するには以下のようにします。
cd gdb-4.18/bfd ../configure host
gdb
はどこにでもインストールできます。
あらかじめ固定されたパスは1つもありません。
ただし、
ユーザのパスにある
(SHELL
環境変数により指定される)
シェルが誰にでも読み込み可能であることを確かめる必要があります。
GDBはシェルを使ってユーザ・プログラムを起動するということを憶えておいてください。
子プロセスが読み込み不可のプログラムである場合、
システムによっては、
GDBがそれをデバッグするのを拒否します。
いくつかのホスト・マシンおよびターゲット・マシン用のGDBを実行したい場合、
ホストとターゲットの個々の組み合わせ用にコンパイルされた異なるgdb
が必要になります。
configure
には、
個々の構成をソース・ディレクトリにではなく個別のサブディレクトリに生成する機能があり、
このようなことが簡単にできるように設計されています。
ユーザの使っているmake
プログラムにVPATH
機能があれば
(GNU make
にはあります)、
これら個々のディレクトリにおいてmake
を実行することで、
そこで指定されているgdb
プログラムをビルドすることができます。
個別のディレクトリにおいてgdb
をビルドするには、
ソースの置かれている場所を指定するために、
--srcdir
オプションを使ってconfigure
を実行します
(同時に、
ユーザの作業ディレクトリからconfigure
を見つけるためのパスも指定する必要があります。
もし、
configure
へのパスが--srcdir
への引数として指定するものと同じであれば、
--srcdir
オプションは指定しなくてもかまいません。
指定されなければ、
同じであると仮定されます)。
例えば、 バージョン4.18でSun 4用のGDBを別のディレクトリにおいて構築するには、 以下のようにします。
cd gdb-4.18 mkdir ../gdb-sun4 cd ../gdb-sun4 ../gdb-4.18/configure sun4 make
configure
が、
別の場所にあるソース・ディレクトリを使って、
ある構成を作成する際には、
ソース・ディレクトリ配下のディレクトリ・ツリーと同じ構造のディレクトリ・ツリーを
(同じ名前で)
バイナリ用に作成します。
この例では、
Sun 4用のライブラリlibiberty.a
はgdb-sun4/libiberty
ディレクトリに、
GDB自身はgdb-sun4/gdb
ディレクトリにそれぞれ作成されます。
いくつかのGDBの構成を別々のディレクトリにおいてビルドする理由としてよくあるのが、
クロス・コンパイル
(GDBはホストと呼ばれるあるマシン上で動作し、
ターゲットと呼ばれる別のマシンで実行されているプログラムをデバッグする)
環境用にGDBを構成する場合です。
クロス・デバッグのターゲットは、
configure
に対する--target=target
オプションを使って指定します。
プログラムやライブラリをビルドするためにmake
を実行するときには、
構成されたディレクトリにいなければなりません。
これは、
configure
を実行したときにいたディレクトリ
(または、
そのサブディレクトリの1つ)
です。
configure
が個別のソース・ディレクトリに生成したMakefile
は再帰的に呼び出されます。
gdb-4.18
(あるいは、
--srcdir=dirname/gdb-4.18
により構成された別のディレクトリ)
などのソース・ディレクトリにおいてmake
を実行すると、
必要とされるすべてのライブラリがビルドされ、
その後にGDBがビルドされることになります。
複数のホストまたはターゲットの構成が、
異なる複数のディレクトリに存在する場合、
(例えば、
それらが個々のホスト上にNFSマウントされている場合)
並行してmake
を実行することができます。
複数の構成が互いに干渉し合うということはありません。
configure
スクリプトにおけるホストおよびターゲットの指定方法は、
3つの名称部分を持ちますが、
あらかじめ定義された短い別名もいくつかサポートされています。
完全名は、
以下のようなパターンの3つの情報部分を持ちます。
architecture-vendor-os
例えば、
ホストを指定する引数hostとして、
あるいは、
--target=target
オプションのtargetの部分に、
sun4
という別名を使うことができます。
これと同等の完全名はsparc-sun-sunos4
です。
GDBに付属しているconfigure
スクリプトには、
サポートされているすべてのホスト名、
ターゲット名、
および、
別名を問い合わせするための機能はありません。
configure
は、
Bourneシェル・スクリプトのconfig.sub
を呼び出すことによって、
省略名を完全名に対応付けします。
このスクリプトを使って、
省略名の意味が推測と合っているかどうかをテストすることもできます。
以下に例を示します。
% sh config.sub i386-linux i386-pc-linux-gnu % sh config.sub alpha-linux alpha-unknown-linux-gnu % sh config.sub hp9k700 hppa1.1-hp-hpux % sh config.sub sun4 sparc-sun-sunos4.1.1 % sh config.sub sun3 m68k-sun-sunos4.1.1 % sh config.sub i986v Invalid configuration `i986v': machine `i986v' not recognized
config.sub
も、
GDBディストリビューションの一部としてソース・ディレクトリ
(バージョン4.18では、gdb-4.18
)
に入っています。
configure
オプション以下に、
GDBをビルドする上でほとんどの場合に役に立つ
configure
のオプションと引数の要約を示します。
configure
には、
ここには挙げられていないオプションもいくつかあります。
configure
に関する完全な説明については、
see 。
configure [--help] [--prefix=dir] [--exec-prefix=dir] [--srcdir=dirname] [--norecursion] [--rm] [--target=target] host
そうしたいのであれば、
--
ではなく単一の-
でオプションを始めることもできますが、
--
を使うとオプション名を省略することができます。
--help
configure
の実行方法の簡単な要約を表示します。
--prefix=dir
dir
にインストールするよう
ソースを構成します。
--exec-prefix=dir
dir
にインストールするよう
ソースを構成します。
--srcdir=dirname
make
、
あるいは、
VPATH
機能を持つ他のmake
を使用する必要があります。configure
は、
構成に固有のファイルをカレント・ディレクトリに書き込みますが、
dirnameディレクトリにあるソースを使うように、
それらのファイルを調整します。
configure
は、
dirnameディレクトリ配下のソース・ディレクトリ・ツリーと同じ構造を持つディレクトリ・ツリーを、
作業ディレクトリの下に作成します。
--norecursion
configure
が実行されたディレクトリ・レベルだけを構成します。
サブディレクトリまで含めて構成することはしません。
--target=target
利用可能なすべてのターゲットの一覧を生成する、
便利な方法はありません。
host ...
利用可能なすべてのホストの一覧を生成する、 便利な方法はありません。
ほかにも利用可能な多くのオプションがありますが、 これは通常、 特殊な目的にのみ必要とされるものです。
#
: Command Syntax
#
in Modula-2: GDB/M2
$
: Value History
$$
: Value History
$_
: Convenience Vars
$_
and info breakpoints
: Set Breaks
$_
and info line
: Machine Code
$_
, $__
, and value history: Memory
$__
: Convenience Vars
$_exitcode
: Convenience Vars
$bpnum
: Set Breaks
$cdir
: Source Path
$cwd
: Source Path
.
: M2 Scope
.esgdbinit
: Command Files
.gdbinit
: Command Files
.os68gdbinit
: Command Files
.vxgdbinit
: Command Files
/proc
: Process Information
@
: Arrays
add-shared-symbol-file
: Files
add-symbol-file
: Files
attach
: Attach
awatch
: Set Watchpoints
b
: Set Breaks
backtrace
: Backtrace
bell-style
: Readline Init File Syntax
break
: Set Breaks
break ... thread threadno
: Thread Stops
breakpoint
subroutine, remote: Stub Contents
breakpoint
サブルーチン、リモート: Stub Contents
bt
: Backtrace
c
: Continuing and Stepping
call
: Calling
catch
: Set Catchpoints
catch catch
: Set Catchpoints
catch exec
: Set Catchpoints
catch fork
: Set Catchpoints
catch load
: Set Catchpoints
catch throw
: Set Catchpoints
catch unload
: Set Catchpoints
catch vfork
: Set Catchpoints
cd
: Working Directory
cdir
: Source Path
clear
: Delete Breaks
commands
: Break Commands
comment-begin
: Readline Init File Syntax
Compiling
: Sparclet Remote
complete
: Help
completion-query-items
: Readline Init File Syntax
condition
: Conditions
continue
: Continuing and Stepping
convert-meta
: Readline Init File Syntax
core
: Files
core-file
: Files
cwd
: Source Path
d
: Delete Breaks
define
: Define
delete
: Delete Breaks
delete display
: Auto Display
detach
: Attach
device
: Hitachi Boards
dir
: Source Path
directory
: Source Path
dis
: Disabling
disable
: Disabling
disable breakpoints
: Disabling
disable display
: Auto Display
disable-completion
: Readline Init File Syntax
disassemble
: Machine Code
display
: Auto Display
do
: Selection
document
: Define
down
: Selection
down-silently
: Selection
eb.log
: Remote Log
EBMON
: Comms (EB29K)
echo
: Output
editing-mode
: Readline Init File Syntax
else
: Define
enable
: Disabling
enable breakpoints
: Disabling
enable display
: Auto Display
enable-keypad
: Readline Init File Syntax
end
: Break Commands
exceptionHandler
: Bootstrapping
exec-file
: Files
expand-tilde
: Readline Init File Syntax
f
: Selection
fg
: Continuing and Stepping
file
: Files
finish
: Continuing and Stepping
flush_i_cache
: Bootstrapping
fork
を呼び出す関数のデバッグ[forkをよびだすかんすうのデバッグ]: Processes
forward-search
: Search
frame
: Selection, Frames
g++
: C
GDBHISTFILE
: History
gdbserve.nlm
: NetWare
gdbserver
: Server
getDebugChar
: Bootstrapping
h
: Help
handle
: Signals
handle_exception
: Stub Contents
hbreak
: Set Breaks
help
: Help
help target
: Target Commands
help user-defined
: Define
heuristic-fence-post
(Alpha,MIPS): Alpha/MIPS Stack
horizontal-scroll-mode
: Readline Init File Syntax
i
: Help
i386-stub.c
: Remote Serial
if
: Define
ignore
: Conditions
INCLUDE_RDB
: VxWorks Remote
info
: Help
info address
: Symbols
info all-registers
: Registers
info args
: Frame Info
info breakpoints
: Set Breaks
info catch
: Frame Info
info display
: Auto Display
info extensions
: Show
info f
: Frame Info
info files
: Files
info float
: Floating Point Hardware
info frame
: Show, Frame Info
info functions
: Symbols
info line
: Machine Code
info locals
: Frame Info
info proc
: Process Information
info proc id
: Process Information
info proc mappings
: Process Information
info proc status
: Process Information
info proc times
: Process Information
info program
: Stopping
info registers
: Registers
info s
: Backtrace
info set
: Help
info share
: Files
info sharedlibrary
: Files
info signals
: Signals
info source
: Symbols, Show
info sources
: Symbols
info stack
: Backtrace
info target
: Files
info terminal
: Input/Output
info threads
: Threads
info types
: Symbols
info variables
: Symbols
info watchpoints
: Set Watchpoints
input-meta
: Readline Init File Syntax
inspect
: Data
jump
: Jumping
keymap
: Readline Init File Syntax
kill
: Kill Process
l
: List
list
: List
load filename
: Target Commands
m68k-stub.c
: Remote Serial
maint info breakpoints
: Set Breaks
maint print psymbols
: Symbols
maint print symbols
: Symbols
make
: Shell Commands
make
の呼び出し[makeのよびだし]: Shell Commands
mapped
: Files
mark-modified-lines
: Readline Init File Syntax
memset
: Bootstrapping
meta-flag
: Readline Init File Syntax
remotedebug
protocol: MIPS Remote
remotedebug
プロトコル: MIPS Remote
#
: GDB/M2
n
: Continuing and Stepping
New systag
: Threads
next
: Continuing and Stepping
nexti
: Continuing and Stepping
ni
: Continuing and Stepping
output
: Output
output-meta
: Readline Init File Syntax
path
: Environment
print
: Data
printf
: Output
ptype
: Symbols
putDebugChar
: Bootstrapping
pwd
: Working Directory
q
: Quitting GDB
quit
[expression
]
: Quitting GDB
rbreak
: Set Breaks
readnow
: Files
remotedebug
, MIPS protocol: MIPS Remote
remotedebug
、MIPSプロトコル: MIPS Remote
remotetimeout
: Sparclet Remote
reset
: Nindy Reset
RET
: Command Syntax
retransmit-timeout
, MIPS protocol: MIPS Remote
retransmit-timeout
、MIPSプロトコル: MIPS Remote
return
: Returning
reverse-search
: Search
run
: Starting
Running
: Sparclet Remote
rwatch
: Set Watchpoints
s
: Continuing and Stepping
search
: Search
section
: Files
select-frame
: Frames
target remote
: Debug Session
set
: Help
set args
: Arguments
set assembly-language
: Machine Code
set check
: Range Checking, Type Checking
set check range
: Range Checking
set check type
: Type Checking
set complaints
: Messages/Warnings
set confirm
: Messages/Warnings
set demangle-style
: Print Settings
set editing
: Editing
set endian auto
: Byte Order
set endian big
: Byte Order
set endian little
: Byte Order
set environment
: Environment
set extension-language
: Show
set gnutarget
: Target Commands
set height
: Screen Size
set history expansion
: History
set history filename
: History
set history save
: History
set history size
: History
set input-radix
: Numbers
set language
: Manually
set listsize
: List
set machine
: Hitachi Special
set memory mod
: Hitachi Special
set mipsfpu
: MIPS Remote
set output-radix
: Numbers
set print address
: Print Settings
set print array
: Print Settings
set print asm-demangle
: Print Settings
set print demangle
: Print Settings
set print elements
: Print Settings
set print max-symbolic-offset
: Print Settings
set print null-stop
: Print Settings
set print object
: Print Settings
set print pretty
: Print Settings
set print sevenbit-strings
: Print Settings
set print static-members
: Print Settings
set print symbol-filename
: Print Settings
set print union
: Print Settings
set print vtbl
: Print Settings
set processor args
: MIPS Remote
set prompt
: Prompt
set remotedebug
: MIPS Remote, Protocol
set retransmit-timeout
: MIPS Remote
set rstack_high_address
: Registers
set symbol-reloading
: Symbols
set timeout
: MIPS Remote
set variable
: Assignment
set verbose
: Messages/Warnings
set width
: Screen Size
set write
: Patching
set_debug_traps
: Stub Contents
sh-stub.c
: Remote Serial
share
: Files
sharedlibrary
: Files
shell
: Shell Commands
show
: Help
show args
: Arguments
show check range
: Range Checking
show check type
: Type Checking
show commands
: History
show complaints
: Messages/Warnings
show confirm
: Messages/Warnings
show convenience
: Convenience Vars
show copying
: Help
show demangle-style
: Print Settings
show directories
: Source Path
show editing
: Editing
show endian
: Byte Order
show environment
: Environment
show gnutarget
: Target Commands
show height
: Screen Size
show history
: History
show input-radix
: Numbers
show language
: Show
show listsize
: List
show machine
: Hitachi Special
show mipsfpu
: MIPS Remote
show output-radix
: Numbers
show paths
: Environment
show print address
: Print Settings
show print array
: Print Settings
show print asm-demangle
: Print Settings
show print demangle
: Print Settings
show print elements
: Print Settings
show print max-symbolic-offset
: Print Settings
show print object
: Print Settings
show print pretty
: Print Settings
show print sevenbit-strings
: Print Settings
show print static-members
: Print Settings
show print symbol-filename
: Print Settings
show print union
: Print Settings
show print vtbl
: Print Settings
show processor
: MIPS Remote
show prompt
: Prompt
show remotedebug
: MIPS Remote, Protocol
show retransmit-timeout
: MIPS Remote
show rstack_high_address
: Registers
show symbol-reloading
: Symbols
show timeout
: MIPS Remote
show user
: Define
show values
: Value History
show verbose
: Messages/Warnings
show version
: Help
show warranty
: Help
show width
: Screen Size
show write
: Patching
show-all-if-ambiguous
: Readline Init File Syntax
si
: Continuing and Stepping
signal
: Signaling
silent
: Break Commands
sim
: Simulator
sleep
: Processes
source
: Command Files
sparc-stub.c
: Remote Serial
sparcl-stub.c
: Remote Serial
speed
: Hitachi Boards
st2000 cmd
: ST2000 Remote
step
: Continuing and Stepping
stepi
: Continuing and Stepping
symbol-file
: Files
target
: Targets
target abug
: Target Commands
target adapt
: Target Commands
target amd-eb
: Target Commands
target array
: Target Commands
target bug
: Target Commands
target core
: Target Commands
target cpu32bug
: Target Commands
target dbug
: Target Commands
target ddb
: Target Commands
target ddb port
: MIPS Remote
target dink32
: Target Commands
target e7000
: Hitachi ICE, Target Commands
target es1800
: Target Commands
target est
: Target Commands
target exec
: Target Commands
target hms
: Target Commands
target lsi
: Target Commands
target lsi port
: MIPS Remote
target m32r
: Target Commands
target mips
: Target Commands
target mips port
: MIPS Remote
target mon960
: Target Commands
target nindy
: Target Commands
target nrom
: Target Commands
target op50n
: Target Commands
target pmon
: Target Commands
target pmon port
: MIPS Remote
target ppcbug
: Target Commands
target ppcbug1
: Target Commands
target r3900
: Target Commands
target rdi
: Target Commands
target rdp
: Target Commands
target remote
: Target Commands
target remote
、TCPポート: Debug Session
target remote
、シリアル回線[target remote
、シリアルかいせん]: Debug Session
target rom68k
: Target Commands
target rombug
: Target Commands
target sds
: Target Commands
target sh3
: Target Commands
target sh3e
: Target Commands
target sim
: Simulator, Target Commands
target sparclite
: Target Commands
target st2000
: Target Commands
target udi
: Target Commands
target vxworks
: Target Commands
target w89k
: Target Commands
tbreak
: Set Breaks
target remote
: Debug Session
thbreak
: Set Breaks
this
: Cplus expressions
thread apply
: Threads
thread threadno
: Threads
timeout
, MIPS protocol: MIPS Remote
timeout
、MIPSプロトコル: MIPS Remote
tty
: Input/Output
u
: Continuing and Stepping
udi
: UDI29K Remote
undisplay
: Auto Display
unset environment
: Environment
until
: Continuing and Stepping
up
: Selection
up-silently
: Selection
visible-stats
: Readline Init File Syntax
vxworks-timeout
: VxWorks Remote
watch
: Set Watchpoints
whatis
: Symbols
where
: Backtrace
while
: Define
x
: Memory
make
の[よびだし、makeの]: Shell Commands
$_
や$__
[あたいヒストリと$_や$__]: Memory
原注:フォーマット文字b
は使用できません。
フォーマット文字はx
コマンドでも共通して使用されますが、
x
コマンドでは、
b
はbyteの省略形として使用されているためです。
See Examining memory。
原注:これは、
スタックがメモリの下位方向に伸長するマシン
(最近のほとんどのマシンがそうです)
上において、
スタックから1ワードを取り除く方法です。
これは、
最下位のスタック・フレームが選択されていることを想定しています。
これ以外のスタック・フレームが選択されているときには、
$sp
に値を設定することは許されません。
マシン・アーキテクチャに依存することなくスタックからフレーム全体を取り除くには、
return
を使用します。
See Returning from a function。
原注:他のサービスによって使用されているポート番号を選択すると、
gdbserver
はエラー・メッセージを出力して終了します。
訳注:GNU Emacs 19 マニュアル(星雲社)の「ニューメリック引数」、 GNU Emacs マニュアル(共立出版)の「数引数」に、 日本語訳があります。
訳注:この日本語の翻訳マニュアルへの改善提案は、 ki@home.email.ne.jpに送ってください。
訳注:この日本語の翻訳マニュアルのバグは、 日本語(か英語)で、 ki@home.email.ne.jpに報告してください。
訳注: ベル音を鳴らす代わりに、 画面表示をフラッシュさせることを表わしています。
訳注:空白(スペース)、 水平タブ、 改行、 垂直タブ、 フォーム・フィード
原注:バージョン4.18ではgdb-4.18/gdb/refcard.ps
です。