[Contents]   [Back]   [Prev]   [Up]   [Next]   [Forward]  


デバッグ・ターゲットの指定

ターゲットとは、 ユーザ・プログラムが持つ実行環境を指します。 多くの場合、 GDBはユーザ・プログラムと同一のホスト環境上で実行されます。 この場合には、 fileコマンドやcoreコマンドを実行すると、 その副作用としてデバッグ・ターゲットが指定されます。 例えば、 物理的に離れた位置にあるホスト・マシン上でGDBを実行したい場合や、 シリアル・ポート経由でスタンドアロン・システムを制御したい場合、 または、 TCP/IP接続を利用してリアルタイム・システムを制御したい場合などのように、 より多くの柔軟性が必要とされる場合、 targetコマンドを使うことによって、 GDBに設定されたターゲットの種類の中から1つを指定することができます (ターゲットを管理するコマンドを参照)。

アクティブ・ターゲット

ターゲットには3つのクラスがあります。 プロセス、コア・ファイル、 そして、 実行ファイルです。 GDBは同時に、 1クラスにつき1つ、 全体で最高で3つまでアクティブなターゲットを持つことができます。 これにより、 (例えば) コア・ファイルに対して行ったデバッグ作業を破棄することなく、 プロセスを起動してその動作を調べることができます。 例えば、 `gdb a.out'を実行すると、 実行ファイルa.outが唯一のアクティブなターゲットになります。 コア・ファイル (おそらくは、 前回実行したときにクラッシュしてコア・ダンプしたもの) を併せて指定すると、 GDBは2つのターゲットを持ち、 メモリ・アドレスを知る必要がある場合には、 それを知るために2つのターゲットを並行して使用します。 この場合、 まずコア・ファイルを参照し、 次に実行ファイルを参照します。 (典型的には、 これら2つのクラスのターゲットは相互に補完的です。 というのも、 コア・ファイルには、 プログラムが持っている変数などの読み書き可能なメモリ域の内容とマシン・ステータスだけがあり、 実行ファイルには、 プログラムのテキストと初期化されたデータだけがあるからです)。 runコマンドを実行すると、 ユーザの実行ファイルはアクティブなプロセス・ターゲットにもなります。 プロセス・ターゲットがアクティブな間は、 メモリ・アドレスを要求するすべてのGDBコマンドは、 プロセス・ターゲットを参照します。 アクティブなコア・ファイル・ターゲットや 実行ファイル・ターゲットの中のアドレスは、 プロセス・ターゲットがアクティブな間は、 隠された状態になります。 新しいコア・ファイル・ターゲットや実行ファイル・ターゲットを選択するには、 core-fileコマンドやexec-fileコマンドを使用します (ファイルを指定するコマンドを参照)。 既に実行中のプロセスをターゲットとして指定するには、 attachコマンドを使用します (既に実行中のプロセスのデバッグを参照)。

ターゲットを管理するコマンド

target type parameters
GDBのホスト環境をターゲット・マシン またはターゲット・プロセスに接続します。 ターゲットとは、 典型的には、 デバッグ機能と通信するためのプロトコルを指します。 引数typeによって、 ターゲット・マシンの種類またはプロトコルを指定します。 parametersはターゲット・プロトコルによって解釈されるものですが、 典型的には、 接続すべきデバイス名やホスト名、 プロセス番号、 ボーレートなどが含まれます。 targetコマンドを実行した後にRETキーを押しても、 targetコマンドは再実行されません。
help target
利用可能なすべてのターゲットの名前を表示します。 現在選択されているターゲットを表示させるには、 info targetコマンドまたはinfo filesコマンドを使用します (ファイルを指定するコマンドを参照)。
help target name
ある特定のターゲットに関する説明を表示します。 選択時に必要となるパラメータも表示されます。
set gnutarget args
GDBは、 自分で持っているライブラリBFDを使用してユーザ・ファイルを読み込みます。 GDBは、 実行ファイルコア・ファイル.oファイルのどれを自分が読み込んでいるのかを知っています。 しかし、 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
GDB固有のプロトコルによる、 リモートのシリアル・ターゲットです。 引数devによって、 接続を確立するために使用するシリアル装置 (例えば、 `/dev/ttya') を指定します。 リモート・デバッグを参照してください。 target remoteは、 loadコマンドもサポートするようになりました。 これは、 スタブをターゲット・システム上に持っていく方法が別にあり、 かつ、 ダウンロードが実行されたときに破壊されないようなメモリ域にそれを置くことができる場合にのみ役に立ちます。
target sim
CPUシミュレータです。 シミュレートされたCPUターゲットを参照してください。

以下のターゲットはすべて、 特定のCPUに固有のものであり、 特定の構成においてのみ利用可能です。

