デバッグ: 犯人捜し

「動かない」で止まるな。「なぜ」を突き止めろ。最強の武器 ASan と GDB を授ける。

デバッグ
バグ(不具合)の原因を特定し、修正する作業。
GDB
GNU Debugger。プログラムを一時停止したり、変数の値を見たりできる強力なツール。
AddressSanitizer (ASan)
メモリ破壊やリークを自動で検知してくれる神ツール。コンパイル時にオプションを入れるだけで使える。
鑑識捜査 (CSI: Code Scene Investigation)

デバッグは「犯行現場(クラッシュ)の捜査」です。 `printf`デバッグは、通りすがりの人に「何か見ましたか?」と聞き回るようなもので、手間がかかる上に嘘をつかれることもあります。 一方、デバッガ(GDB)は「時間を止めて現場を検証する能力」、サニタイザ(ASan)は「犯行の瞬間にアラームを鳴らす防犯カメラ」です。 文明の利器(ツール)を使えば、犯人(バグ)はすぐに確保できます。

Printfデバッグの限界

「とりあえず printf を入れまくる」のは、小規模なら有効ですが、大規模なバグやメモリ破壊(変な値になる、たまに落ちる)には無力です。

プロは**デバッガ (GDB)** と **サニタイズ (Sanitizer)** を使います。これは「犯行現場をビデオ判定する」ようなもので、犯人(バグ)を現行犯逮捕できます。

最強ツール: AddressSanitizer

Googleが開発したツールです。使い方は驚くほど簡単で、コンパイル時にオプションを追加するだけです。

Using ASan
# AddressSanitizer (The Magic Wand)
# Just add -fsanitize=address
gcc -g -fsanitize=address main.c -o app
./app
# If a bug exists, it will print a colorful error report!
ヒント: Segfault(セグメンテーション違反)が起きたら、まずこれを試してください。9割解決します。

GDBの基本

プログラムを一時停止し、変数の宇宙を覗き見るツールです。

GDB Cheatsheet
# GDB (Detective Tool)
gcc -g main.c -o app # -g is MUST!
gdb ./app
(gdb) run # Start execution
(gdb) bt # Backtrace (See where it crashed)
(gdb) print x # Inspect variable x
(gdb) quit # Exit

実践テクニック

デバッグ情報の付加 (-g)

コンパイル時に <code>-g</code> をつけないと、GDBを使っても「行番号」や「変数名」が表示されません。開発中はつけっぱなしでOKです。

演習課題

課題1: ASan体験
わざと範囲外アクセスをするプログラム (arr[100] = 1;) を書き、普通に実行した場合と ASan付きで実行した場合の違いを確認してください。

合格ライン

-fsanitize=address の偉大さを知っている
コンパイル時に -g をつける癖がついている