Известные проблемы и ограничения AddressSanitizer

Примечание.

Отправьте нам отзыв о том, что вы хотите увидеть в будущих выпусках, и сообщите об ошибках при возникновении проблем.

Несовместимые параметры и функциональные возможности

Следующие параметры и функциональные возможности несовместимы и /fsanitize=address должны быть отключены или избегать.

Поддержка стандартной библиотеки

Стандартная библиотека Microsoft Visual C++ (MSVC) частично использует AddressSanitizer и предоставляет другие проверки безопасности кода. Дополнительные сведения см. в разделе container-overflow об ошибке.

Если заметки отключены или в версиях стандартной библиотеки, которые не поддерживают их, исключения AddressSanitizer, создаваемые в коде STL, по-прежнему определяют реальные ошибки. Однако они более точны, если заметки включены, и вы используете версию стандартной библиотеки, которая поддерживает их.

В этом примере демонстрируется отсутствие точности и преимущества включения заметок:

// 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 или / переопределяет в других библиотеках пользовательские версии ASandeleteoperator newoperator delete. В этом случае ASan может не перехватывать некоторые ошибки, основанные на его пользовательском operator new и operator delete.

MFC включает пользовательские переопределения для operator new и operator delete. Если переопределения классов Microsoft Foundation (MFC) используются вместо предоставленного operator new ASan, а operator deleteASan может полностью пропустить ошибки или классифицировать их неправильно в результате. Следующие ошибки могут быть пропущены или неправильно классифицированы:

Использование памяти

Среда выполнения AddressSanitizer не освобождает память в ОС во время выполнения, чтобы память не была выделена заранее. С точки зрения ОС это может выглядеть так, как утечка памяти.

Расположения DLL среды выполнения AddressSanitizer

Файлы 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 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 может не диагностировать все ошибки безопасности памяти. Наиболее распространенным примером является загрузка библиотеки DLL, скомпилированной с помощью ASan, в процесс, содержащий код, не скомпилированный с помощью ASan. В этом случае ASan пытается классифицировать выделения, которые произошли до инициализации ASan. После перераспреждения этих выделений ASan пытается владеть и отслеживать время существования памяти.

Если все библиотеки DLL, скомпилированные с помощью ASan, выгружаются из процесса до завершения процесса, могут возникать сбои из-за перехваченных ссылок на перехваты таких функций, как memcmp, memcpymemmoveи т. д. Для получения наилучших результатов скомпилируйте все модули под тестом или не выгрузите модули, скомпилированные /fsanitize=addressс помощью ASan после ввода процесса.

Сообщите о любых ошибках в нашем сообществе разработчиков.

Исключения первого шанса ASan 64-разрядной версии

В регионе теневых байтов MSVC ASan занимает несколько терабайтов виртуального адресного пространства. ASan не фиксирует эту память перед фиксацией. Вместо этого он использует разбиение по запросу. При первом доступе к теневой странице возникает исключение сбоя первой случайной страницы и обрабатывается ASan, которая фиксирует страницу.

Отладчик Visual Studio обрабатывает это корректно и не отображает эти трассировки. Однако отладчики, такие как WinDbgX, могут прерывать все исключения по умолчанию. Рекомендуется отключить критические исключения первого шанса. Например, в WinDbgX это соответствует команде sxd av .

См. также

Обзор AddressSanitizer
Справочник по сборке и языку AddressSanitizer
Справочник по среде выполнения AddressSanitizer
Теневой байт AddressSanitizer
Облачное или распределенное тестирование AddressSanitizer
Интеграция отладчика AddressSanitizer
Примеры ошибок AddressSanitizer