[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Documentation/kernel/kgdb.list



こんばんは。

Documentation/kernel/kgdb.list を翻訳してみました。

-- やまの

<html>
<head>
<!-- Copyright (c) 2000
        The NetBSD Foundation, Inc.  ALL RIGHTS RESERVED. -->
<link rev="made" href="mailto:www@JP.NetBSD.ORG">
<title>How to Debug the NetBSD kernel with GDB</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">

<HEADING> GDB を使い NetBSD カーネルをデバッグする方法

<LIST>

<SECTION>KGDB の使用方法

<ENTRY>introduction 概要

NetBSD カーネルに含まれている DDB デバッガーは、クラッシュ・トレースバック
を入手したり、変数の値の検査、その他のこまかいデバッグのために、役に立ちま
す。しかしながら、もし、真剣にカーネルをハックしているのであれば、DDB のか
わりに、リモートデバッガー KGDB が動作するように設定したいと思うでしょう。
<p>

DDB に対する KGDB の利点は、ディスアセンブルされたマシンコードでなく
カーネルの *ソースコード* を見ることができることです。実際のところ、
ほとんどすべての GDB の機能が使用可能で、gdb のいくつかのグラフィカル
インターフェースを使うこともできます(例えば <PKGSRC>devel/ddd など)。

<ENTRY>prerequisites 事前に準備しておくこと

* 同一アーキテクチャーで NetBSD の動作しているマシン二台(オブジェクトコード
のフォーマットも同一であること)<p><p>

<PRE>
    TARGET - デバッグするカーネルを実行するマシン
    REMOTE - gdb を実行、表示するマシン
</PRE>

あるアーキテクチャーのホストで、他のアーキテクチャーのターゲット用の gdb 
を構築することも可能です。しかし、これについてはここではふれません。きっと
誰かが書いてくれることでしょう。<p><p>

* 空きのシリアルポートが両方のマシンに存在すること<p>
* null モデムケーブル<p>
* カーネルの構築とインストール、そして gdb の使用法についての知識<p>

<ENTRY>instructions 手順

(以下の文中では、REMOTE マシン上(gdb が動作している)で tty01 を、TARGET 
マシン(デバッグされる)では tty00 を使用していると仮定して説明します。
これで、以下の手順の中で、どのシリアルポートについてのべているのか混乱する
ことはないでしょう。<p><p>


1) KGDB を有効にしたカーネルの構築<p><p>

(注意: 私は、これがリモートマシン上でカーネルを構築する最良の方法だと
思います。これで、デバッグする時には、すべての必要なソースファイルと
シンボルファイルはすでに準備されています。)<p><p>

1.1) TARGET マシンのためにカーネルのコンフィグファイル内の以下の行を
コメントアウトしてください。<p><p>

<PRE>
  #options 	DDB		# in-kernel debugger
  #options 	DDB_HISTORY_SIZE=100	# enable history editing 
</PRE>

以下の三行をアンコメントアウト(あるいは追加)してください。<p><p>

<PRE>
  options 	KGDB		# remote debugger
  options 	"KGDB_DEVNAME=\"com\"",KGDBADDR=0x3f8,KGDBRATE=9600
  makeoptions	DEBUG="-g"	# compile full symbol table
</PRE>

TARGET マシン上で使用するシリアルポートの IO アドレス(0x3f8 は tty00、
0x2f8 は tty01 用です)に一致するように、KGDBADDR を変更してください。
それから、KGDBRATEを、使用するビットレートに一致させてください。<p><p>

1.2) TARGET マシンのカーネルの設定と構築をおこなってください。
<ここに "How to build a kernel" へのリンクを挿入する><p><p>

2) TARGET マシンの準備。- ファイル「netbsd」を、カーネルを構築したディレクトリ
から TARGET マシンのルートディレクトリにコピーしてください。このカーネルを
リモートマシンにインストールしてはいけません。(特に、両方のマシンで同じ tty 
を使っている時には注意してください!)<p><p>

3) REMOTE マシンの準備<p><p>

