デバッグ: 犯人捜し
「動かない」で止まるな。「なぜ」を突き止めろ。最強の武器 ASan と GDB を授ける。
デバッグ
バグ(不具合)の原因を特定し、修正する作業。
GDB
GNU Debugger。プログラムを一時停止したり、変数の値を見たりできる強力なツール。
AddressSanitizer (ASan)
メモリ破壊やリークを自動で検知してくれる神ツール。コンパイル時にオプションを入れるだけで使える。
Printfデバッグの限界
「とりあえず printf を入れまくる」のは、小規模なら有効ですが、大規模なバグやメモリ破壊(変な値になる、たまに落ちる)には無力です。
プロは**デバッガ (GDB)** と **サニタイズ (Sanitizer)** を使います。これは「犯行現場をビデオ判定する」ようなもので、犯人(バグ)を現行犯逮捕できます。
最強ツール: AddressSanitizer
Googleが開発したツールです。使い方は驚くほど簡単で、コンパイル時にオプションを追加するだけです。
# AddressSanitizer (The Magic Wand)# Just add -fsanitize=addressgcc -g -fsanitize=address main.c -o app
./app# If a bug exists, it will print a colorful error report! ヒント: Segfault(セグメンテーション違反)が起きたら、まずこれを試してください。9割解決します。
GDBの基本
プログラムを一時停止し、変数の宇宙を覗き見るツールです。
# 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 をつける癖がついている