次の方法で共有


AddressSanitizer の既知の問題と制限事項

今後のリリースで期待する内容に関するフィードバックをお送りください。また、問題にぶつかった場合はバグを報告してください。

互換性のないオプションと機能

次のオプションと機能は、 /fsanitize=address と互換性がありません。無効または回避する必要があります。

標準ライブラリのサポート

MSVC 標準ライブラリ (STL) は AddressSanitizer を部分的に使用し、他のコードの安全性チェックを提供します。 詳細については、 container-overflow エラーを参照してください。

注釈が無効になっている場合、またはそれらをサポートしていない標準ライブラリのバージョンでは、STL コードで発生した AddressSanitizer 例外によって、実際のバグが引き続き識別されます。 ただし、注釈が有効になっていて、それらをサポートする標準ライブラリのバージョンを使用している場合は、より正確です。

この例では、精度の欠如と注釈を有効にする利点を示します。

// Compile with: cl /fsanitize=address /Zi
#include <vector>

int main() {   
    // Create a vector of size 10, but with a capacity of 20.    
    std::vector<int> v(10);
    v.reserve(20);

    // In versions prior to 17.2, MSVC ASan does NOT raise an exception here.
    // While this is an out-of-bounds write to 'v', MSVC ASan
    // ensures the write is within the heap allocation size (20).
    // With 17.2 and later, MSVC ASan will raise a 'container-overflow' exception:
    // ==18364==ERROR: AddressSanitizer: container-overflow on address 0x1263cb8a0048 at pc 0x7ff6466411ab bp 0x005cf81ef7b0 sp 0x005cf81ef7b8
    v[10] = 1;

    // Regardless of version, MSVC ASan DOES raise an exception here, as this write
    // is out of bounds from the heap allocation.
    v[20] = 1;
}

演算子 new と delete のオーバーライド

AddressSanitizer (ASan) は、 operator newoperator delete のカスタム バージョンを使用して、 alloc_dealloc_mismatchなどの割り当てエラーを見つけます。 /INFERASANLIBSを使用してリンカーを実行すると、ASan のnew/deleteオーバーライドの優先順位が低くなります。これにより、リンカーは、ASan のカスタム バージョンよりも他のライブラリのoperator newまたはoperator deleteオーバーライドを選択できます。 この場合、ASan はカスタム operator newoperator deleteに依存するいくつかのエラーをキャッチできない可能性があります。

MFC には、 operator newoperator delete のカスタム オーバーライドが含まれており、 alloc_dealloc_mismatchなどのエラーが見逃される可能性があります。

メモリ使用量

AddressSanitizer ランタイムは、メモリがすべて前もって割り当てられないように、実行中にメモリを OS に解放しません。 OS の視点から見ると、メモリ リークが発生しているように見えるかもしれません。

AddressSanitizer ランタイム DLL の場所

clang_rt.asan*.dll ランタイム ファイルは、コンパイラの横の %VSINSTALLDIR%\VC\Tools\MSVC\<version>\bin\<host-arch>\<target-arch>\ にインストールされます。 これらの場所は、デバッグ セッションと Visual Studio 開発者コマンド プロンプトのパスにあります。 これらのファイルは、C:\Windows\System32C:\Windows\SysWOW64 には置かれません。

カスタム プロパティ シートのサポート

Visual Studio プロパティ マネージャー ウィンドウでは、カスタム .props ファイルをプロジェクトに追加できます。 Enable Address Sanitizer プロパティ (<EnableASAN>) が表示されていても、ビルドではこのプロパティは使用されません。 .props値を使用して他のプロパティを設定するMicrosoft.cpp.propsの後にカスタム <EnableASAN> ファイルが含まれるため、ビルドではこれを優先しません。

回避策として、プロジェクトのルートに Directory.Build.props ファイルを作成し、 <EnableASAN> プロパティを定義します。 詳細については、「C++ ビルドのカスタマイズ」を参照してください。

スレッド ローカル変数

スレッド ローカル変数 ( __declspec(thread) または thread_local で宣言されたグローバル変数) は AddressSanitizer によって保護されません。 この制限は、Windows または Microsoft Visual C++ に固有のものではなく、一般的な制限事項です。

カスタム コードは、通常の関数の戻りシーケンスをスキップします

カスタム コードまたはアセンブリ言語を使用して、通常の戻りメカニズムを受け入れずに現在のスタック フレームから離れることはサポートされていません。 たとえば、長いジャンプで現在のスタック フレームを離れると、誤検知が発生する可能性があります。

代わりに、カスタムのジャンプのようなコードを呼び出す前に、 __asan_handle_no_return() を呼び出します。 この関数は、現在のスレッドのスタックに関連付けられているすべてのシャドウ バイトをクリアします。これにより、カバレッジが失われ、偽陰性のリスクが発生します。 ただし、古いスタック シャドウ バイトが原因で誤検知が発生することなく、プログラムはスタックを安全にアンワインドできます。

部分的にサニタイズされた実行可能ファイルに関する問題

プロセス内のすべてのコードが /fsanitize=addressでコンパイルされていない場合、ASan はすべてのメモリセーフ エラーを診断できない可能性があります。 最も一般的な例は、ASan でコンパイルされた DLL が、ASan でコンパイルされていないコードを含むプロセスに読み込まれる場合です。 この場合、ASan は、ASan 初期化の前に行われた割り当ての分類を試みます。 これらの割り当てが再割り当てされると、ASan はメモリの有効期間を所有および監視しようとします。

ASan でコンパイルされたすべての DLL がプロセスの終了前にプロセスからアンロードされた場合、 memcmpmemcpymemmoveなどのインターセプトされた関数への未解決の参照が原因でクラッシュする可能性があります。 最適な結果を得るには、 /fsanitize=addressでテスト対象のすべてのモジュールをコンパイルするか、プロセスに入った後に ASan でコンパイルされたモジュールをアンロードしないでください。

開発者コミュニティにバグを報告してください。

関連項目

AddressSanitizer の概要
AddressSanitizer のビルドと言語リファレンス
AddressSanitizer ランタイム リファレンス
AddressSanitizer シャドウ バイト
AddressSanitizer クラウドまたは分散テスト
AddressSanitizer デバッガーの統合
AddressSanitizer エラーの例