3.1) TARGET マシンでカーネルを構築したのであれば、/usr/src/sys すべてを、
REMOTE マシンにコピーしてください。(*注意: TARGET マシンのディレクトリ
を 単に NFS マウントしてはいけません。gdb がブレークポイントで停止した
時に、TARGET マシン上の nfsd を含むすべてのプロセスは停止します。)<p><p>

3.2) REMOTE マシン上で使う予定の(そして REMORE マシンでだけ使う) tty の
ために /etc/ttys を変更してください。例えば以下のように。<p><p>

<PRE>
   tty01 "/usr/libexec/getty std.9600" unknown off local
</PRE>

ここで重要なのは、「off」(これで、init がこのポートで getty を起動する
ことはありません)と「local」です。ttyflags は、/etc/ttys に従ってブート
時にポートのデフォルトを設定します。そして、gdb を使うには、DTR を待た
ないようにするために「local」が設定されていなければなりません
(*注意: 「local」の設定は、1999 年 12 月 21 日以降の NetBSD-current、
そして、NetBSD 1.5 リリース後には必要ありません。詳細は PR6547 を参照して
ください。)<p><p>

「std.9600」を別のビットレートに変更したい場合もあるかもしれません。この
場合、ビットレートは、gdb で設定する remotebaudrate (後で説明します)と
同様に、TARGET 用のカーネルオプションで設定したレートと一致していなけ
ればなりません。/etc/gettytab の中に、あなたが使う名前と一致するエントリー
があることを確認してください。<p><p>

3.3) REMOTE マシンをリブートするか、ttyflags を起動し /etc/ttys を再
読み込みさせてください。(「kill -1 1」で十分かもしれません。しかし、
/etc/ttys の項目の順番を変更したことにより、init が混乱したのを見た
経験があります。)<p><p>

4) null モデムケーブルを使い、シリアルポートに接続してください。<p><p>

5) TARGET マシンをリブートし、ブートローダーのメッセージが表示されたら
すぐに、スペースキーを押してください。そして、次のコマンドを入力して
ください。<p><p>

<PRE>
	boot -d
</PRE>

これによりカーネルがロードされます。「waiting for kgdb」というメッセージ
が表示された後、TARGET は停止します。<p><p>

6) REMOTE マシン側で、カーネルを構築したディレクトリ
(一般的には /usr/src/sys/arch/<something>/compile/<config-name>) 
に移動し、gdb を起動します。

<PRE>
	gdb netbsd.gdb
</PRE>

数秒後、(gdb) プロンプトが表示されるはずです。

7) gdb のいくつかのフラグを設定する<p><p>

<PRE>
	# いつでも Ctrl-C により TARGET を停止させることができるようにする。
	(gdb) set remotebreak 1
	# gdb の使用するボーレートを設定する。(デフォルトは 9600、
	# TARGET にインストールされたカーネルの設定と一致していること)
	(gdb) set remotebaud 9600
	# シリアル上でラインエラーが発生した場合の再送速度を速くする。
	(gdb) set remotetimeout 3
</PRE>

8) REMOTE マシンに接続します(REMOTEマシン側で tty00 を使用していると
仮定しています)<p><p>

<PRE>
	target remote /dev/tty00
</PRE>

以下のようなメッセージが表示されます。<p><p>

<PRE>
	Remote debugging using /dev/tty01
	kgdb_connect (verbose=1) at 	../../../../arch/i386/i386/kgdb_machdep.c:244
	244             if (verbose)
	(gdb)
</PRE>

もし、これらのメッセージが表示されるかわりに、GDB が 「hang」しているよう
なら、シリアルハードウェア、ケーブル、あるいは設定に何か間違いがあります。
トラブルシューティングのセクションを参照してください。<p><p>

9) さて、プロンプトが表示されれば、ハックする準備はできています。
ブレークポイントを設定したり、データを確認したり、一ステップ毎に実行する
ことができます。ちょうど、ローカルマシン上で動作しているユーザーレベル
アプリケーションを gdb でデバッグするのと同じです。カーネルのブートプロ
セスを続行させるには、「cont」を使ってください。後でデバッガーにもどるため
には、Ctrl-C を押してください。<p><p>