target abug dev
M68K用のABug ROMモニタです。
target adapt dev
A29K用のAdaptモニタです。
target amd-eb dev speed PROG
シリアル回線により接続されている、 リモートのPCに組み込まれたAMD EB29Kボードです。 target remoteの場合と同様、 devはシリアル装置です。 speedによって回線速度を指定することができます。 PROGは、 デバッグ対象となるプログラムをPC上のDOSから見た場合の名前です。 AMD29KのEBMONプロトコルを参照してください。
target array dev
Array Tech LSI33K RAIDコントローラ・ボードです。
target bug dev
MVME187(m88k)ボード上で動作するBUGモニタです。
target cpu32bug dev
CPU32(M68K)ボード上で動作するCPU32BUGモニタです。
target dbug dev
Motorola ColdFire用のdBUG ROMモニタです。
target ddb dev
Mips Vr4300用のNEC DDBモニタです。
target dink32 dev
PowerPC用のDINK32 ROMモニタです。
target e7000 dev
日立H8、 SH用のE7000エミュレータです。
target es1800 dev
M68K用のES-1800エミュレータです。
target est dev
CPU32(M68K)ボード上で動作するEST-300 ICEモニタです。
target hms dev
ユーザのホストにシリアル回線で接続された日立のSH、 H8/300、 H8/500ボードです。 特別なコマンドであるdevicespeedによって、 使用されるシリアル回線と通信速度を制御します。 GDBと日立のマイクロ・プロセッサを参照してください。
target lsi dev
Mips用のLSI ROMモニタです。
target m32r dev
三菱M32R/D ROMモニタです。
target mips dev
Mips用のIDT/SIM ROMモニタです。
target mon960 dev
Intel i960用のMON960モニタです。
target nindy devicename
Nindy Monitorにより制御されるIntel 960ボードです。 devicenameは、接続に使用するシリアル装置の名前です。 例えば`/dev/ttya'です。 GDBとリモートi960(Nindy)を参照してください。
target nrom dev
NetROM ROMエミュレータです。 このターゲットは、 ダウンロードのみサポートしています。
target op50n dev
OKI HPPAボード上で動作するOP50Nモニタです。
target pmon dev
Mips用のPMON ROMモニタです。
target ppcbug dev
target ppcbug1 dev
PowerPC用のPPCBUG ROMモニタです。
target r3900 dev
東芝R3900 Mips用のDensan DVE-R3900 ROMモニタです。
target rdi dev
RDIライブラリ・インターフェイスを経由したARM Angelモニタです。
target rdp dev
ARM Demonモニタです。
target rom68k dev
M68K IDPボード上で動作するROM 68Kモニタです。
target rombug dev
OS/9000用のROMBUG ROMモニタです。
target sds dev
(MotorolaのADSなどの) PowerPCボード上で動作するSDSモニタです。
target sparclite dev
ロードするためだけの目的で使用される、 富士通のsparcliteボードです。 プログラムをデバッグするためには、 さらに別のコマンドを使用しなければなりません。 一例を挙げると、 GDBの標準的なリモート・プロトコルを使用する target remote devです。
target sh3 dev
target sh3e dev
日立SH-3、 SH-3Eターゲット・システムです。
target st2000 dev speed
Tandem STDBUGプロトコルを実行しているTandem ST2000電話交換機です。 devは、 ST2000のシリアル回線に接続されている装置の名前です。 speedは通信回線の速度です。 GDBがST2000にTCPまたはTelnetで接続するよう構成されている場合、 引数は使用されません。 GDBとTandem ST2000を参照してください。
target udi keyword
AMD UDIプロトコルを使用するRemote AMD29Kターゲットです。 引数keywordが、 使用する29Kボードまたはシミュレータを指定します。 AMD29K用のUDIプロトコルを参照してください。
target vxworks machinename
TCP/IPで接続されたVxWorksシステムです。 引数machinenameは、 ターゲット・システムのマシン名またはIPアドレスです。 GDBとVxWorksを参照してください。
target w89k dev
Winbond HPPAボード上で動作するW89Kモニタです。

GDBの構成によって、 利用可能なターゲットも異なるものになります。 構成次第で、 ターゲットの数は多くなったり少なくなったりします。 多くのリモート・ターゲットでは、 接続に成功すると、 実行プログラムのコードをダウンロードすることが必要となります。

load filename
構成によってGDBに組み込まれたリモート・デバッグ機能によっては、 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ボード (GDBと日立のマイクロ・プロセッサを参照) に対するリモート・デバッグを選択すると、 loadコマンドはユーザ・プログラムを日立ボードにダウンロードし、 (fileコマンドと同様) ユーザのホスト・マシン上のGDBのカレントなターゲット実行ファイルとしてオープンします。 loadコマンドを実行した後にRETキーを押しても、 loadコマンドは繰り返し実行されません。

ターゲットのバイト・オーダの選択

MIPS、 PowerPC、 Hitachi SHなどのプロセッサは、 ビッグ・エンディアン、 リトル・エンディアンのどちらのバイト・オーダでも実行することができます。 通常は、 実行ファイルまたはシンボルの中に、 エンディアン種別を指定するビットがあるので、 どちらを使用するかを気にする必要はありません。 しかし、 GDBの認識しているプロセッサのエンディアン種別を手作業で調整することができれば、 便利なこともあるでしょう。

set endian big
GDBに対して、 ターゲットはビッグ・エンディアンであると想定するよう指示します。
set endian little
GDBに対して、 ターゲットはリトル・エンディアンであると想定するよう指示します。
set endian auto
GDBに対して、 実行ファイルに関連付けされているバイト・オーダを使用するよう指示します。
show endian
GDBが認識している、 ターゲットの現在のバイト・オーダ種別を表示します。

これらのコマンドは、 ホスト上でのシンボリック・データの解釈を調整するだけであり、 ターゲット・システムに対しては全く何の影響も持たないということに注意してください。

リモート・デバッグ

通常の方法でGDBを実行させることのできないマシン上で実行中のプログラムをデバッグするには、 リモート・デバッグ機能を使うのが便利です。 例えば、 オペレーティング・システムのカーネルのデバッグや、 フル機能を持つデバッガを実行するのに十分な機能を持つ汎用的なオペレーティング・システムを持たない小規模なシステムでのデバッグでは、 ユーザはリモート・デバッグ機能を使うことになるかもしれません。 GDBは、 その構成によっては、 特別なシリアル・インターフェイスやTCP/IPインターフェイスを持ち、 これを特定のデバッグ・ターゲット用に使用することができます。 さらに、 GDBには汎用的なシリアル・プロトコルが組み込まれており (GDB固有のもので、 特定のターゲット・システムに固有なものではありません)、 リモート・スタブを作成すれば、 これを使用することができます。 リモート・スタブとは、 GDBと通信するためにリモート・システム上で動作するコードです。 GDBの構成によっては、 他のリモート・ターゲットが利用可能な場合もあります。 利用可能なリモート・ターゲットを一覧表示させるには、 help targetコマンドを使用します。

GDBリモート・シリアル・プロトコル

他のマシン上で実行中のプログラムをデバッグするには (ターゲット・マシンをデバッグするには)、 そのプログラムを単独で実行するために通常必要となる事前条件をすべて整える必要があります。 例えば、 Cのプログラムの場合、

  1. Cの実行環境をセットアップするためのスタートアップ・ルーチンが必要です。 これは通常`crt0'のような名前を持っています。 スタートアップ・ルーチンは、 ハードウェアの供給元から提供されることもありますし、 ユーザが自分で書かなければならないこともあります。
  2. ユーザ・プログラムからのサブルーチン呼び出しをサポートするために、 入出力の管理などを行うCのサブルーチン・ライブラリが必要になるかもしれません。
  3. ユーザ・プログラムを他のマシンに持っていく手段、 例えばダウンロード・プログラムが必要です。 これはハードウェアの供給元から提供されることが多いのですが、 ハードウェアのドキュメントをもとにユーザが自分で作成しなければならないこともあります。

