AddressSanitizer がプチブームなので乗ってみる

⚠️ご注意

このサイトでは、想定読書にあわせた簡易的な内容のみ記載しています。よって、プロフェッショナルな人向けではありません。

AddressSanitizer って何者?

このサイトでは、『メモリ関連のバグを発見してくれる便利やヤツ』という、ふわっとした扱いに留めます。
「AddressSanitizer」や「アドレスサニタイザ」でネット検索すれば、大量に情報があります。正しいことは、他のサイトで勉強してください。(無責任・・・)

どうやって発見してくれるの?

AddressSanitizerを有効にした状態で作られたプログラムを実行し、かつ、メモリに関する問題を発見した時に診断ログが出てきて教えてくれる。

どうやって有効にするの?

コンパイルオプション(-fsanitize=address)を指定して有効にする。
※コンパイラ自身が対応している必要あり
※Xcode上のGUIで有効にした場合は別のオプション(-D_LIBCPP_HAS_NO_ASAN)も自動追加される

どんな事象を発見できるの?

-fsanitize=address で発見できるのは以下のような内容
・ヒープ領域における定義済領域以外への操作(heap-buffer-overflow
・グローバル領域における定義済領域以外への操作(global-buffer-overflow
・スタック領域における定義済領域以外への操作(stack-buffer-overflow
・重複領域に対するmemcpy(memcpy-param-overlap
・多重解放(double-free
・解放済みヒープ領域への操作(heap-use-after-free
・mallocされていない領域のfree、もしくは、newされていない領域のdelete(attempting free on address which was not malloc()-ed
・ローカル変数に対するスコープ外からの操作(stack-use-after-scope
・ローカル変数に対する関数外からの操作(stack-use-after-return

⚠️ご注意

Androidの場合は、普通の市販端末環境下では使うことができず、root化環境もしくは、シミュレータ環境が必須のようだ。(※2019/12/18 訂正:NDKのドキュメントによると、Android 8.1以降ならば実機でもサポートするようになったらしい)

⚠️ご注意

stack-use-after-return の検出には、動的オプションの指定(ASAN_OPTIONS=detect_stack_use_after_return=1)が必須。

プログラム中で環境変数をセットしても効果なし。起動前にセットする必要あり

iPhoneの場合はXcode上の設定で「Detect use of stack after return」にチェックを入れた状態でデバッグ実行する必要あり。

どんな結果が得られるの?

発見するたびに毎回リセット(クラッシュ)するけど続行できないの?

(※2018/10/15 追加)
コンパイル時に、コンパイルオプション(-fsanitize-recover=address) をつけ、かつ、実行時オプションとして、ASAN_OPTIONS=halt_on_error=0 を指定すると良いようだ。

⚠️ご注意

Xcode 10 & iPhone 12.0.1(実機)の組み合わせにおいて、ASAN_OPTIONS を指定しなくてもコンパイルオプションの追加だけで、続行できるようになった実績があるが、バージョン依存かもしれない
※iPhone実機の場合は、そもそも実行時オプションを指定する手段がないので、デフォルト設定が他とは変更されているのかも??

【まとめ】

・AddressSanitizer はコンパイラの機能で『メモリ関連のバグを発見してくれる便利やヤツ』
・10種類くらいの事象を発見してくれる
・使える環境と使えない環境があるっぽい(コンパイラのバージョン依存とかAndroidの実機だと不能とか)
・レポートが出るだけなので、レポートを理解して自分で修正する必要あり
・発見するたびに止まらないようにするコンパイルオプションがある(※2018/10/15 追加)

コメントを残す

メールアドレスが公開されることはありません。