- Published on
ソフトウェアデバッグマスタリー 2026 完全ガイド - GDB / LLDB / rr / Pernosco / pdb / Chrome DevTools / Bun inspect / DAP 徹底分析
- Authors

- Name
- Youngju Kim
- @fjvbn20031
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian Kernighan
ソフトウェアエンジニアが生涯で最も多く行う仕事はコードを書くことではなく、バグをデバッグする ことです。各種統計はその割合を 25 〜 50 % と推定していますが、シニアになるほどこの比率はむしろ増える傾向があります。複雑な分散システム、見えにくいメモリ破壊、非決定的な並行バグ、本番環境でしか再現しないミステリー — 2026 年現在、デバッグは単に print を仕込む作業ではなく、科学的方法 + 巨大なツール群 + AI アシスト を組み合わせた一つの学問になりつつあります。
本稿では GDB 15、LLDB 19、rr、Pernosco、WinDbg TTD などのネイティブデバッガから、Chrome DevTools 2025 の AI アシスト、Bun / Deno / Node のインスペクタ、Python の pdb / pdbpp / ipdb / pudb 比較、Rust・Go・Java の言語別デバッガ、eBPF ベースの観測、Valgrind とサニタイザ、DAP(Debug Adapter Protocol)の標準 — そして最も重要な デバッグマインドセット までを一気通貫で整理します。
1. デバッグマインドセット — 仮説駆動(Hypothesis-Driven)の科学的デバッグ
優れたデバッグはツールではなく 思考様式(マインドセット) から始まります。Andreas Zeller の名著 Why Programs Fail(2009 / 2023 第 2 版)は、デバッグを「科学者が仮説を立て、実験で反証していく」プロセスになぞらえています。中核となるループ:
- 現象(Symptom)を観察する: どんな入力で、どんな環境で、どんな結果が出たか
- 仮説(Hypothesis)を立てる: 可能性のある原因候補を N 個、可能性の高い順に並べる
- 予測(Prediction): この仮説が正しければ、A を変えたら B が変わるはずだ
- 実験(Experiment): 最小の変更で予測を検証する
- 反証(Falsify) または 絞り込み(Refine): 結果に応じて仮説を捨てる/狭める
このサイクルを速く回せる人が優れたデバッガです。初学者が最もよく陥る罠は、ランダムにコードを変えてうまくいくのを祈る こと。Zeller はこれを "shotgun debugging" と呼び、時間を無駄にして新たなバグを生むだけだと指摘します。もう一つの罠は 確証バイアス: 自分の仮説を支持する証拠ばかり探し、反証を無視すること。優れたデバッガは自分の仮説を積極的に 反証しよう とします。
2026 年のシニアエンジニアが強調するもう一つの原則は 「バグは情報である(A bug is information)」。バグ発生時に最も貴重な資源はそれを再現する正確な条件であり、それが失われる前に 再現可能な最小ケース(Minimal Reproducer) を確保することがデバッグの半分です。Delta debugging アルゴリズム(Zeller, 2002)はこのプロセスを自動化し、モダンなテストフレームワークの shrinking(Hypothesis, QuickCheck, fast-check)も同じ発想です。
2. GDB 15 — モダンネイティブデバッガの標準
GDB(GNU Debugger, gnu.org/software/gdb)は 1986 年に Richard Stallman が開始して以来 40 年間進化し続ける、事実上のネイティブデバッガ標準です。2025 年 1 月リリースの GDB 15 は Python 3.12 統合、DWARF 5 の完全サポート、Rust / Swift / Modula-2 のような後発言語の pretty-printing 改善をもたらしました。
基本ワークフロー:
# ソースからビルド — 必ず -g(デバッグシンボル)と -O0 または -Og(最適化抑制)
gcc -g -Og main.c -o app
# デバッガに入る
gdb ./app
# または実行中プロセスにアタッチ
gdb -p 12345
# あるいはコアダンプ解析
gdb ./app core.12345
中心となるコマンドは break、run、next、step、print、backtrace(略 bt)、info、watch、continue。
(gdb) break main.c:42 # 行単位ブレークポイント
(gdb) break parse_request # 関数名で
(gdb) break parse_request if errno == 5 # 条件付き
(gdb) watch *ptr # メモリが変わったら停止
(gdb) catch throw # C++ 例外発生時に停止
(gdb) bt full # スタック全体 + ローカル変数
(gdb) frame 3 # 3 番フレームへ移動
(gdb) info locals # ローカル変数一覧
(gdb) print/x *(struct request *)0x7ffe8000 # 16 進で構造体キャスト表示
GDB 15 で最も強力なのは Python スクリプティング です。gdb.execute、gdb.parse_and_eval、カスタム pretty-printer を通じて、コンパイル済みのドメインオブジェクトを人間が読める形式で表示できます。
# ~/.gdbinit または別の .py ファイル
import gdb
class RequestPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
path = self.val['path'].string()
method = self.val['method'].string()
return f"Request {method} {path}"
def lookup_request(val):
if str(val.type) == 'struct request':
return RequestPrinter(val)
return None
gdb.pretty_printers.append(lookup_request)
TUI(Text User Interface)モード gdb -tui または Ctrl+X A はターミナルを 4 分割し、ソース・レジスタ・アセンブリ・コマンド入力を同時に表示します。2025 年には gdb-dashboard(github.com/cyrus-and/gdb-dashboard)が事実上の標準 UI 拡張となりました。
3. LLDB 19 — Apple / LLVM 生態系の標準
LLDB(lldb.llvm.org)は LLVM プロジェクトのデバッガで、2025 年 9 月リリースの LLVM 19 の一部として進化します。Apple の全プラットフォーム(macOS, iOS, watchOS, visionOS)で Xcode が内部的に使い、Rust の rust-lldb、Swift のデフォルトデバッガでもあります。
コマンドは GDB に似ていますが、少し違う語彙を使います。
(lldb) breakpoint set --file main.c --line 42 # b main.c:42 略式もサポート
(lldb) breakpoint set --name parse_request
(lldb) run
(lldb) thread step-over # n
(lldb) thread step-in # s
(lldb) frame variable # info locals
(lldb) frame select 3
(lldb) thread backtrace # bt
(lldb) memory read --size 4 --format x 0x100000 # メモリの hex dump
(lldb) expression -- (*request).path # p (*request).path
LLDB の強みは Python スクリプトブリッジ が GDB より深く統合されている点です。script コマンドで LLDB の中で直接 Python REPL が立ち上がり、SBValue、SBFrame、SBProcess などのオブジェクトでデバッグセッションをプログラム可能にします。
(lldb) script
>>> import lldb
>>> frame = lldb.thread.GetSelectedFrame()
>>> req = frame.FindVariable('request')
>>> print(req.GetChildMemberWithName('path').GetSummary())
Swift デバッグ時には po(print object)で Swift オブジェクトの description を呼び出し、v(variable)は変数の高速表示に最適化されています。2025 年の Swift 6.1 から Swift Macros デバッグが LLDB に統合され、マクロ展開結果をその場で inspect できるようになりました。
Rust では rust-lldb(または rust-gdb)ラッパーが標準ライブラリの型(Vec、String、HashMap)の pretty-printer を自動で読み込みます。
4. rr — 決定論的な記録 & 再生デバッグ
rr(rr-project.org)は Mozilla が 2014 年に発表した record-and-replay デバッガで、非決定的(non-deterministic)なバグを決定的に再現 できるようにします。一度録画した実行を同じシステムコール・スレッドスケジュール・シグナル順序でそのまま再生するので、同じバグが何度でも再現します。
# 録画
rr record ./app --input data.json
# 再生(gdb 風のセッションに入る)
rr replay
# あるいは最新の録画を自動再生
rr replay -p 0
# 録画ディレクトリの位置
ls ~/.local/share/rr/
rr の真の魅力は 逆方向(Reverse)実行 です。
(rr) reverse-continue # 直前のブレークポイントまで逆戻り
(rr) reverse-step # 一段階逆戻り
(rr) reverse-next # 一行逆戻り
(rr) watch -l x # x がどこで変わったか逆方向にトレース
伝統的な「ポインタが NULL だが、どこで NULL になったか分からない」というシナリオは、rr では reverse-continue + watch *ptr の一行で解決します。メモリが変化した時点まで逆走するので、犯人がすぐ分かります。
制約は三つ。Intel CPU でのみ動作(2026 年に AMD Zen 5 の部分対応が追加されましたが、まだベータ)、CPU の PMC(Performance Monitoring Counter)を使うため仮想化環境では動作が難しい、シングル / マルチスレッド両方に対応するがマルチコア並列実行はシリアライズされる(性能オーバーヘッド 1.2 〜 5 倍)。それでも非決定的バグデバッグでの効果が圧倒的で、Firefox、Chromium、Microsoft Edge チームはすべて rr ベースのワークフローを持ちます。
5. Pernosco — クラウド型 omniscient デバッガ
Pernosco(pernos.co)は rr の創始者 Robert O'Callahan と Kyle Huey が 2018 年に Mozilla から spin-off したクラウドデバッグサービスです。中心アイデアは rr の録画をクラウドにアップロードすると、実行全体を事前に分析して「全知(omniscient)」なデバッグセッションを Web UI で提供する こと。
# ローカルで rr 録画
rr record ./app
# Pernosco CLI でアップロード(Pernosco アカウントが必要)
pernosco-submit upload ~/.local/share/rr/latest-trace
アップロード後、Pernosco はバックエンドで 1 〜 10 分間トレース全体をインデックスし、その結果として以下を提供します。
- 任意時点へのジャンプ: 時間軸の任意点をクリックすると、その瞬間のメモリ・レジスタ・コールスタック全体が即時表示
- dataflow トラッキング: ある値がどこから来たかを逆方向に追跡
- 自動 root-cause 候補のハイライト: "この NULL は 30 秒前の 42 行目で free された後に再利用されました"
- 共有可能な URL: 同僚にデバッグセッションそのものを共有
Mozilla、Cloudflare、Sourcegraph、Discord などが本番グレードのバグハンティングに利用しています。2026 年現在の単価はやや高め(トレース当たり 10 〜 50 米ドル前後)ですが、一週間消費するミステリーバグを一時間で解決するなら圧倒的に得です。
6. WinDbg + TTD — Windows のタイムトラベルデバッグ
Windows 陣営の標準デバッガは WinDbg(learn.microsoft.com/windows-hardware/drivers/debugger/)で、2018 年から WinDbg Preview(現在の WinDbg "engine 2"、2025 年にモダン UI に統合)がメインクライアントとなっています。WinDbg はユーザモードだけでなく カーネルモード、クラッシュダンプ、そして TTD(Time Travel Debugging) までカバーします。
TTD は rr / Pernosco の Windows 版に相当し、TTTracer.exe で実行を録画すると .run ファイルが生成されます。
# 管理者プロンプトで録画開始
TTTracer.exe -out C:\traces\ -launch myapp.exe
# WinDbg で .run ファイルを開く → リバースデバッグ可能
# WinDbg コマンドウィンドウ
0:000> g- # 逆方向 go
0:000> t- # 逆方向 step
0:000> wt- # 逆方向 watch
WinDbg の真価は カーネルデバッグ です。BSOD(Blue Screen of Death)ダンプファイル(.dmp)を開き、誰が IRQL 違反を起こしたか、どのドライバが deadlock を作ったかを追跡できます。Windows セキュリティチーム、アンチチートエンジン、EDR ソリューション開発者が毎日扱う道具です。
7. Chrome DevTools 2025 — AI アシストと MCP
Chrome DevTools は 2008 年の初登場以来最も進化したデバッガの一つで、2025 年に入り AI アシスト(Insights, Recorder) と DevTools MCP が合流して本質的な変化を迎えました。
主要パネル:
- Sources: ブレークポイント、条件付き、logpoint、async stack traces、source map 自動マッピング
- Performance: トレース録画 → flame chart → AI 駆動の自動インサイト("LCP が遅い原因は main thread blocking です")
- Memory: Heap snapshot、Allocation timeline、detached DOM ツリー、retainer ツリー
- Network: リクエスト毎の timing waterfall、Initiator チェーン、throttling シミュレーション
- Coverage: 未使用 JS / CSS の測定
- Recorder: ユーザシナリオ録画 → Playwright / Puppeteer スクリプト自動生成
2025 年 4 月にリリースされた Chrome DevTools MCP(github.com/ChromeDevTools/chrome-devtools-mcp)は、Claude・Cursor・Codex のような AI コーディングエージェントが実際のブラウザを操作しながらデバッグ・テストできるようにします。例えば Claude に「コンソールエラーが出ているボタンを見つけて直して」と頼むと、MCP 経由で DevTools を操作してコンソールを読み、セレクタを探し、トレースを取って原因分析を行います。
Node.js デバッグでも Chrome DevTools は標準です。node --inspect で起動したプロセスは chrome://inspect または about:inspect で発見され、V8 inspector プロトコルで接続します。
# Node.js: 起動と同時に inspector を開く
node --inspect index.js
# 1 行目でブレークして attach を待つ
node --inspect-brk index.js
# ポート指定(Docker などで)
node --inspect=0.0.0.0:9229 index.js
8. Firefox DevTools / Safari Web Inspector
Firefox DevTools(firefox-source-docs.mozilla.org/devtools-user/)は Chrome とほぼ同等の機能を提供しながらも、いくつかの差別点を持ちます。
- CSS Grid Inspector: グリッドライン・ギャップ・領域を視覚的にオーバーレイ(Chrome も後追いしましたが Firefox が元祖)
- Accessibility Inspector: WCAG 違反を自動検出
- Network Throttling: WebRTC・WebSocket トラフィック解析(Chrome より豊富)
- about:debugging: 別ページから他のタブ・service worker・extension を一括で attach
Safari Web Inspector は iOS / macOS デバイスのデバッグに必須です。Mac の Safari → 開発者メニュー → iPhone シミュレータ / 実機を選択して attach します。2025 年の Safari 18.4 から WebGPU 対応のデバッガが正式リリースされ、2026 年の Safari 19 では React DevTools 統合がネイティブサポートされます。
三つのブラウザはそれぞれ WebKit Inspector Protocol(Safari)・CDP(Chrome DevTools Protocol)・Firefox Remote Debugging Protocol が異なりますが、Playwright・Puppeteer はその差を抽象化します。
9. Python デバッグ — pdb / pdbpp / ipdb / pudb / debugpy
Python には意外と多くのデバッガ選択肢があります。基本の pdb(docs.python.org/3/library/pdb.html)から始めましょう。
import pdb
def buggy(x, y):
pdb.set_trace() # または Python 3.7+ の breakpoint() ビルトイン
z = x / y
return z
buggy(10, 0)
breakpoint() ビルトインは環境変数 PYTHONBREAKPOINT でどのデバッガを起動するか変更できます(PYTHONBREAKPOINT=ipdb.set_trace など)。
pdbpp(github.com/pdbpp/pdbpp)は pdb のドロップイン代替で、syntax highlighting、sticky モード(現在の関数を常に上部表示)、tab completion を追加します。インストール後、単に import pdb; pdb.set_trace() だけで動作が自動で強化されます。
ipdb(github.com/gotcha/ipdb)は IPython ベースで、?、??、magic コマンドのような IPython 機能をデバッグセッションで使えます。
pudb(github.com/inducer/pudb)はターミナル GUI デバッガで、curses ベースの 4 分割画面(ソース・スタック・変数・コマンド)を提供します。X11 のない SSH セッションで最も人気の選択肢です。
rpdb(github.com/tamentis/rpdb)はリモートデバッガで、ネットワークソケットを通じて別マシンから attach できます。本番サーバに一時的に入る必要があるときに便利です。
debugpy(github.com/microsoft/debugpy)は VS Code のデフォルト Python デバッガバックエンドで、DAP プロトコルを通じて IDE と通信します。
# 本番環境で attach を待つ
import debugpy
debugpy.listen(("0.0.0.0", 5678))
debugpy.wait_for_client() # クライアントが attach するまでブロック
比較表:
| ツール | 使う場面 | 強み |
|---|---|---|
| pdb | 追加依存なしで即座に | ビルトイン、breakpoint() |
| pdbpp | ローカル単独利用 | 自動強化、sticky モード |
| ipdb | データ / ノートブック作業 | IPython 統合 |
| pudb | SSH・ターミナル環境 | フルスクリーン GUI |
| rpdb | 本番サーバ attach | リモートソケット |
| debugpy | IDE(VS Code) | DAP、マルチクライアント |
10. Bun 1.3 / Deno 2 / Node.js — JavaScript ランタイムのデバッグ
Bun(bun.sh)は 2024 年 9 月の 1.2 リリース以降 ビルトイン inspector が安定化し、2026 年 1 月の 1.3 で Chrome DevTools 以外に VS Code DAP 直接対応も追加されました。
# Bun: ビルトイン inspector を起動
bun --inspect index.ts
# 1 行目で停止
bun --inspect-brk index.ts
# 明示的ポート
bun --inspect=ws://0.0.0.0:6499 index.ts
Bun inspector は V8 inspector プロトコル互換ですが、独自の JavaScriptCore ベースなので一部のトレース形状が異なります。2026 年 4 月リリースの Bun 1.3.2 では source map 処理が大きく改善されました。
Deno 2(deno.com、2024 年 10 月に 1.0 互換 GA)は Chromium V8 の上にあるので、Node とほぼ同じ inspector が使えます。
deno run --inspect=0.0.0.0:9229 server.ts
deno run --inspect-brk server.ts
Node.js は最も成熟しています。
node --inspect index.js # デフォルト 9229
node --inspect-brk index.js # 1 行目で停止
node --inspect-port=9230 index.js # ポート明示
node --inspect=0.0.0.0:9229 index.js # 外部 attach を許可
chrome://inspect で Discover targets が有効ならば自動で発見されます。VS Code では launch.json に "type": "node" と書くだけで OK。
launch.json の例:
// launch.json(各フィールドは JSON。外部評価はされない)
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/index.js"
}
]
}
${workspaceFolder} は VS Code が評価する変数で、JS のテンプレートリテラルではありません。
11. Rust デバッグ — dbg! / cargo-flamegraph / tokio-console
Rust デバッグの最速ツールは dbg! マクロです。
fn calculate(x: i64, y: i64) -> i64 {
let intermediate = dbg!(x * 2); // stderr にファイル・行・値を出力
let result = dbg!(intermediate + y);
result
}
出力は [src/main.rs:2] x * 2 = 20 の形式で、println!("{:?}", expr) よりも多くの文脈を残せます。
本格的なデバッガとしては rust-gdb(GDB ラッパー)または rust-lldb を使います。両ラッパーは Rust 標準ライブラリの pretty-printer を自動で読み込むので、Vec<i32>、HashMap<K, V> のような型も読みやすく表示されます。
cargo build --profile=dev # デフォルト debug ビルド
rust-gdb target/debug/myapp
rust-lldb target/debug/myapp
tokio-console(github.com/tokio-rs/console)は Tokio ランタイム専用のデバッガで、実行中の非同期タスク・リソース・deadlock をリアルタイムで可視化します。
// Cargo.toml に tokio = { features = ["tracing"] }、console-subscriber を追加
fn main() {
console_subscriber::init();
// ...
}
別のターミナルで tokio-console を起動 → busy なタスク・ポーリング頻度・時間のかかるタスクが即座に見えます。Tokio ベースのサーバの deadlock・starvation デバッグに必須です。
cargo-flamegraph(github.com/flamegraph-rs/flamegraph)は perf / dtrace 上で動作するラッパーで、一行で flame graph を作ってくれます。
cargo flamegraph --bin myapp -- --some-arg
# flamegraph.svg が生成される
pprof-rs(github.com/tikv/pprof-rs)はインプロセス CPU プロファイラで、本番環境で Go の pprof と同じフォーマットで結果を export できます。
12. Go デバッグ — Delve(dlv)
Go の標準デバッガは Delve(github.com/go-delve/delve)です。GDB も動きますが、goroutine や channel のような Go 固有概念を十分理解できず、ほとんど使われません。2025 年に Go 1.23 / 1.24 と一緒に Delve 1.24 がリリースされ、generics デバッグが安定化しました。
# デバッグモードで実行
dlv debug ./cmd/server
# コンパイル済みバイナリを実行(debug シンボルが必須)
dlv exec ./server
# 実行中プロセスにアタッチ
dlv attach 12345
# コアダンプ解析
dlv core ./server core.12345
# remote モード(ヘッドレス)
dlv --listen=:2345 --headless --api-version=2 debug
Delve コマンド:
(dlv) break main.go:42
(dlv) break main.processRequest
(dlv) condition 1 r.UserID == 42 # 条件付きブレークポイント
(dlv) continue
(dlv) next
(dlv) step
(dlv) goroutines # 全 goroutine を見る
(dlv) goroutine 3 # goroutine 3 を選択
(dlv) bt
(dlv) print req.Body
(dlv) call myFunc(42) # 危険だが可能
VS Code の Go 拡張が Delve をバックエンドに使うので、GUI デバッグも自然です。2025 年からは GoLand も Delve を直接埋め込みます。
13. Java デバッグ — JFR + JMC + IntelliJ debugger
Java は JVM 標準プロトコル JDWP(Java Debug Wire Protocol) を持つので、IDE とデバッガの間が標準化されています。JDB CLI は deprecated となり、現実には IntelliJ IDEA・Eclipse・VS Code Java Pack が JDWP を通してデバッグします。
# JVM をデバッグモードで起動
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 -jar app.jar
# suspend=y にすると IDE が attach するまで止まる
性能・メモリデバッグには JFR(Java Flight Recorder) + JMC(JDK Mission Control) が標準です。JFR は JVM に内蔵された極めて軽量(< 2 % のオーバーヘッド)なプロファイラで、本番環境で常時オンにする事例が増えています。
# JFR 録画開始
jcmd <pid> JFR.start name=profile duration=60s filename=profile.jfr
# あるいは JVM 起動引数で
java -XX:StartFlightRecording=duration=60s,filename=profile.jfr -jar app.jar
# JMC で解析
jmc profile.jfr
JFR / JMC は GC pause、allocation hot path、lock contention、IO ボトルネックを一度に表示してくれるので、本番グレードの性能デバッグの事実上の標準です。
Java 11 から導入された Async Stack Traces は、CompletableFuture / リアクティブチェーンの非同期コールバックを仮想的につなぎ合わせて 1 本のスタックで見せます。Project Loom の Virtual Threads(Java 21+)はデバッガに新しい挑戦を投げかけ、IntelliJ 2025.1 から仮想スレッドを別パネルで可視化します。
14. データベースデバッグ — EXPLAIN ANALYZE とその仲間
サービス性能バグの半分はデータベースにあり、そのまた半分は誤ったクエリプランが原因です。PostgreSQL の EXPLAIN ANALYZE は実際の実行統計も一緒に出してくれる最強のデバッグコマンドです。
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT u.id, u.email, COUNT(o.id) AS orders
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.created_at > NOW() - INTERVAL '30 days'
GROUP BY u.id, u.email
ORDER BY orders DESC
LIMIT 100;
出力で注目すべきは Seq Scan vs Index Scan、Rows planned vs actual(差が大きいと統計が古い)、Buffers: shared hit / read(IO コスト)、Sort method: external merge(メモリ不足でディスクソート)のようなシグナルです。
pgBadger(pgbadger.darold.net)は PostgreSQL のスローログを解析して HTML レポートを生成し、pg_stat_statements 拡張は累積統計をリアルタイムで提供します。
MySQL には EXPLAIN FORMAT=JSON と 8.0+ の EXPLAIN ANALYZE があり、MySQL Performance Schema が累積統計を提供します。
ORM ユーザにとっては、ORM が生成する実際の SQL をロギングするのが第一のデバッグツールです。Hibernate の show_sql、Prisma の log: ['query']、Drizzle の logger: true、ActiveRecord の ActiveRecord::Base.logger がその入口です。
15. 分散システムのデバッグ — OpenTelemetry と構造化ログ
マイクロサービスではバグは一つのプロセスに留まりません。一つのリクエストが 5 〜 50 サービスを経由し、どこで何が失敗したかを追跡する必要がありますが、シングルノードのデバッガでは不可能です。
OpenTelemetry(opentelemetry.io)は分散トレーシング・ログ・メトリクスの事実上の標準 SDK です。コードにインストルメンテーションを一度仕込めば、すべての呼び出しが trace ID を共有しながら Jaeger、Tempo、Honeycomb、Datadog、New Relic などに送られます。
import { trace } from '@opentelemetry/api'
const tracer = trace.getTracer('my-service')
async function handleRequest(req: Request) {
return tracer.startActiveSpan('handleRequest', async (span) => {
span.setAttribute('user_id', req.userId)
try {
const result = await processRequest(req)
span.setStatus({ code: 1 }) // OK
return result
} catch (err) {
span.recordException(err as Error)
span.setStatus({ code: 2, message: (err as Error).message }) // ERROR
throw err
} finally {
span.end()
}
})
}
構造化ログ(Structured Logging) は同じ trace ID をキーに、すべてのサービスのログを 1 本に join できるようにします。JSON フォーマット(pino、winston、zap、logrus、slog)が標準で、Datadog Logs、Grafana Loki、Elastic Cloud がバックエンドです。
分散デバッグの最大の罠は clock skew です。2 ノードの時計が 50 ms ずれていると、因果関係が逆転して見えるトレースが出ます。なので OpenTelemetry は時計の代わりに trace context(span ID の親子関係)を使います。
16. eBPF デバッグ — bpftrace / BCC / Pixie
eBPF(ebpf.io)は Linux カーネルに安全にコードを注入できる技術で、デバッグ・観測・セキュリティの新標準になりつつあります。eBPF ベースのデバッグツールの魅力は 本番システムにコード変更なしで、ほぼゼロのオーバーヘッドで動く ことです。
bpftrace(bpftrace.org)は awk 風の 1-liner 言語で eBPF プログラムを書きます。
# すべての syscall::open 呼び出しを追跡
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }'
# Node.js プロセスがどのファイルを開くか
bpftrace -e 'tracepoint:syscalls:sys_enter_openat /comm == "node"/ { printf("%s\n", str(args->filename)); }'
# TCP 接続レイテンシ分布
bpftrace -e 'kprobe:tcp_v4_connect { @start[tid] = nsecs; } kretprobe:tcp_v4_connect /@start[tid]/ { @dur = hist(nsecs - @start[tid]); delete(@start[tid]); }'
BCC(github.com/iovisor/bcc)は Python・C で更に複雑な eBPF ツールを書くフレームワークで、opensnoop、execsnoop、tcpconnect のような既製ツールが同梱されます。
Pixie(pixielabs.ai、CNCF Sandbox)は Kubernetes で eBPF による自動観測・デバッグを提供します。エージェントをインストールするだけで、すべての HTTP・gRPC・MySQL・Postgres トラフィックが自動キャプチャされ、コード変更なしでデバッグできます。
Coroot(coroot.com)は eBPF + OpenTelemetry を組み合わせ、すべてのマイクロサービス間の呼び出し関係とレイテンシを自動でマッピングします。
17. メモリバグ — Valgrind / ASan / MSan / TSan / UBSan
C / C++ / Rust unsafe コードの永遠の敵は メモリ安全性バグ(use-after-free、double-free、buffer overflow、uninitialized read、data race)です。2026 年の標準はコンパイル時 Sanitizer + ランタイム Valgrind の組み合わせです。
Valgrind Memcheck(valgrind.org)は 30 年近い歴史を持つ動的分析器で、すべてのメモリアクセスを傍受して検証します。
valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all ./app
オーバーヘッドは 10 〜 50 倍と遅いですが、どんなコードも変更なしで動かせるという圧倒的な強みがあります。
ASan(AddressSanitizer) はコンパイル時オプション -fsanitize=address でビルドし、ランタイムオーバーヘッド約 2 倍で use-after-free・buffer overflow を捕まえます。
clang -fsanitize=address -g -O1 main.c -o app
./app
MSan(MemorySanitizer): 未初期化メモリ読み込みを検出(-fsanitize=memory)。
TSan(ThreadSanitizer): data race を検出(-fsanitize=thread)。マルチスレッドデバッグの必須ツール。
UBSan(UndefinedBehaviorSanitizer): 整数オーバーフロー、NULL 参照、不整列ポインタなど(-fsanitize=undefined)。
これら 4 つのサニタイザを CI パイプラインで高速テストスイートと一緒に常時オンにするのが 2026 年の標準慣行です。Chromium・Firefox・LLVM 自体が毎日 ASan・TSan ビルドを回しています。
18. パフォーマンスプロファイラ — perf / Instruments / VTune / pprof
性能バグもデバッグの一部です。速いコードを作る最速の道は 遅い場所を測定する ことです。
Linux perf(perf.wiki.kernel.org)はカーネルが内蔵するプロファイラで、ハードウェア PMC(Performance Monitoring Counter)にアクセスして CPU・キャッシュ・branch ミスを測定します。
# 関数別 CPU time 測定
perf record -g ./app
perf report
# Flame graph で可視化
perf record -F 99 -g ./app -- sleep 30
perf script | stackcollapse-perf.pl | flamegraph.pl > out.svg
Instruments(macOS、Xcode の一部)は Apple の標準プロファイラで、Time Profiler・Allocations・Leaks・Network・System Trace のようなテンプレートを提供します。
Intel VTune(intel.com/vtune)は Intel CPU 特化のプロファイラで、マイクロアーキテクチャ単位(cache miss、branch misprediction、vectorization opportunity)まで解析します。
pprof(github.com/google/pprof)は Google が作ったプロファイルフォーマット兼解析ツールで、Go のビルトイン runtime/pprof、Rust の pprof-rs、C++ の gperftools がすべて互換です。
import _ "net/http/pprof" // 自動で /debug/pprof エンドポイント追加
// 別のターミナルで
// go tool pprof -http=:8080 http://localhost:6060/debug/pprof/profile?seconds=30
19. DAP — Debug Adapter Protocol
複数のデバッガが存在するのに IDE 一つで全部扱える秘密が DAP(Debug Adapter Protocol)(microsoft.github.io/debug-adapter-protocol/)です。Microsoft が 2017 年に発表した標準で、JSON-RPC ベースで IDE とデバッガバックエンドを分離します。
標準メッセージは initialize、launch、attach、setBreakpoints、stackTrace、scopes、variables、evaluate、continue、next、stepIn、stepOut、terminate など。
DAP をサポートするクライアントは VS Code、Vim の vimspector、Neovim の nvim-dap、Emacs の dap-mode、JetBrains IDE、Sublime Text の Debugger など、ほぼすべてのモダンエディタです。バックエンドには debugpy(Python)、node inspector、delve(Go)、lldb-vscode(C / C++)、js-debug(Node / Chrome)などがあります。
VS Code の launch.json は本質的に DAP launch メッセージの引数です。クライアント(IDE)とバックエンド(言語別デバッガ)が標準プロトコルで分離されていることが DAP のコア価値です。
20. AI デバッグ — Claude Code / Cursor / Copilot Workspace
2025 〜 2026 年の最大の変化は AI コーディングエージェントのデバッグ能力 です。
Claude Code(claude.com/code)はターミナルベースのエージェントで、スタックトレース・ログ・テスト出力をそのまま貼り付ければ仮説を立て、コードを読み、修正案を提示します。2025 年の Claude 4.7 から Chrome DevTools MCP を通じて実際のブラウザデバッグも直接行えます。
Cursor(cursor.com)は VS Code fork で、インラインエラーメッセージに "Fix with AI" ボタンを提供します。2026 年の Cursor 1.0 ではデバッガセッション自体と統合され、ブレークポイントで停止した状態の変数の値を LLM が直接 inspect しながら仮説を生成します。
GitHub Copilot Workspace(githubnext.com/projects/copilot-workspace)はイシュー → コード変更 → PR 全体の流れを自動化する実験的プロダクトで、デバッグシナリオでは「このイシューを再現するテストを書いて直して」が可能です。
AI デバッグの限界も明確です。再現不可能なバグ(タイミング、環境依存)、巨大なコードベース全体の文脈、外部システム統合(データベース、外部 API)が必要なデバッグは依然として人間が主導しなければなりません。AI は仮説生成・コード読解・反復作業の自動化に強いですが、root cause の決定は最後まで人が行います。
21. リバースデバッグ — UDB / rr / Pernosco / TTD 比較
タイムトラベル・リバースデバッグツールを一覧で比較します。
| ツール | ベンダー | プラットフォーム | 価格 | 強み |
|---|---|---|---|---|
| rr | Mozilla(オープンソース) | Linux(Intel) | 無料 | Firefox・Chromium の標準 |
| Pernosco | Pernosco Inc. | Linux + クラウド | トレース毎課金 | クラウド omniscient |
| WinDbg TTD | Microsoft | Windows | 無料 | カーネルデバッグ |
| UDB | Undo.io | Linux | エンタープライズ | C++・Java 特化、AAA ゲーム |
UDB(undo.io)は英国ケンブリッジの Undo が作るエンタープライズ向けリバースデバッガで、EA・Riot Games・Bloomberg が利用します。rr より広い CPU・プラットフォーム対応と IDE 統合が強みです。
リバースデバッグが最も光るシナリオ:
- NULL ポインタ追跡:
watch *ptr+reverse-continue→ 誰が NULL を入れたか - 状態破壊: おかしな値が見えるとき、逆方向に行って誰が set したか
- 非決定的 deadlock: 一度録画すれば無限に再現できる
- テスト flakiness: CI でたまに失敗するテストの再現
22. Print デバッグを上手にやる方法
最も古く、最もよく使われ、最も過小評価されているデバッグツールは依然として print です。printf、console.log、eprintln!、dbg!、fmt.Println。これを上手に使う方法:
- 文脈を全部書く: 変数名、値、関数名、行番号を一緒に出力。Rust の
dbg!、Go のlog.Printf("[%s] x=%v", funcName, x)が模範。 - JSON 1 行(JSON Lines): 人間が読み、grep・jq で再解析できる。
console.log(JSON.stringify({ event: 'request', userId, latency }))。 - ログレベルを使う: trace / debug / info / warn / error。本番でオン・オフできるように。
- 相関 ID(Correlation ID): 一つのリクエストを追うすべてのログが同じ ID を共有。
console.dirvsconsole.log: オブジェクトを深く出力するならconsole.dir(obj, { depth: null })。- Rust の
tracingcrate: マクロで span・event を作り、OpenTelemetry で自動 export。
print デバッグの罠は ログ爆発 です。誤ってオンのまま忘れると、本番でディスクが埋まり、ログ料金が EC2 料金より大きくなります。環境変数でレベルを制御し、1 行ログでも cardinality(値のバリエーション)爆発に注意しましょう。
23. 韓国の事例 — クーパン / Naver / カカオ
クーパンの SRE 事後分析(Post-mortem)文化 は韓国 IT 業界でよく知られています。2021 年の AWS Tokyo リージョン障害で発生した部分的サービス停止以降、クーパンはすべての P0 / P1 インシデントについて英文 post-mortem を作成し、社内に公開する方針を定着させました。デバッグ面で強調されるのは タイムライン精度 と 5 Whys ベースの root cause 分析 です。
Naver D2 / SRE ブログ(d2.naver.com、tech-blog.naver.com)は Java・JVM・MySQL のデバッグ事例を長年公開してきました。特に 2024 年に公開された "Pinpoint 分散トレーサでマイクロサービス障害を追跡する" シリーズは、Naver 自社製トレーサ Pinpoint(github.com/pinpoint-apm/pinpoint、オープンソース)の実戦的な利用法を扱います。
カカオの 2022 年 10 月のデータセンター火災事案 は韓国 IT 史上最大のデバッグ・事後分析事例として残りました。データセンター一拠点の火災で、カオトーク・Daum・カカオ T のようなサービスが 5 〜 127 時間停止し、その後カカオはマルチ DC アクティブ-アクティブ構成、障害対応マニュアル全面改訂、分散トレーシング義務化のような変化をもたらしました。その過程とデバッグ教訓はカカオ Tech Blog(tech.kakao.com)で多年シリーズとして公開されました。
三社の共通点は 事後分析を資産にする文化 です。デバッグは個人の技術ではなく、組織の学習サイクルとして機能すべきだ、という韓国ビッグテックの共通メッセージです。
24. 日本の事例 — Cookpad / Mercari / はてな / HSAS
Cookpad Engineering Blog(techlife.cookpad.com)は日本で最も多く Ruby / Rails のデバッグ事例を公開しています。特に 2024 年シリーズ "rbtrace で本番 Ruby プロセスをデバッグする" は、Ruby の rbtrace(github.com/tmm1/rbtrace)と rbspy(github.com/rbspy/rbspy)を活用した無停止診断を扱います。
Mercari Engineering Blog(engineering.mercari.com/en/blog/)は Go・Kubernetes のデバッグ事例が豊富です。2025 年の "Debugging Goroutine Leaks at Mercari Scale" 投稿は、pprof + goleak を組み合わせた自動 leak 検知を扱います。
はてなエンジニアセミナー は日本のエンジニアリングカンファレンスの中で最も歴史のあるシリーズで、はてなの Perl・Go・TypeScript のデバッグノウハウが毎年公開されます。
HSAS(High School / University Security Audit Society) と日本のセキュリティコミュニティは、GDB・radare2・Ghidra などを使ったリバースエンジニアリング・exploit デバッグ領域でとても活発です。SECCON・DEF CON CTF の日本チームが使うデバッグワークフローは、システム・バイナリデバッグの最先端を示します。
25. 参考 / References
- Why Programs Fail(Zeller, 2009 / 2023 第 2 版) — 仮説駆動デバッグの正典
- GDB documentation —
https://sourceware.org/gdb/current/onlinedocs/gdb/ - GDB Python API —
https://sourceware.org/gdb/current/onlinedocs/gdb/Python.html - gdb-dashboard —
https://github.com/cyrus-and/gdb-dashboard - LLDB documentation —
https://lldb.llvm.org/ - LLDB Python reference —
https://lldb.llvm.org/python_reference/index.html - rr project —
https://rr-project.org/ - Pernosco —
https://pernos.co/ - WinDbg TTD —
https://learn.microsoft.com/windows-hardware/drivers/debugger/time-travel-debugging-overview - Chrome DevTools —
https://developer.chrome.com/docs/devtools/ - Chrome DevTools MCP —
https://github.com/ChromeDevTools/chrome-devtools-mcp - Firefox DevTools —
https://firefox-source-docs.mozilla.org/devtools-user/ - Safari Web Inspector —
https://webkit.org/web-inspector/ - Python pdb —
https://docs.python.org/3/library/pdb.html - pdbpp —
https://github.com/pdbpp/pdbpp - ipdb —
https://github.com/gotcha/ipdb - pudb —
https://github.com/inducer/pudb - debugpy —
https://github.com/microsoft/debugpy - Bun docs —
https://bun.sh/docs/runtime/debugger - Deno docs —
https://docs.deno.com/runtime/manual/basics/debugging_your_code - Node.js inspector —
https://nodejs.org/api/debugger.html - Delve —
https://github.com/go-delve/delve - tokio-console —
https://github.com/tokio-rs/console - cargo-flamegraph —
https://github.com/flamegraph-rs/flamegraph - pprof-rs —
https://github.com/tikv/pprof-rs - JDK Mission Control —
https://www.oracle.com/java/technologies/jdk-mission-control.html - Java Flight Recorder —
https://docs.oracle.com/en/java/javase/21/jfapi/ - OpenTelemetry —
https://opentelemetry.io/ - bpftrace —
https://bpftrace.org/ - BCC —
https://github.com/iovisor/bcc - Pixie —
https://github.com/pixie-io/pixie - Coroot —
https://coroot.com/ - Valgrind —
https://valgrind.org/ - AddressSanitizer —
https://github.com/google/sanitizers/wiki/AddressSanitizer - ThreadSanitizer —
https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual - Linux perf —
https://perf.wiki.kernel.org/ - pprof —
https://github.com/google/pprof - Debug Adapter Protocol —
https://microsoft.github.io/debug-adapter-protocol/ - Pinpoint APM —
https://github.com/pinpoint-apm/pinpoint - Cookpad Techlife —
https://techlife.cookpad.com/ - Mercari Engineering —
https://engineering.mercari.com/en/blog/ - カカオ Tech Blog —
https://tech.kakao.com/