互換性のないオプションと機能
次のオプションと機能は、 /fsanitize=address と互換性がありません。無効または回避する必要があります。
-
/RTCオプションは AddressSanitizer と互換性がないため、無効にする必要があります。 - インクリメンタル リンクはサポートされていないため、無効にする必要があります。
- エディットコンティニュ はサポートされていないため、無効にする必要があります。
- コルーチンは AddressSanitizer と互換性がなく、再開可能な関数がインストルメンテーションから除外されています。
- OpenMP はサポートされていないため、無効にする必要があります。
- マネージド C++ はサポートされていないため、無効にする必要があります。
- C++ AMP はサポートされていないため、無効にする必要があります。
- ユニバーサル Windows プラットフォーム (UWP) アプリケーションはサポートされていません。
- 特別なケース リスト ファイルはサポートされていません。
-
/fsanitize=addressなしでビルドされたプリコンパイル済みヘッダーはサポートされていません。
標準ライブラリのサポート
Microsoft Visual C++ (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;
}
operator newのオーバーライドとdelete
AddressSanitizer (ASan) は、 operator new と operator delete のカスタム バージョンを使用して、 alloc_dealloc_mismatchなどの割り当てエラーを見つけます。
/INFERASANLIBSを使用してリンカーを実行して、ASan のnew/deleteオーバーライドの優先順位が低くなり、リンカーが ASan のカスタム バージョンよりも他のライブラリでoperator newまたはoperator deleteオーバーライドを選択できるようにします。 この場合、ASan はカスタム operator new と operator deleteに依存するいくつかのエラーをキャッチしない可能性があります。
MFC には、 operator new と operator deleteのカスタム オーバーライドが含まれています。 ASan が提供する operator new と operator deleteの代わりに Microsoft Foundation Classes (MFC) オーバーライドを使用すると、エラーが完全に見落とされたり、結果として誤って分類されたりする可能性があります。 次のエラーが見落とされたり、誤って分類されたりする可能性があります。
alloc_dealloc_mismatchdouble-freeheap-use-after-freeheap-buffer-overflownew-delete-type-mismatch
メモリ使用量
AddressSanitizer ランタイムは、メモリがすべて前もって割り当てられないように、実行中にメモリを OS に解放しません。 OS の視点から見ると、メモリ リークが発生しているように見えるかもしれません。
AddressSanitizer ランタイム DLL の場所
clang_rt.asan*.dll ランタイム ファイルは、コンパイラの横の %VSINSTALLDIR%\VC\Tools\MSVC\<version>\bin\<host-arch>\<target-arch>\ にインストールされます。 これらの場所は、デバッグ セッションと Visual Studio 開発者コマンド プロンプトのパスにあります。 これらのファイルは、C:\Windows\System32 や C:\Windows\SysWOW64 には置かれません。
カスタム プロパティ シートのサポート
Visual Studio プロパティ マネージャー ウィンドウでは、カスタム .props ファイルをプロジェクトに追加できます。
[AddressSanitizer の有効化] プロパティ (<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 がプロセスの終了前にプロセスからアンロードされた場合、 memcmp、 memcpy、 memmoveなどのインターセプトされた関数への未解決の参照が原因でクラッシュする可能性があります。 最適な結果を得るには、 /fsanitize=addressでテスト対象のすべてのモジュールをコンパイルするか、プロセスに入った後に ASan でコンパイルされたモジュールをアンロードしないでください。
開発者コミュニティにバグを報告してください。
ASan 64 ビットの最初の確率例外
x64 では、MSVC ASan の シャドウ バイト 領域は数テラバイトの仮想アドレス空間を占有します。 ASan では、このメモリは事前コミットされません。 代わりに、オンデマンドページングが使用されます。 シャドウ ページに初めてアクセスすると、初回のページ フォールト例外が発生し、ページをコミットする ASan によって処理されます。
Visual Studio デバッガーはこれを適切に処理し、これらのトレースは表示しません。 ただし、WinDbgX などのデバッガーは、既定ではすべての例外で中断される可能性があります。 初回例外の中断を無効にすることをお勧めします。 たとえば、WinDbgX では、これは sxd av コマンドに対応します。
関連項目
AddressSanitizer の概要
AddressSanitizer のビルドと言語リファレンス
AddressSanitizer ランタイム リファレンス
AddressSanitizer シャドウ バイト
AddressSanitizer クラウドまたは分散テスト
AddressSanitizer デバッガーの統合
AddressSanitizer エラーの例