10) 5 から 7 の手順を自動化するためには、カーネルを構築するディレクトリに
以下の内容のファイル .gdbinit を作成してください。<p><p>

<PRE>
      file netbsd.gdb
      set remotebreak 1
      set remotebuad 9600
      target remote /dev/tty00
</PRE>

さて、これで「gdb」とタイプするだけで、デバッグを始めることができます。<p><p>

<ENTRY>troubleshooting トラブルシューティング

もし、うまく動作しない場合は、以下の事を試してみてください。<p><p>

1) -d を指定せずに TARGET マシンをリブートしてください。デバイスの
プローブ時に以下のようなメッセージが表示されるはずです。二行目が表示
されていなければ、構築したカーネルでは KGDB が有効になっていないか、
間違ったカーネルを使用しています。

<PRE>
	com0 at isa0 port 0x3f8-0x3ff irq4: ns16550a, working fifo
	com0: kgdb
</PRE>

2) シリアルポートとケーブルが「通常」のアプリケーションで動作すること
を確認してください。KGDB を無効にしたカーネルで TARGET マシンをリブート
し、二つのマシン間で「tip 」を実行してみてください。もし、tip について
知らないのであれば、以下の簡単な手順を参考にしてください。<p><p>

* 以下の行を、TARGET と REMOTE 両マシンの /etc/remote に追加してください。

<PRE>
	tty00-9600:dv=/dev/tty00:br#9600:pa=none:dc:
	tty01-9600:dv=/dev/tty01:br#9600:pa=none:dc:
</PRE>

* TARGET マシン上で「tip tty00-9600」を、REMOTE マシン上で「tip tty01-9600」
を実行してください。<p><p>

* 両方のマシンのキーボードで適当な文字を入力してください。文字は
他のマシンのディスプレイに表示されるはずです。

3) /etc/ttys の中の、自分が使っている tty の行を再度確認し、それが有効
かどうかを確認するためにリブートしてください。<p><p>

4) 今まで書いてた文章の中では、root で作業している事を仮定していました。
一般ユーザーの場合、tip と gdb は動作しません。(/dev/tty0* のパーミッション
に依存します)。もちろん、root での作業は、一般的にはおすすめできません。
かわりに、以下のようにしてください。<p><p>

   * /dev/tty0* のグループを「wheel」にしてください(そうなっていなければ)<p>
   * あなたのユーザー名を、/etc/group の「wheel」行に追加してください<p>
   * あなたのユーザー名を、/etc/group の「dialer」行に追加してください<p>

(2) により、gdb のプロセスが(そして、あなたが起動している他のプロセスも)、
tty をオープンできるようになる。(3) により、tip を起動することができる
ようになる。<p><p>

<ENTRY>general_caveats 一般的な注意

1) コマンドを入力してから反応が返ってくるまでに、時々長い時間がかかる
ことがあります。これは、おそらくシリアルコネクション上の不正なデータの
せいです。みじかい休止と再送の後、すべて正常にもどります。
「remotetimeout」の値をデフォルトの 20 秒より短かく設定するとよいでしょう。
(これはある人から報告がありました。(彼の場合は)カーネルのsprintf() が
コマンドの間に実行されたことが原因でした。これにより gdb のデータがこわれ
たようです)。
<p>
2) カーネルが高優先度の割り込み(機種依存)ロック中は、Ctrl-C は動作しません。
例えば、i386 では、splimp() の中の永久ループを停止させることはできません。
しかし、ブレークポイントを、そのループの前にセットすれば、そこを一ステップ
ずつ実行することができます。

</LIST>

<a href=""><em>NetBSD Documentation: Kernel</em>にもどる</a>
<hr>

<DOCLINK>

<hr>
<address>
  <a href="../../Misc/feedback.html">(Contact us)</a>
  $NetBSD: kgdb.list,v 1.1 2000/03/20 06:03:45 dent Exp $<br>
  <a href="../../Misc/disclaimer.html">Copyright &copy; 2000
    The NetBSD Foundation, Inc.  ALL RIGHTS RESERVED.</a>
</address>

</body>
</html>