Address Sanitizer を使用したメモリ破損のデバッグ

このドキュメントでは、AGDE を使用する際に特別なデバッグツールを有効にする方法について説明します。これらのツールは、診断が困難なメモリの破損や上書きのエラーに対して活用できます。

HWAddress Sanitizer と Address Sanitizer

HWAddress Sanitizer(HWASan)と Address Sanitizer(ASan)は、次のようなメモリの破損と上書きのエラーをデバッグする際に活用できるデバッグツールです。

  • スタック バッファのオーバーフローとアンダーフロー
  • ヒープバッファのオーバーフローとアンダーフロー
  • スコープ外でのスタックの使用
  • 二重解放とワイルド解放のエラー
  • 返却後のスタック使用(HWASan のみ)

問題をデバッグする場合や自動テストの一環として使用する場合にのみ、HWASan や ASan を有効にすることをおすすめします。これらのツールは高性能ですが、使用するとデメリットもあります。

ランタイムの動作

HWASan や ASan を有効にすると、いずれもアプリのランタイム全体のメモリ破損を自動的にチェックします。

メモリエラーが検出されると、アプリは SIGBART(シグナルの中断)エラーでクラッシュし、logcat に詳細なメッセージが出力されます。メッセージのコピーも /data/tombstones の下のファイルに書き込まれます。

次のようなエラー メッセージが表示されます。

ERROR: HWAddressSanitizer: tag-mismatch on address 0x0042a0826510 at pc 0x007b24d90a0c
WRITE of size 1 at 0x0042a0826510 tags: 32/3d (ptr/mem) in thread T0
    #0 0x7b24d90a08  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x2a08)
    #1 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)
    #2 0x7b8f1db364  (/apex/com.android.art/lib64/libart.so+0x18f364)
    #3 0x7b8f2ad8d4  (/apex/com.android.art/lib64/libart.so+0x2618d4)

0x0042a0826510 is located 0 bytes to the right of 16-byte region [0x0042a0826500,0x0042a0826510)
allocated here:
    #0 0x7b92a322bc  (/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so+0x212bc)
    #1 0x7b24d909e0  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x29e0)
    #2 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)

前提条件

Android OS の HWASan ビルドをインストールする

Google Pixel デバイスで HWASan を使用するには、HWASan ドキュメントの設定手順に沿って、Google Pixel デバイス用 Android OS の HWASan ビルドをインストールします。

その他のデバイスの場合は、メーカーに問い合わせて、可能であれば OS の HWASan ビルドを入手するか、ソフトウェアのみの ASan ツールを使用してください。

プロジェクトで共有 C++ 標準ライブラリを使用する

既知の問題により、ASan は、libc++_static を使用した場合に発生する C++ の例外の処理には対応していません。libc++_shared を使用している場合、この問題は発生しません。

HWASan には演算子 newdelete が独自に実装されていますが、標準ライブラリがプロジェクトに静的にリンクされている場合は使用できません。

この設定を変更するには、このドキュメントの「C++ 標準ライブラリをリンクする」セクションをご覧ください。

フレーム ポインタ生成を有効にする

HWASan と ASan は、フレーム ポインタに基づく高速アンワインダーを使用して、メモリの割り当てイベントと割り当て解除イベントのスタック トレース情報を生成します。これらの機能を使用するには、C++ コンパイラ設定でフレーム ポインタ生成を有効にする必要があります。すなわち、フレーム ポインタの省略の最適化を無効にする必要があります。

この設定を変更するには、このドキュメントの「フレーム ポインタ生成を有効にする」セクションをご覧ください。

HWASan または ASan を使用するように Visual Studio プロジェクトを設定する

HWASan または ASan を有効にする

HWASan または ASan を有効にするには、プロジェクトの [プロパティ] ページ[構成のプロパティ] > [全般] に移動します。

現在のプロジェクトに関する Visual Studio Solution Explorer の [プロパティ] メニュー。

図 1: Visual Studio Solution Explorer ウィンドウでの対象プロジェクトの [プロパティ] オプション

[全般] プロパティが表示され、[Address Sanitizer] 設定がハイライト表示されている、対象プロジェクトの [プロパティ] ページ ダイアログ。

図 2: [全般] プロジェクト プロパティの [Address Sanitizer(ASan)] 設定

プロジェクトで HWASan を有効にするには、[Address Sanitizer(ASan)] 設定を [ハードウェア ASan を有効にする(fsanitize=hwaddress)] に変更します。

プロジェクトで ASan を有効にするには、[Address Sanitizer(ASan)] 設定を [ASan を有効にする(fsanitize=address)] に変更します。

フレーム ポインタ生成を有効にする

フレーム ポインタの生成は、[フレーム ポインタを省略] の C/C++ コンパイラ設定で管理します。内容は、プロジェクトの [プロパティ] ページ[構成のプロパティ] > [C/C++] > [最適化])で確認できます。

[C/C++ 最適化] プロパティが表示され、[フレーム ポインタを省略] 設定がハイライトされている対象プロジェクトの [プロパティ] ページ ダイアログ。

図 3: [フレーム ポインタを省略] 設定を確認できる場所

HWASan または ASan を使用する場合は、[フレーム ポインタを省略] 設定を [いいえ(-fno-omit-frame-pointer)] に設定します。

共有ライブラリ モードで C++ 標準ライブラリをリンクする

C++ 標準ライブラリのリンカーモード設定は、プロジェクトの [プロパティ] ページ([プロジェクトのデフォルト] セクションの [構成のプロパティ] > [全般])で確認できます。

[全般] カテゴリが選択され、[STL の使用] 設定がハイライト表示されている対象プロジェクトの [プロパティ] ページ ダイアログ。

図 4: C++ 標準ライブラリのリンカーモード設定を確認できる場所

HWASan または ASan を使用する場合は、[STL の使用] を [C++ 標準ライブラリ(.so)を使用] に設定します。この設定にすると、C++ 標準ライブラリが共有ライブラリとしてプロジェクトにリンクされます。HWASan と ASan が正しく機能するために必要な設定です。

Address Sanitizer で使用するビルド構成を作成する

HWASan または ASan を一時的に使用するだけの場合は、そのために新たなビルド構成を作成するのがためらわれる場合があります。たとえば、プロジェクトが小規模の場合、機能を調査している場合、またはテスト中に見つかった問題に対応しようとしている場合などが考えられます。

ただし、HWASan または ASan が有効で、定期的に使用する場合は、Teapot サンプルに示すように、HWASan または ASan 用に新しいビルド構成を作成することを検討してください。たとえば、単体テストの一環として、または夜間にゲームのスモークテストを実施する際に、Address Sanitizer を定期的に実行する場合などには新しいビルド構成を作成します。

多数のサードパーティ ライブラリを使用する大規模なプロジェクトがあり、通常、それらのライブラリを C++ 標準ライブラリに静的にリンクする場合は、個別のビルド構成を作成することが非常に有効な場合があります。専用のビルド構成を使用すると、常に正確なプロジェクト設定を維持できます。

ビルド構成を作成するには、プロジェクトの [プロパティ] ページで [構成マネージャー…] ボタンをクリックし、[アクティブなソリューションの構成] プルダウンを使用します。次に、 を選択し、適切な名前(例: HWASan 有効化用)で新しいビルド構成を作成します。