次に、ユーザ・プログラムがシリアル・ポートを使って、GDBを実行中のマシン (ホスト・マシン) と通信できるように準備します。 一般的には、以下のような形になります。

ホスト上では:
GDBは既にこのプロトコルの使い方を理解しています。 他の設定がすべて終了した後、 単に`target remote'コマンドを使用するだけです (デバッグ・ターゲットの指定を参照)。
ターゲット上では:
ユーザ・プログラムに、 GDBリモート・シリアル・プロトコルを実装した特別なサブルーチンを いくつかリンクする必要があります。 これらのサブルーチンを含むファイルは、 デバッグ・スタブと呼ばれます。 特定のリモート・ターゲットでは、 ユーザ・プログラムにスタブをリンクする代わりに、 gdbserverという補助プログラムを使うこともできます。 詳細については、 gdbserverプログラムの使用を参照してください。

デバッグ・スタブはリモート・マシンのアーキテクチャに固有のものです。 例えば、 SPARCボード上のプログラムをデバッグするには`sparc-stub.c'を使います。 以下に実際に使えるスタブを列挙します。 これらは、 GDBとともに配布されています。

i386-stub.c
Intel 386アーキテクチャ、 およびその互換アーキテクチャ用です。
m68k-stub.c
Motorola 680x0アーキテクチャ用です。
sh-stub.c
日立SHアーキテクチャ用です。
sparc-stub.c
SPARCアーキテクチャ用です。
sparcl-stub.c
富士通SPARCLITEアーキテクチャ用です。

GDBとともに配布されるREADMEファイルには、 新しく追加された他のスタブのことが記されているかもしれません。

スタブの提供する機能

各アーキテクチャ用のデバッグ・スタブは、 3つのサブルーチンを提供します。

