[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 © 2000
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.</a>
</address>
</body>
</html>