以下は、Linux カーネル文書、Documentation/DocBook/kgdb にある、Using kgdb, kdb and the kernel debugger internalsの kanda.motohiro@gmail.com による訳です。原文と同じ、GPL v2 で公開します。
Jason Wessel <jason.wessel@windriver.com>
Copyright © 2008,2010 Wind River Systems, Inc.
Copyright © 2004-2005 MontaVista Software, Inc.
Copyright © 2004 Amit S. Kale
This file is licensed under the terms of the GNU General Public License version 2. This program is licensed "as is" without any warranty of any kind, whether express or implied.Table of Contents
1. はじめに
2. カーネルをコンパイルする
3. カーネルデバッガーブート引数
4. kdb を使う
5. kgdb / gdb を使う
6. kgdb とkdb を同時に使う
7. kgdb テストスイート
8. カーネルデバッガーの内部
9. クレジット
1. はじめに
カーネルには、2つの異なるデバッガーフロントエンド (kdb and kgdb) があり、それぞれがデバッグのコアに接続します。いずれか片方のデバッガーフロントエンドを使いながら、ダイナミックに切り替えることも、カーネルのコンパイル時と実行時に正しい設定をすれば可能です。
Kdb は、単純なシェルスタイルのインタフェースであり、キーボードのあるシステムコンソールあるいはシリアルコンソールで使えます。メモリー、レジスター、プロセス一覧、dmesg を見ることができます。指定した位置で止まるようにブレークポイントをかけることもできます。ブレークポイントをかけたり、基本的なカーネルの実行制御ができますが、Kdb は、ソースレベルデバッガーではありません。それは、開発を助けるための調査をしたり、カーネルの問題を診断することを主な目的とします。コードが CONFIG_KALLSYMS つきでビルドされている場合、カーネルビルトインあるいは、カーネルモジュールにあるシンボルを、名前でアクセスすることができます。
Kgdb は、 Linux カーネルのためのソースレベルデバッガーとして使われるためのものです。Linux カーネルをデバッグするために、 gdb とともに使われます。アプリケーションの開発者が、アプリケーションをデバッグするために gdb を使うのと同じように、 gdb がカーネルに「割り込んで」メモリーや変数を調べ、コールスタック情報を見ることができるようにしてあります。カーネルコードにブレークポイントをかけたり、いくつかの制限された実行ステップをすることができます。
kgdb を使うには、2つのマシンが必要です。1つは開発マシン、もうひとつは、ターゲットマシンです。デバッグされるカーネルは、ターゲットマシンで動きます。開発マシンは、 vmlinux に対して、gdb を動かします。vmlinux には、シンボルがあります。(bzImage, zImage, uImage などのブートイメージではありません。)gdb で、開発者はコネクションパラメーターを指定して、 kgdb に接続します。開発者が使うことのできるコネクションのタイプは、ターゲットマシンのカーネルに、ビルトインあるいはローダブルモジュールとして存在する、 kgdb I/O モジュールによって決まります。
kdb のコンパイルを有効にするためには、まず、 kgdb を有効にして下さい。
kgdb テストコンパイルオプションは、 kgdb テストスイートの章で説明します。
CONFIG_KGDB を有効にするためには、 "Kernel debugging" の下を見て、 "KGDB: kernel debugger" を選択します。
vmlinux ファイルにシンボルがあることは必須ではありませんが、gdb はシンボルデータなしではあまり役に立ちません。 config メニューで、"Compile the kernel with debug info" と呼ばれる、 CONFIG_DEBUG_INFO をオンにするのがよいでしょう。
また、config メニューで、"Compile the kernel with frame pointers" と呼ばれる、 CONFIG_FRAME_POINTER をオンにするのをお勧めします。必須ではありません。このオプションは、コンパイルされた実行ファイルに、いろいろな場所で、フレーム情報をレジスターあるいはスタックに退避するコードを追加するため、 gdb などのデバッガーが、カーネルをデバッグする時により正確にスタックのバックトレースを作成することができます。
あなたのお使いのアーキテクチャが、 CONFIG_DEBUG_RODATA カーネルオプションをサポートしているなら、それをオフにするのがよいです。このオプションは、カーネルメモリー空間のある領域を、リードオンリーにするため、ソフトウエアブレークポイントが使えなくなります。もし、kgdb がお使いのアーキテクチャでハードウエアブレークポイントをサポートしており、あなたが CONFIG_DEBUG_RODATA をオンで動かしたいなら、それでもいいですが、そうでないなら、このオプションはオフにする必要があります。
次に、デバッグされるターゲットとデバッグするホストをつなぐための I/O ドライバーを選びましょう。ブート初期 Early boot のデバッグのためには、early デバッギングをサポートする KGDB I/O ドライバーが必要で、ドライバーはカーネルに直接ビルトインされる必要があります。Kgdb I/O ドライバーの設定は、カーネルあるいはモジュールパラメータで行われ、"kgdboc" パラメーターのセクションで説明します。
以下は、kgdb を使うためにオン、オフにするべき .config シンボルの例です。
# CONFIG_DEBUG_RODATA is not set
CONFIG_FRAME_POINTER=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
Kdb は、カーネルのデバッグコアの上に座っている単純な gdbstub と比べるとずっと複雑です。 Kdb は、シェルを提供する必要があり、さらにカーネルのいろいろな場所に、 "lsmod" や "ps" を実行した時に見えるような、重要なデータを表示するためのヘルパー関数をいくつも追加します。 kdb をカーネルに組み込むためのステップは、 kgdb のときと同じです。
kdb のメインの設定オプションは、config メニューで、 "KGDB_KDB: include kdb frontend for kgdb" と呼ばれる、 CONFIG_KGDB_KDB です。あなたが kgdb の設定を済ませているならば、あなたが kdb をシリアルポートで使うために必要な CONFIG_KGDB_SERIAL_CONSOLE などのI/O ドライバーの設定は済んでいるかもしれません。
PS/2 スタイルのキーボードを kdb で使うためには、config メニューで、"KGDB_KDB: keyboard as input device" と呼ばれる、 CONFIG_KDB_KEYBOARD を選択します。これは、kgdb の gdb インタフェースでは使われません。 kdbにだけ効きます。
以下は、kdb を使うためにオン、オフにするべき .config シンボルの例です。
# CONFIG_DEBUG_RODATA is not set
CONFIG_FRAME_POINTER=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDB_KDB=y
CONFIG_KDB_KEYBOARD=y
kdb をシリアルポートで使うクイックスタート
kdb の使い方の例です。
以下の引数でカーネルをブートする。
console=ttyS0,115200 kgdboc=ttyS0,115200
あるいは、
カーネルがブートした後で、 kgdboc を設定する。シリアルポートコンソールを使っている前提です。
echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc
手でカーネルデバッガーに入るか、 oops や例外が起きるのを待ちます。手でカーネルデバッガーに入る方法はいくつもあります。すべて、 sysrq-g を使います。そのためには、カーネル設定で CONFIG_MAGIC_SYSRQ=y が必要です。
kdb プロンプトが出たら、 "help" コマンドで、使えるコマンドの完全な一覧が見えます。
便利な kdb コマンドは:
lsmod -- カーネルモジュールがロードされているところを表示する。
ps -- アクティブプロセスだけを表示する。
ps A -- すべてのプロセスを表示する。
summary -- カーネルバージョンとメモリー状態を表示する。
bt -- dump_stack() で、現在プロセスのスタックバックトレースを表示する。
dmesg -- カーネル syslog バッファを表示する。
go -- システムを続行する。
kdb を使い終わったら、システムをリブートするか、あるいは、 "go" コマンドで通常のカーネル実行を続行します。長いことカーネルを止めていた場合、タイムリーなネットワーキングや、なんらかの実時間に依存するアプリケーションは誤動作することがあるので注意下さい。
kdb を、キーボード接続したコンソールで使うクイックスタート
キーボードで kdb を使う例です。
以下の引数でカーネルをブートする。
kgdboc=kbd
あるいは、
カーネルがブートした後で、 kgdboc を設定する。
echo kbd > /sys/module/kgdboc/parameters/kgdboc
手でカーネルデバッガーに入るか、 oops や例外が起きるのを待ちます。手でカーネルデバッガーに入る方法はいくつもあります。すべて、 sysrq-g を使います。そのためには、カーネル設定で CONFIG_MAGIC_SYSRQ=y が必要です。
g を押して、放す。
g を押して、放す。
これで、 "help", "dmesg", "bt" などの kdb コマンドがうてます。カーネル実行を続行するには、 "go" です。
5. kgdb / gdb を使う
6. kgdb とkdb を同時に使う
kdb と kgdb をダイナミックに移動できます。デバッグコアは、あなたが前回どっちを使っていたかを覚えているので、自動的に同じモードで開始します。
kgdb から kdb にスイッチする
kgdb から kdb にスイッチするには、2つの方法があります。 gdb にメンテナンスパケットを送らせるか、 $3#33 コマンドをじかにタイプします。カーネルデバッガーが kgdb モードで止まると、 KGDB メッセージを表示します。KDB のときは、 $3#33 です。シーケンスは、1パスで正しくタイプする必要があります。バックスペースやデリートを使ってはいけません。 kgdb がそれをデバッグストリームの一部として解釈してしまうからです。
1 じかにタイプ
$3#33
2 gdb から
maintenance packet 3
注意:ここで gdb は止めなくてはいけません。例えば、control-z を打って、kill -9 % します。
kdb から kgdb にスイッチする
kdb から kgdb にスイッチするには、2つの方法があります。kdb シェルプロンプトから、 kgdb コマンドを入れて、手で kgdb モードに入れます。あるいは、kdb シェルプロンプトがアクティブのときに、 gdb を接続できます。kdb シェルは、 gdb が gdb リモートプロトコルで発行する典型的な最初のコマンドを監視していますから、それらを見たら、自動的に kgdb モードに入ります。
1 kdb から、このコマンドを実行します:
kgdb
端末プログラムを切断して、 gdb をその代わりに接続します。
2 kdb プロンプトで、端末プログラムを切断して、 gdb をその代わりに接続します。
gdb から kdb コマンドを使う
gdb monitor コマンドを使って、gdb から kdb コマンドの一部を使うことができます。実行の制御や、ブレークポイント操作をしてはいけません。カーネルデバッガーの状態をこわします。gdb が接続されているときは、 gdb の実行制御と、ブレークポイントを使って下さい。便利なコマンドは、lsmod, dmesg, ps そして、メモリー状態を見るコマンドでしょう。すべての可能な kdb コマンドを見るには、monitor help して下さい。
例:
(gdb) monitor ps
1 idle process (state I) and
27 sleeping system daemon (state M) processes suppressed,
use 'ps A' to see all.
Task Addr Pid Parent [*] cpu State Thread Command
0xc78291d0 1 0 0 0 S 0xc7829404 init
0xc7954150 942 1 0 0 S 0xc7954384 dropbear
0xc78789c0 944 1 0 0 S 0xc7878bf4 sh
(gdb)
7. kgdb テストスイート
(大意) KGDB_TESTS を有効にしてビルドすると、kgdb_開発者に便利な内部テストが有効になります。
8. カーネルデバッガーの内部
アーキテクチャ固有
kgdb_skipexception — (optional) exit kgdb_handle_exception early
kgdb_breakpoint — compiled in breakpoint
kgdb_arch_init — Perform any architecture specific initalization.
kgdb_arch_exit — Perform any architecture specific uninitalization.
pt_regs_to_gdb_regs — Convert ptrace regs to GDB regs
sleeping_thread_to_gdb_regs — Convert ptrace regs to GDB regs
gdb_regs_to_pt_regs — Convert GDB regs to ptrace regs.
kgdb_arch_handle_exception — Handle architecture specific GDB packets.
kgdb_roundup_cpus — Get other CPUs into a holding pattern
kgdb_arch_set_pc — Generic call back to the program counter
kgdb_arch_late — Perform any architecture specific initalization.
struct kgdb_arch — Describe architecture specific values.
struct kgdb_io — Describe the interface for an I/O driver to talk with KGDB.
The kernel debugger is organized into a number of components:
デバッグコア
The debug core is found in kernel/debugger/debug_core.c. It contains:
A generic OS exception handler which includes sync'ing the processors into a stopped state on an multi-CPU system.
The API to talk to the kgdb I/O drivers
The API to make calls to the arch-specific kgdb implementation
The logic to perform safe memory reads and writes to memory while using the debugger
A full implementation for software breakpoints unless overridden by the arch
The API to invoke either the kdb or kgdb frontend to the debug core.
The structures and callback API for atomic kernel mode setting.
NOTE: kgdboc is where the kms callbacks are invoked.
kgdb arch-specific implementation
This implementation is generally found in arch/*/kernel/kgdb.c. As an example, arch/x86/kernel/kgdb.c contains the specifics to implement HW breakpoint as well as the initialization to dynamically register and unregister for the trap handlers on this architecture. The arch-specific portion implements:
contains an arch-specific trap catcher which invokes kgdb_handle_exception() to start kgdb about doing its work
translation to and from gdb specific packet format to pt_regs
Registration and unregistration of architecture specific trap hooks
Any special exception handling and cleanup
NMI exception handling and cleanup
(optional)HW breakpoints
gdbstub frontend (aka kgdb)
The gdbstub is located in kernel/debug/gdbstub.c. It contains:
All the logic to implement the gdb serial protocol
kdb frontend
The kdb debugger shell is broken down into a number of components. The kdb core is located in kernel/debug/kdb. There are a number of helper functions in some of the other kernel components to make it possible for kdb to examine and report information about the kernel without taking locks that could cause a kernel deadlock. The kdb core contains implements the following functionality.
A simple shell
The kdb core command set
A registration API to register additional kdb shell commands.
A good example of a self-contained kdb module is the "ftdump" command for dumping the ftrace buffer. See: kernel/trace/trace_kdb.c
For an example of how to dynamically register a new kdb command you can build the kdb_hello.ko kernel module from samples/kdb/kdb_hello.c. To build this example you can set CONFIG_SAMPLES=y and CONFIG_SAMPLE_KDB=m in your kernel config. Later run "modprobe kdb_hello" and the next time you enter the kdb shell, you can run the "hello" command.
The implementation for kdb_printf() which emits messages directly to I/O drivers, bypassing the kernel log.
SW / HW breakpoint management for the kdb shell
kgdb I/O driver
Each kgdb I/O driver has to provide an implementation for the following:
configuration via built-in or module
dynamic configuration and kgdb hook registration calls
read and write character interface
A cleanup handler for unconfiguring from the kgdb core
(optional) Early debug methodology
Any given kgdb I/O driver has to operate very closely with the hardware and must do it in such a way that does not enable interrupts or change other parts of the system context without completely restoring them. The kgdb core will repeatedly "poll" a kgdb I/O driver for characters when it needs input. The I/O driver is expected to return immediately if there is no data available. Doing so allows for the future possibility to touch watch dog hardware in such a way as to have a target system not reset when these are enabled.
If you are intent on adding kgdb architecture specific support for a new architecture, the architecture should define HAVE_ARCH_KGDB in the architecture specific Kconfig file. This will enable kgdb for the architecture, and at that point you must create an architecture specific kgdb implementation.
There are a few flags which must be set on every architecture in their <asm/kgdb.h> file. These are:
NUMREGBYTES: The size in bytes of all of the registers, so that we can ensure they will all fit into a packet.
BUFMAX: The size in bytes of the buffer GDB will read into. This must be larger than NUMREGBYTES.
CACHE_FLUSH_IS_SAFE: Set to 1 if it is always safe to call flush_cache_range or flush_icache_range. On some architectures, these functions may not be safe to call on SMP since we keep other CPUs in a holding pattern.
There are also the following functions for the common backend, found in kernel/kgdb.c, that must be supplied by the architecture-specific backend unless marked as (optional), in which case a default function maybe used if the architecture does not need to provide a specific implementation.
9. クレジット
略