Поделиться через


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

Примечание.

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

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

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

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

Стандартная библиотека MSVC (STL) частично использует AddressSanitizer и предоставляет другие проверки безопасности кода. Дополнительные сведения см. в статье об ошибке переполнения контейнеров.

Если заметки отключены или в версиях стандартной библиотеки, которые не поддерживают их, исключения 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;
}

Переопределение оператора new and delete

AddressSanitizer (ASAN) использует пользовательскую версию operator new и operator delete для поиска ошибок выделения, таких как alloc_dealloc_mismatch. Запуск компоновщика с /INFERASANLIBS гарантирует, что new/delete переопределение ASAN имеет низкий приоритет, чтобы компоновщик выбрал любые operator new или operator delete переопределяется в других библиотеках по пользовательским версиям ASAN. В этом случае ASAN может не перехватывать некоторые ошибки, основанные на пользовательских operator new и operator delete.

MFC включает пользовательские переопределения для operator new и operator delete может пропустить такие alloc_dealloc_mismatchошибки.

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

Среда выполнения 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 Address Sanitizer (<EnableASAN>), сборка не учитывает ее. Это связано с тем, что пользовательские .props файлы включены после Microsoft.cpp.propsэтого, что использует <EnableASAN> значение для задания других свойств.

В качестве обходного решения создайте Directory.Build.props файл в корне проекта для определения <EnableASAN> свойства. Дополнительные сведения см. в разделе "Настройка сборок C++".

Локальные переменные потока

Локальные переменные потока (глобальные переменные, объявленные с __declspec(thread) помощью Или thread_local) не защищаются адресом AddressSanitizer. Это ограничение не зависит от Windows или Microsoft Visual C++, но является общим ограничением.

Проблемы с частично санируемыми исполняемыми файлами

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

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

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

См. также

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