set_debug_traps
このルーチンは、 ユーザ・プログラムが停止したときにhandle_exceptionが実行されるよう設定します。 ユーザ・プログラムは、 その先頭付近でこのサブルーチンを明示的に呼び出さなければなりません。
handle_exception
これが中心的な仕事をする部分ですが、 ユーザ・プログラムはこれを明示的には呼び出しません。 セットアップ・コードによって、 トラップが発生したときに handle_exceptionが実行されるよう設定されます。 ユーザ・プログラムが実行中に (例えば、ブレイクポイントで) 停止すると、 handle_exceptionが制御権を獲得し、 ホスト・マシン上のGDBとの通信を行います。 これが、 通信プロトコルが実装されている部分です。 handle_exceptionは、 ターゲット・マシン上でGDBの代理として機能します。 それはまず、 ユーザ・プログラムの状態に関する情報を要約して送ることから始めます。 次に、 GDBが必要とする情報を入手して転送する処理を継続します。 これは、 ユーザ・プログラムの実行を再開させるようなGDBコマンドが実行されるまで続きます。 そのようなコマンドが実行されると、 handle_exceptionは、 制御をターゲット・マシン上のユーザ・コードに戻します。
breakpoint
ユーザ・プログラムにブレイクポイントを持たせるには、 この補助的なサブルーチンを使います。 特定の状況においては、 これがGDBが制御を獲得する唯一の方法です。 例えば、 ユーザのターゲット・マシンに割り込みを発生させるボタンのようなものがあれば、 このサブルーチンを呼び出す必要はありません。 割り込みボタンを押すことで、 制御はhandle_exceptionに、 つまり事実上GDBに渡されます。 マシンによっては、 シリアル・ポートから文字を受け取るだけでトラップが発生することもあります。 このような場合には、 ユーザ・プログラム自身からbreakpointを呼び出す必要はなく、 ホストのGDBセッションから`target remote'を実行するだけで制御を得ることができます。 これらのどのケースにも該当しない場合、 あるいは、 デバッグ・セッションの開始箇所としてあらかじめ決めてあるところでユーザ・プログラムが停止することを 単に確実にしたいのであれば、 breakpointを呼び出してください。

スタブに対する必須作業

GDBとともに配布されるデバッグ用スタブは、 特定のチップのアーキテクチャ用にセットアップされたものですが、 デバッグのターゲット・マシンに関してそれ以外の情報は持っていません。 まず最初に、 どのようにしてシリアル・ポートと通信するかをスタブに教えてやる必要があります。

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)
例外処理テーブルにexception_addressを組み込むよう、 この関数を書きます。 ユーザがこれを提供しなければならないのは、 スタブにはターゲット・システム上の例外処理テーブルがどのようなものになるかを知る手段がないからです (例えば、 プロセッサのテーブルはROM上にあり、 その中のエントリがRAM上のテーブルを指す、 という形になっているかもしれません)。 exception_number は例外番号で、 これは変更される必要があります。 例外番号の意味は、 アーキテクチャに依存します (例えば、 0による除算、 境界を無視したメモリ・アクセス等は、 異なる番号によって表わされるかもしれません)。 この例外が発生したとき、 制御は直接exception_addressに渡されなければならず、 また、 プロセッサの状態 (スタック、レジスタなど) はプロセッサ例外が発生したときの状態と同じでなければなりません。 したがって、 exception_addressに到達するのにジャンプ命令を使用したいのであれば、 サブルーチン・ジャンプではなく、 ただのジャンプ命令を使わなければなりません。 386では、 ハンドラが実行されているときに割り込みがマスクされるよう、 exception_addressは割り込みゲートとして組み込まれる必要があります。 そのゲートは特権レベル0 (最も高いレベル) でなければなりません。 SPARC用のスタブや68k用のスタブは、 exceptionHandlerの助けを借りなくても自分で割り込みをマスクすることができます。
void flush_i_cache()
(sparc、 sparcliteのみ) ターゲット・マシンに命令キャッシュがある場合、 それをフラッシュするようこのサブルーチンを書きます。 命令キャッシュがない場合には、 このサブルーチンは何もしないものになるかもしれません。 命令キャッシュを持つターゲット・マシン上のGDBは、 ユーザ・プログラムが安定した状態にあることが この関数によって保証されることを必要とします。

また、次のライブラリ・ルーチンが使用可能であることを確かめなければなりません。

void *memset(void *, int, int)
あるメモリ領域に既知の値を設定する標準ライブラリ関数memsetです。 フリーのlibc.aを持っていれば、 そこにmemsetがあります。 フリーのlibc.aがなければ、 memsetをハードウェアの供給元から入手するか、 自分で作成する必要があります。

GNU Cコンパイラを使っていないのであれば、 他の標準ライブラリ・サブルーチンも必要になるかもしれません。 これは、 スタブによっても異なりますが、 一般的にスタブは、 gccがインライン・コードとして生成する共通ライブラリ・サブルーチンを使用する可能性があります。

ここまでのまとめ

要約すると、 ユーザ・プログラムをデバッグする準備が整った後、 以下の手順に従わなければなりません。

  1. 下位レベルのサポート・ルーチンがあることを確認します (スタブに対する必須作業を参照)。
    getDebugChar, putDebugChar,
    flush_i_cache, memset, exceptionHandler.
    
  2. ユーザ・プログラムの先頭付近に以下の行を挿入します。
    set_debug_traps();
    breakpoint();
    
  3. 680x0のスタブに限り、 exceptionHookという変数を提供する必要があります。 通常は、 以下のように使います。
    void (*exceptionHook)() = 0;
    
    しかし、 set_debug_trapsが呼び出される前に、 ユーザ・プログラム内のある関数を指すようこの変数を設定すると、 トラップ (例えば、 バス・エラー) で停止した後にGDBが処理を継続実行するときに、 その関数が呼び出されます。 exceptionHookによって指される関数は、 1つの引数付きで呼び出されます。 それは、 int型の例外番号です。
  4. ユーザ・プログラム、 ターゲット・アーキテクチャ用のGDBデバッグ・スタブ、 サポート・サブルーチンをコンパイルしリンクします。
  5. ターゲット・マシンとGDBホストとの間がシリアル接続されていることを確認します。 また、 ホスト上のシリアル・ポートの名前を調べます。
  6. ターゲット・マシンにユーザ・プログラムをダウンロードし (あるいは、 製造元の提供する手段によってターゲット・マシンにユーザ・プログラムを持っていき)、 起動します。
  7. リモート・デバッグを開始するには、 ホスト・マシン上でGDBを実行し、 リモート・マシン上で実行中のプログラムを実行ファイルとして指定します。 これにより、 ユーザ・プログラムのシンボルとテキスト域の内容を見つける方法がGDBに通知されます。 次に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は再び待ち状態になります。

通信プロトコル

GDBとともに提供されるスタブ・ファイルは、 ターゲット側の通信プロトコルを実装します。 そしてGDB側の通信プロトコルは、 GDBのソース・ファイル`remote.c'に実装されています。 通常は、 これらのサブルーチンに通信処理を任せて、 詳細を無視することができます (独自のスタブ・ファイルを作成するときでも、 詳細については無視して、 既存のスタブ・ファイルをもとにして作成を始めることができます。 `sparc-stub.c'が最もよく整理されており、 したがって最も読みやすくなっています)。 しかし、 場合によっては、 プロトコルについて何かを知る必要が出てくることもあるでしょう。 例えば、 ターゲット・マシンにシリアル・ポートが1つしかなく、 GDBに対して送られてきたパケットを検出したときに、 ユーザ・プログラムが何か特別なことをするようにしたい場合です。 (単一文字による確認メッセージを除く) すべてのGDBコマンドとそれに対する応答は、 チェックサムを含むパケットとして送信されます。 パケットは、 文字`$'で始まり、 文字`#'に2桁のチェックサム値が続いて終わります。

