gdbstub-mcp について
gdbstub-mcpは、QEMU上で動くベアメタルカーネルをデバッグするMCPサーバーです。gdbバイナリなしでGDB Remote Serial Protocolを直接使用し、QEMUログからx86のクラッシュやトリプルフォルトを説明できます。
主な機能
- 01QEMU gdbstubセッションへの接続
- 02レジスタとメモリの読み書き
- 03ブレークポイントとウォッチポイントの設定
- 04実行のステップ実行と継続、確認
- 05シンボル、行番号、バックトレースの解決
- 06QEMUログからx86の障害を説明
活用シーン
- 01QEMU上で動くカーネルのデバッグ
- 02ブレークポイントとステップ実行による追跡
- 03カーネルのメモリとレジスタの確認
- 04QEMUログによるトリプルフォルトの診断
MCP 対応
MCPサーバーとして動作し、MCPクライアントにデバッグツールを提供します。GDB Remote Serial ProtocolでQEMUのgdbstubと直接通信し、gdbバイナリを必要としません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
18掲載時のツール一覧 · 3 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| elf | any | いいえ | |
| host | string | いいえ | |
| name | string | はい | |
| port | integer | いいえ | |
| load_bias | integer | いいえ | |
| timeout_s | number | いいえ |
詳細
gdbstub-mcp
AI エージェントにカーネルをデバッグさせ、トリプルフォールトの原因を教えてもらいましょう。
gdbstub-mcp は、QEMU で実行されるベアメタルコードをデバッグする機能を AI エージェント
(Claude Code、または任意の MCP クライアント)に提供する MCP サーバーです。
GDB Remote Serial Protocol を QEMU 内蔵の gdbstub と直接やり取りするため、gdb バイナリは不要です。クロスアーキテクチャ対応の gdb の入手が面倒な Windows や macOS では、特に便利です。
qemu-mcp と連携して使います。qemu-mcp を使うと、エージェントがカーネルを起動してクラッシュを確認できます。gdbstub-mcp を使うと、クラッシュの原因を突き止められます。
動作例
趣味で開発しているカーネルをデバッグするエージェントの例です。tests/fixtures/kernel にあるテストカーネルから取得した実際の出力です。
> debug_break kernel.c:10
#1 sw breakpoint at 0x100029 <add+0x9> at kernel.c:10
> debug_continue
Stopped: SIGTRAP (breakpoint/step) - breakpoint #1 (kernel.c:10)
pc = 0x100029 <add+0x9> at kernel.c:10
next: mov eax, dword ptr [ebp + 8]
> debug_backtrace
#0 0x100029 <add+0x9> at kernel.c:10
#1 0x100071 <compute+0x31> at kernel.c:16
#2 0x1000b2 <kmain+0x12> at kernel.c:28
#3 0x100016 <_start+0xa> at boot.s:21
> debug_registers eip,eflags,cr0
eip = 0x00100029 <add+0x9> at kernel.c:10
eflags = 0x00000093 [SF AF CF]
cr0 = 0x00000011 [ET PE]
マシンが何も表示せずに再起動した場合、debug_explain_fault は QEMU の割り込みログを読み取り、クラッシュの原因を説明します。
> debug_explain_fault
A TRIPLE FAULT occurred: the CPU reset itself.
[0] #UD invalid opcode at triple_fault+0xa (kernel.c:23)
[1] #GP general protection fault at triple_fault+0xa (kernel.c:23)
selector 0x32: IDT entry 6 = #UD
-> the IDT entry for vector 0x6 is missing or invalid - the CPU couldn't
even start your handler. ...
[2] #DF double fault at triple_fault+0xa (kernel.c:23)
Root cause: the chain started with #UD at triple_fault+0xa.
It escalated to a triple fault because the handler for #UD (IDT entry 0x6)
could not be invoked. Fix the IDT entry so the original exception reaches
your handler, then fix the #UD itself.
実際の QEMU のクラッシュログは、タイマー割り込みとレジスタダンプで数千行に及びます。このツールは例外の連鎖を特定し、エラーコードをデコードして、原因を示します。
なぜ、別のデバッガー MCP が必要なのか?
既存の GDB MCP サーバーは gdb バイナリをラップし、ユーザーランドプログラムやコアダンプを対象としています。組み込み向けのものは、probe-rs や OpenOCD を通じてマイクロコントローラーを対象としています。自作カーネルを QEMU で実行し、何も出力する前にクラッシュするという OS 開発の反復作業に特化したものはありません。
- gdb は不要です。 純粋な Python(
pyelftoolsとcapstone)で動作します。pip install gdbstub-mcpを実行すれば準備完了です。 - QEMU がサポートするあらゆるアーキテクチャに対応します。 レジスタの配置は gdbstub 自身の
target.xmlから取得します。x86 では制御レジスタ(CR0/CR2/CR3/CR4、EFER)も利用でき、フラグレジスタもデコードされます。 - シンボルとソース行に対応します。
kmain、kmain+0x10、またはkernel.c:42にブレークポイントを設定でき、停止するたびにfunction+offset at file:lineが表示されます。プレフィックス付きの ABI にも対応しており、名前が一意ならkmainはmort_kmainに解決されます。 - 実際のカーネルでも使えるバックトレース。 フレームポインターのチェーンをたどり、x86 のプロローグとエピローグを正しく処理します。フレームポインターなしでビルドされた
-O2カーネルでは、スタックをスキャンして戻りアドレスを探すこともできます。 - トリプルフォールトを診断します。 上記の
debug_explain_faultが対応します。この機能を備えた別のツールは見つけられていません。
インストール
pip install gdbstub-mcp
Claude Code の場合:
claude mcp add gdbstub -- gdbstub-mcp
ほかの MCP クライアントでも同様に、gdbstub-mcp を stdio サーバーとして実行します。Python 3.10 以降が必要です。
使い方
gdbstub を有効にし、CPU を停止した状態で QEMU を起動します。
qemu-system-i386 -kernel kernel.elf -s -S -d int,cpu_reset -D int.log -no-reboot
-sはtcp::1234で gdbstub を開きます。-Sは最初の命令を実行する前に CPU を停止します。debug_explain_faultを使う場合のみ、-d int,cpu_reset -D int.log -no-rebootが必要です。
qemu-mcp を使う場合は、同じフラグを qemu_boot の extra_args に渡します。
extra_args="-s -S -d int,cpu_reset -D int.log -no-reboot"。
続いて、エージェントに「kernel.elf でカーネルに接続し、kmain にブレークポイントを設定して、ページフォールトが起きるまでステップ実行して」のように指示します。
アドレスは 0x1234、symbol、symbol+0x10、file.c:42、または $esp+8 の形式で指定できます。
ツール
| ツール | 機能 |
|---|---|
debug_connect | gdbstub(port、デフォルトは 1234)に接続し、オプションでシンボル付きの elf を読み込みます。名前付きセッションを複数同時に開けます。 |
debug_disconnect | ブレークポイントを削除し、デタッチ(ゲストは実行を継続します)して、セッションを閉じます。 |
debug_sessions | セッションのエンドポイント、実行中または停止中の状態、ELF、ブレークポイント数を一覧表示します。 |
debug_registers | レジスターを読み取ります。選択したリスト、汎用レジスター一式、または制御、セグメント、FPU レジスターを含む all=True を指定できます。フラグはデコードされ、ポインターはシンボルに対応付けられます。 |
debug_set_register | レジスターに値を書き込みます。 |
debug_memory | メモリーを、16 進ダンプ、シンボルに対応付けられたポインターサイズの words、または string として読み取ります。 |
debug_write_memory | バイトを書き込みます。 |
debug_break | ブレークポイント(sw、またはページング前や未ロードのコード用の hw)またはウォッチポイント(write、read、access)を設定します。 |
debug_delete / debug_breakpoints | ブレークポイントを削除するか、すべて一覧表示します。 |
debug_continue | 再開し、停止するまで最大 timeout_s 待機します。停止しない場合、ターゲットは実行を継続します。 |
debug_wait / debug_interrupt | 停止するまで待機を続けるか、今すぐターゲットを停止します(Ctrl-C と同様です)。 |
debug_step | N 個の命令をシングルステップ実行します。 |
debug_backtrace | フレームポインターチェーン(fp)、スタックスキャン(scan)、または auto によるコールスタックを表示します。 |
debug_disassemble | アドレスまたは pc の位置を逆アセンブルします。bits=16 はリアルモードのコードをデコードします。 |
debug_symbol | ターゲットがなくても、アドレス、シンボル、または行をオフラインで検索します。 |
debug_explain_fault | QEMU の -d int,cpu_reset ログからクラッシュまたはトリプルフォールトを説明します(x86)。 |
制限事項(正直に記載)
- ソースレベルではなく、マシンレベルです。
next/finishはなく、ローカル変数や C 式にもまだ対応していません(BACKLOG.md を参照)。シンボル、行、レジスター、メモリー、逆アセンブルを利用でき、カーネルのデバッグの大部分をカバーします。 - スタックスキャンはヒューリスティックです。 既知の関数内にある
callの直後を指すスタックワードをすべて報告するため、古いフレームが表示されることがあります。正確なバックトレースを得るには、-fno-omit-frame-pointerを指定してビルドしてください。 debug_explain_faultが対応するのは x86 のログのみです。- QEMU の gdbstub でテスト済みです。ほかの RSP スタブ(OpenOCD、Bochs、実機用プローブ)も同じプロトコルを使うため動作する可能性は高いですが、テストされていません。
テスト
pip install ".[test]" anyio "ruff==0.16.0" "mypy==2.3.0"
ruff check src tests && mypy --strict src
pytest tests
ユニットテストでは、実際の TCP ソケット上の偽 gdbstub と、トリプルフォールトの実際の QEMU ログを使用するため、QEMU は必要ありません。tests/test_qemu_integration.py は実際の QEMU でフィクスチャーカーネルを起動します(CI では qemu-system-x86 をインストールします)。ブレークポイント、ウォッチポイント、行番号、4 階層のバックトレース、エンドツーエンドのトリプルフォールトを検証し、QEMU がインストールされていない場合はテストをスキップします。フィクスチャーカーネルを再ビルドするには、pip install ziglang が必要な python tests/fixtures/kernel/build.py を実行してください。
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。