kgdb
は非常に高レベルのユーザインタフェースを提
供するオフラインデバッガですが, いくつかのことはできません.
(できないことの中で)極めて重要なことはカーネルコードへのブレークポイ
ントの設定とシングルステップ実行です.
カーネルの低レベルデバッグが必要であれば, DDBと呼ばれる on-lineデバッ
ガが使えます. ブレークポイントの設定, シングルステップのカーネルの実
行, 変数の検査と変更などができます. ただし,これはカーネルのソースファ
イルにアクセスすることはできません. kgdb
のようにすべてのデ
バッグ情報にはアクセスできず, globalと staticのシンボルにアクセス
することができるだけです.
カーネルに DDBを含めるためにはコンフィグファイルに次のようなオプショ ンを加えて,
options DDB
再構築をおこないます. ( FreeBSDのカーネルの設定の詳細については FreeBSDカーネルのコンフィグレーションを参照してくださ い. もしブートブロックが古いバージョンですと, デバッガのシンボルが完 全にはロードされないかもしれませんので注意してください. DDBシンボル がロードされるようにブートブロックを最新の物にアップデートしてくださ い)
DDB カーネルの実行において, DDBに入るいくつかの方法があります. 最初
の, 最も早い方法はブートプロンプトが出ている時に-d
のブート
フラグをタイプすることです. カーネルはデバッグモードで起動し, デバ
イスのプローブ以前に DDBに入ります. したがって, デバイスのプローブ/初期
設定ファンクションのデバッグができます.
2つ目のシナリオはキーボードのホットキーで, 通常は Ctrl-Alt-ESCです.
syscons ではホットキーは再設定することができ, 配付されているいくつかの
キーマッピングでは別のキーに再設定されていますので確認しておいてください.
シリアルラインの BREAKを使って シリアルコンソールから DDBへ入ることを可
能にするオプションもあります (カーネルコンフィグレーションファイルの
``options BREAK_TO_DEBUGGER
''). これは 多くのつまらないシリ
アルアダプタが, 例えばケーブルを引き抜いた時に BREAK状態を意味もなく
作り出してしまうのでデフォルトでは無効になっています.
3つ目は, DDBを使うようになっているカーネルがパニック状態になると DDB へ入るというものです. このため, 無人運転するマシンのカーネルにDDBを 入れるのは賢明ではありません.
DDBのコマンドはおおまかには gdb
のいくつかのコマンドと似て
います。おそらく最初にブレークポイントを設定する必要があるでしょう。
b function-name
b address
数値はデフォルトでは16進数で, シンボル名とはまったく異ります. 16進数で
a
-f
の文字で始まる場合は, 先頭に
0x
をつける必要があります(それ以外の数字の場合はどちらでもか
まいません). function-name + 0x103
のような単純な式を使うこ
とができます.
割り込みされたカーネルから処理を続行するためには,
c
とタイプするだけです.
スタックのトレースには
trace
とします.
DDB にホットキーで入った場合は, カーネルはその (ホットキーの) 割り込み の処理を行っていますのでスタックトレースはあまり役にたたないことに注 意してください.
ブレークポイントを削除したい場合は,
del
del address-expression
とします. 最初の形式はブレークポイントにヒットしたすぐ後で使うことが
でき, 現在のブレークポイントを削除します. 2番目の形式では任意のブレー
クポイントを削除することができますが, 次の形式で得られるような正確な
アドレスを与えることが必要です.
show b
カーネルをシングルステップ実行させるには
s
としてみてください. これは関数呼出し先までステップ実行 (step into
function) するでしょう. 次のステートメントが終了するまでのDDBトレースは
n
によっておこなうことができます.
注: これは gdb
の `next' 命令とは異ります.
gdb
の `finish'命令と似ています.
メモリ上のデータを調べるには (例として) 次のようにします.
x/wx 0xf0133fe0,40
x/hd db_symtab_space
x/bc termbuf,10
x/s stringbuf
word/halfword/byte 単位でアクセスをおこない, hex (16進) /dec (10進) /
char (文字) /string (文字列) で表示します. カンマの後ろの数字はオブジェク
トカウントです. 次の 0x10個の要素を表示するには, 単純に
x ,10
とします. 同様に次のように使うことができます.
x/ia foofunc,10
foofunc
の最初の 0x10個の命令語をディスアセンブルし,
foofunc
の先頭からのオフセットとともに表示します.
メモリの内容を変更するには writeコマンドを使います.
w/b termbuf 0xa 0xb 0
w/w 0xf0010030 0 0
コマンドモディファイアの (b
/h
/w
) はデータを
書くサイズを定義し, これに続く最初の式は書き込むアドレス, 残りがこれ
に続く連続するメモリアドレスに書き込まれるデータになります.
現在のレジスタ群の内容を知りたい場合は
show reg
とします. また, 単一のレジスタの値を表示するには, 例えば
p $eax
とします. また値の変更は
set $eax new-value
とします.
DDBからカーネルの関数を呼び出す必要がある場合は, 単に
call func(arg1, arg2, ...)
とします. return 値が出力されます.
動いているプロセスの ps(1)
スタイルの概要は
ps
です.
カーネルの失敗の原因の調査が終わったらリブートすべきです. それまでの 不具合によりカーネルのすべての部分が期待するような動作をしているわけ ではないということを忘れないでください. 以下のうちいずれかの方法でシ ステムのシャットダウンおよびリブートを行ってください.
call diediedie()
カーネルをコアダンプしてリブートしますので, 後で kgdbによってコアの高
レベル解析をすることができます. このコマンドは通常
`continue
'命令にエイリアスされています.
`panic
'にエイリアスされている
call boot(0)
は動いているシステムを `clean' に shut downするよい方法です. すべて
のディスクを sync()
して最後にリブートします. ディスクとカー
ネルのファイルシステムインタフェースが破損していない限り, ほぼ完全
に `clean'にシャットダウンするよい方法でしょう.
call cpu_reset()
は大惨事を防ぐための最後の手段で「赤い大きなボタン」を押すのとほとんど
同じです.(訳注: リセットボタンを押すのとほぼ同じであるという意味です)
短いコマンドの要約は
help
をタイプします. ただし, デバッグセッションのために ddb(4)
の
マニュアルページのプリントアウトを用意しておくことを強くお奨めします.
カーネルのシングルステップ中にオンラインマニュアルを読むことは難しい
ということを覚えておいてください.