$packet info#checksum

ここで、 checksumpacket infoのすべての文字の値を合計したものを256で割った余りとして計算されます。 ホスト・マシンまたはターゲット・マシンがパケットを受信したとき、 最初に期待される応答は確認メッセージです。 これは単一文字で、 (パッケージが正しく受信されたことを示す) `+'または (再送要求を示す) `-'です。 ホスト (GDB) がコマンドを送信し、 ターゲット (ユーザ・プログラムに組み込まれたデバッグ・スタブ) が応答としてデータを送信します。 ターゲットは、ユーザ・プログラムが停止したときにも、 データを送信します。 コマンド・パケットは最初の文字で区別されます。 最初の文字がコマンドの種類を表わします。 以下に、 現在サポートされているコマンドをいくつか列挙します (コマンドの完全なリストについては`gdb/remote.c'を参照してください)。

g
CPUレジスタの値を要求します。
G
CPUレジスタの値を設定します。
maddr,count
addrで示される位置からcountで示されるバイト数を読み込みます。
Maddr,count:...
addrで示される位置からcountで示されるバイト数を書き込みます。
c
caddr
カレントなアドレス (addrが指定されているのであれば、 それによって指定されるアドレスから) 実行を再開します。
s
saddr
プログラム・カウンタの指すカレントな箇所から (addrが指定されているのであれば、 それによって指定されるアドレスから) ターゲット・プログラムを1命令だけステップ実行します。
k
ターゲット・プログラムを終了させます。
?
最後に受信したシグナルを報告します。 GDBのシグナル処理コマンドを利用できるように、 デバッグ・スタブの中のある関数が、 CPUトラップを対応するPOSIXシグナル値として報告してきます。
T
リモートのスタブに対して、 GDBがシングル・ステップ処理や条件付きブレイクポイントに関する迅速な決定を下すのに必要となる レジスタの情報だけを送信するようにさせます。 これによって、 ステップ実行中の1命令ごとにすべてのレジスタの情報を入手する必要がなくなります。 現在の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リモート・シリアル・プロトコルによって通信します。

ターゲット・マシンでは:
デバッグしたいプログラムのコピーが1つ必要です。 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ポートでなければ、 任意の番号をポート番号として選択できます (例えば、 23telnetに予約されています) (3)。 ここで指定したのと同じポート番号を、 ホスト上のGDBのtarget remoteコマンドで使わなければなりません。
GDBのホスト・マシンでは:
GDBはシンボル情報、 デバッグ情報を必要とするので、 ストリップされていないユーザ・プログラムのコピーが必要です。 通常どおり、 第1引数にユーザ・プログラムのローカル・コピーの名前を指定してGDBを起動します (シリアル回線の速度が9600 bps以外であれば、 `--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リモート・シリアル・プロトコルを使って、 シリアル回線経由で通信します。

ターゲット・マシンでは:
デバッグしたいプログラムのコピーが1つ必要です。 gdbserve.nlmはユーザ・プログラムのシンボル・テーブルを必要とはしませんので、 スペースの節約が必要であれば、 プログラムをストリップすることができます。 ホスト・システム上のGDBが、 シンボルに関わるすべての処理を実行します。 gdbserve.nlmを使うには、 GDBとの通信方法、 ユーザ・プログラムの名前、 ユーザ・プログラムの引数を教えてやる必要があります。 構文は、 以下のとおりです。
load gdbserve [ BOARD=board ] [ PORT=port ]
              [ BAUD=baud ] program [ args ... ]
boardportがシリアル回線を指定します。 baudは接続に使われるボーレートを指定します。 portnodeのデフォルト値は0、 baudのデフォルト値は9600 bpsです。 例えば、 `foo.txt'という引数を指定してEmacsをデバッグし、 シリアル・ポート番号2、 ボード1を経由して19200 bpsの接続でGDBと通信するには、 以下のように実行します。
load gdbserve BOARD=1 PORT=2 BAUD=19200 emacs foo.txt
GDBのホスト・マシンでは:
GDBはシンボル情報、 デバッグ情報を必要とするので、 ストリップされていないユーザ・プログラムのコピーが必要です。 通常どおり、 第1引数にユーザ・プログラムのローカル・コピーの名前を指定してGDBを起動します (シリアル回線の速度が9600 bps以外であれば、 `--baud'オプションも必要になります)。 その後、 target remoteコマンドによって gdbserve.nlmとの通信を確立します。 引数には、 装置名 (通常は`/dev/ttyb'のようなシリアル装置) を指定します。 例えば、
(gdb) target remote /dev/ttyb
は、 シリアル回線`/dev/ttyb'を経由してgdbserve.nlmと通信します。

GDBとリモートi960(Nindy)

Nindyは、 Intel 960ターゲット・システム用のROM Monitorプログラムです。 Nindyを使ってリモートのIntel 960を制御するようGDBが構成されている場合、 いくつかの方法によってGDBに960との接続方法を教えることができます。

Nindy使用時の起動方法

コマンドライン・オプションを一切使わずにgdbを起動すると、 通常のGDBプロンプトが表示されるに、 使用するシリアル・ポートを指定するよう促されます。

Attach /dev/ttyNN -- specify NN, or "quit" to quit:  

このプロンプトに対して、 使いたいシリアル・ポートを示す (`/dev/tty'の後ろの) サフィックスを入力します。 もしそうしたいのであれば、 プロンプトに空行で答えることによって、 Nindyとの接続を確立せずに起動することもできます。 この場合、 後にNindyと接続したいときにはtargetコマンドを使います (ターゲットを管理するコマンドを参照)。

Nindy用のオプション

接続されたNindy-960ボードとのGDBセッションを開始するための 起動オプションを以下に示します。

-r port
ターゲット・システムとの接続に使用されるシリアル・インターフェイスのシリアル・ポート名を指定します。 このオプションは、 GDBがIntel 960ターゲット・アーキテクチャ用に構成されているときのみ利用可能です。 portは、 完全なパス名 (例:`-r /dev/ttya')、 `/dev'配下のデバイス名 (例:`-r ttya')、 tty固有の一意なサフィックス (例:`-r a') のいずれによっても指定することができます。
-O
(ゼロではなく、 英大文字のOです)。 GDBがターゲット・システムと接続する際に、 古いNindyモニタ・プロトコルを使用すべきであることを指定します。 このオプションは、 GDBがIntel 960ターゲット・アーキテクチャ用に構成されているときのみ利用可能です。

注意`-O'を指定したにもかかわらず、 実際にはより新しいプロトコルを期待しているターゲット・システムに接続しようとした場合、 接続は失敗します。 この失敗は、 あたかも通信速度の不一致が原因であるかのように見えてしまいます。 GDBは、 異なる回線速度によって再接続を繰り返し試みます。 割り込みによって、 この処理を中断させることができます。

-brk
接続する前にNindyターゲットをリセットするために、 ターゲット・システムに対して最初にBREAK信号を送信するよう、 GDBに対して指定します。

注意:多くのターゲット・システムは、 このオプションが必要とするハードウェアを備えていません。 このオプションは、 少数のボードでしか機能しません。

標準の`-b'オプションが、 シリアル・ポート上で使用される回線速度を制御します。

Nindy resetコマンド

reset
ターゲットがNindyである場合、 このコマンドはBREAK信号をリモートのターゲット・システムに送信します。 これは、 BREAK信号を受信したときにハード・リセット (または、 その他の興味深いアクション) を実行する回路がターゲットに備わっている場合にのみ役に立ちます。

AMD29K用のUDIプロトコル

GDBは、 a29kプロセッサ・ファミリをデバッグするためのAMD UDI (Universal Debugger Interface) プロトコルをサポートしています。 MiniMONモニタを実行するAMDターゲットという構成を使うには、 AMD社から無料で入手可能なMONTIPプログラムが必要になります。 また、 AMD社から入手可能なUDI準拠のa29kシミュレータ・プログラムISSTIPとともにGDBを使うこともできます。

target udi keyword
リモートのa29kボードまたはシミュレータへのUDIインターフェイスを選択します。 keywordは、 AMD構成ファイル`udi_soc'内のエントリです。 このファイルには、 a29kターゲットに接続するときに使われるパラメータを指定する キーワード・エントリが含まれます。 `udi_soc'ファイルが作業ディレクトリにない場合には、 環境変数`UDICONF'にそのパス名を設定しなければなりません。

AMD29KのEBMONプロトコル

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と通信するのにtipcuのような通信プログラムを使います。 以下に例を示します。

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プログラムをダウンロードすることはしません

EB29Kクロス・デバッグ

最後に、 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側での予期せぬイベントを理解する助けになることがよくあります。

GDBとTandem ST2000

ST2000をホスト・システムに接続する方法については、 製造元のマニュアルを参照してください。 ST2000が物理的に接続されれば、 それをデバッグ環境として確立するには、以下を実行します。

target st2000 dev speed

devは通常、 シリアル回線によってST2000と接続される`/dev/ttya'のようなシリアル装置の名前です。 代わりに、 hostname:portnumberという構文を使って (例えば、端末多重化装置経由で接続されたシリアル回線への) TCP接続としてdevを指定することもできます。 このターゲットに対して、 loadコマンドとattachコマンドは定義されていません。 通常スタンドアロンで操作している場合と同様、 ST2000にユーザ・プログラムをロードしなければなりません。 GDBは (シンボルのような) デバッグ用の情報を、 ホスト・コンピュータ上にある別のデバッグ・バージョンのプログラムから読みとります。 ST2000での作業を支援するために、 以下の補助的なGDBコマンドが利用可能です。

st2000 command
STDBUGモニタにcommandを送信します。 利用できるコマンドについては、 製造元のマニュアルを参照してください。
connect
STDBUGコマンド・モニタに対して制御端末を接続します。 STDBUGの操作が終了した後、 RET~. (Returnキーに続いて、チルダとピリオドを入力)、 または、 RET~C-d (Returnキーに続いて、チルダとControl-Dを入力) のいずれかを入力することによってGDBコマンド・プロンプトに戻ります。

GDBとVxWorks

開発者は、 GDBを使用することによって、 ネットワークに接続されたVxWorks端末上のタスクを、 UNIXのホストから起動してデバッグすることができます。 VxWorksシェルから起動され、 既に実行中の状態のタスクをデバッグすることもできます。 GDBは、 UNIXホスト上で実行されるコードとVxWorksターゲット上で実行されるコードの両方を使います。 gdbは、 UNIXホスト上にインストールされて実行されます (ホスト上のプログラムをデバッグするのに使うGDBと区別するために、 vxgdbという名前でインストールされることもあります)。

VxWorks-timeout args
すべてのVxWorksベースのターゲットが、 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)

VxWorksへの接続

GDBのtargetコマンドによって、 ネットワーク上のVxWorksターゲットに接続します。 ttというホスト名を持つターゲットに接続するには、 以下のようにします。

(vxgdb) target vxworks tt

GDBは以下のようなメッセージを表示します。

Attaching remote machine across net... 
Connected to tt.

続いてGDBは、 最後にVxWorksターゲットが起動されたときより後にロードされた オブジェクト・モジュールのシンボル・テーブルを読み込もうと試みます。 GDBは、 コマンドのサーチ・パスに含まれているディレクトリを探索することによって、 これらのファイルを見つけます (ユーザ・プログラムの環境を参照)。 オブジェクト・ファイルを見つけることができない場合には、 以下のようなメッセージを表示します。

prog.o: No such file or directory.

このような場合には、 GDBのpathコマンドによって適切なディレクトリを検索パスに加えてから、 再度targetコマンドを実行します。

VxWorksダウンロード

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.o

GDBは次のような応答を表示します。

Reading symbol data from wherever/vw/demo/rdb/prog.o... done.

ソース・ファイルを編集して再コンパイルした後に、 loadコマンドを使ってオブジェクト・モジュールを再ロードすることもできます。 ただし、 これを行うと、 GDBはその時点で定義されているすべてのブレイクポイント、 自動表示設定、 コンビニエンス変数を削除し、 値ヒストリを初期化してしまいますので、 注意してください (これは、 ターゲット・システムのシンボル・テーブルを参照するデバッガのデータ構造の完全性を保つために必要です)。

タスクの実行

以下のようにattachコマンドを使うことで、 既存のタスクにアタッチすることも可能です。

(vxgdb) attach task

taskは、 VxWorksの16進数のタスクIDです。 アタッチするときに、 タスクは実行中であってもサスペンドされていても構いません。 実行中であったタスクは、 アタッチされたときにサスペンドされます。

GDB と Sparclet

開発者は、 GDBを使うことによって、 Sparcletターゲット上で実行中のタスクをUnixホストからデバッグできるようになります。 GDBは、 Unixホスト上で実行されるコードとSparcletターゲット上で実行されるコードの両方を使用します。 gdbは、 Unixホスト上にインストールされて実行されます。

timeout args
GDBはオプションremotetimeoutをサポートするようになりました。 このオプションはユーザによって設定されるもので、 argsはGDBが応答を待つ秒数を表わします。

デバッグ用にコンパイルする際には、 デバッグ情報を得るために"-g"オプションを、 また、 ターゲット上でロードしたい位置にプログラムを再配置するために"-Ttext"オプションを指定します。 各セクションのサイズを小さくするために、 "-n"または"-N"オプションを加えるのも良いでしょう。

sparclet-aout-gcc prog.c -Ttext 0x12010000 -g -o prog -N

アドレスが意図したものと一致しているかどうかを検証するのに、 objdumpを使うことができます。

sparclet-aout-objdump --headers --syms prog

GDBが見つかるようにUnixの実行サーチ・パスを設定すれば、 GDBを実行するための準備は完了です。 Unixホストからgdb (インストールの方法によっては、 sparclet-aout-gdb) を実行します。 GDBが起動されて、 以下のプロンプトを表示します。

(gdbslet)

デバッグするファイルの選択

GDBのfileコマンドによって、 デバッグするプログラムを選択することができます。

(gdbslet) file prog

このコマンドを実行すると、 GDBは`prog'のシンボル・テーブルを読み込もうとします。 GDBは、 コマンド・サーチ・パスに含まれるディレクトリを探索することによって、 そのファイルを見つけます。 そのファイルがデバッグ情報付き (オプション"-g") でコンパイルされた場合は、 ソース・ファイルも探します。 GDBは、 ディレクトリ・サーチ・パス (ユーザ・プログラムの環境を参照) に含まれるディレクトリを探索することによって、 そのソース・ファイルを見つけます。 ファイルが見つからない場合には、 次のようなメッセージを表示します。

prog: No such file or directory.

このメッセージが表示された場合には、 GDBのpathコマンドとdirコマンドを使って適切なディレクトリをサーチ・パスに加えてから、 targetコマンドを再実行します。

Sparcletへの接続

GDBのtargetコマンドによってSparcletターゲットに接続することができます。 シリアル・ポート"ttya"でターゲットに接続するには、 以下のように入力します。

(gdbslet) target sparclet /dev/ttya
Remote target sparclet connected to /dev/ttya
main () at ../prog.c:3 

GDBは以下のようなメッセージを表示します。

Connected to ttya.

Sparcletダウンロード

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の実行制御コマンドであるbsteprunなどを使ってタスクのデバッグを開始することができます。 コマンドの一覧については、 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)                           

GDBと日立のマイクロ・プロセッサ

日立のSH、 H8/300、 H8/500と通信するためには、 GDBは以下の情報を知っている必要があります。

  1. ユーザは、 日立マイクロ・プロセッサへのリモート・デバッグ用インターフェイスである`target hms'と、 日立SHや日立300Hのインサーキット・エミュレータであるtarget`e7000'のどちらを使用したいかということ (GDBが日立SH、 H8/300、 H8/500用に特に構成されている場合には、 `target hms'がデフォルトです)。
  2. ホストと日立ボードを接続しているシリアル装置 (デフォルトは、 ホスト上で利用できる最初のシリアル装置です)
  3. シリアル装置で使用する速度

日立ボードへの接続

シリアル装置を明示的に指定する必要があれば、 そのための専用コマンドである、 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インサーキット・エミュレータの使用

E7000インサーキット・エミュレータを使って、 日立SHまたはH8/300H用のコードを開発することができます。 `target e7000'コマンドを以下のいずれかの形式で使って、 GDBをE7000に接続します。

target e7000 port speed
E7000がシリアル・ポートに接続されている場合は、 この形式を使ってください。 引数portが、 使用するシリアル・ポートを指定します (例えば、 `com2')。 3番目の引数は、 秒あたりのビット数による回線速度です (例えば、 `9600')。
target e7000 hostname
E7000がTCP/IPネットワーク上のホストとしてインストールされている場合、 ホスト名だけを指定することもできます。 GDBは接続にtelnetを使います。

日立マイクロ・プロセッサ用の特別なGDBコマンド

いくつかの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に指定可能な値は、 smallbigmediumcompactのいずれかです。

GDBとリモートMIPSボード

GDBは、 MIPSのリモート・デバッグ用のプロトコルを使って、 シリアル回線に接続されたMIPSボードと通信することができます。 これは、 GDBを`--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
GDBのホスト構成によっては、 `hostname:portnumber'という構文を使うことで、 シリアル・ポートの代わりに (例えば、 端末多重化装置によって管理されているシリアル回線への) TCP接続を指定することができます。
target pmon port
target ddb port
target lsi port

GDBは、 MIPSターゲットに対して、 以下の特別なコマンドもサポートしています。

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
MIPS浮動小数点コプロセッサをサポートしないターゲット・ボードを使う場合は、 `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
MIPSリモート・プロトコルにおけるパケット待ちの状態でのタイムアウト時間を、 set timeout secondsコマンドで制御することができます。 デフォルトは5秒です。 同様に、 パケットに対する確認 (ACK) を待っている状態でのタイムアウト時間を、 set retransmit-timeout secondsコマンドで制御することができます。 デフォルトは3秒です。 それぞれの値をshow timeoutshow retransmit-timeoutで調べることができます (どちらのコマンドも、 GDBが`--target=mips-idt-ecoff'用に構成されている場合のみ使用可能です)。 set timeoutで設定されたタイムアウト時間は、 ユーザ・プログラムが停止するのをGDBが待っている間は適用されません。 この場合には、 GDBは永遠に待ち続けます。 これは、 停止するまでにプログラムがどの程度長く実行を継続するのかを知る方法がないからです。

シミュレートされたCPUターゲット

構成によっては、 ユーザ・プログラムをデバッグする際にハードウェア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上でプログラムをデバッグします。 シミュレータがセットアップ・オプションをサポートしている場合は、 それをargsの部分に指定します。

このターゲットを指定した後には、 ホスト・コンピュータ上のプログラムをデバッグするのと同様の方法で、 シミュレートされたCPU用のプログラムをデバッグすることができます。 新しいプログラムのイメージをロードするには fileコマンドを使い、 ユーザ・プログラムを実行するにはrunコマンドを使う、 という具合です。 Z8000シミュレータでは、 通常のマシン・レジスタ (info reg を参照) がすべて利用可能であるだけでなく、 特別な名前を持つレジスタとして、 3つの追加情報が提供されています。

cycles
シミュレータ内のクロック・ティックをカウントします。
insts
シミュレータ内で実行された命令をカウントします。
time
1/60秒を単位とする実行時間を示します。

これらの変数は、 GDBの式の中で普通に参照することができます。 例えば、 `b fputc if $cycles>5000'は、 シミュレートされたクロック・ティックが最低5,000回発生した後に停止するような、 条件付きブレイクポイントを設定します。


[Contents]   [Back]   [Prev]   [Up]   [Next]   [Forward]