Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Обзор
Языки C и C++ являются мощными, но могут страдать от класса ошибок, влияющих на правильность программы и безопасность программы. Начиная с Visual Studio 2019 версии 16.9 компилятор Microsoft C/C++ (MSVC) и интегрированная среда разработки поддерживают AddressSanitizer санитеризатор. AddressSanitizer (ASan) — это технология компилятора и среды выполнения, которая обнаруживает множество трудно обнаруживаемых ошибок без ложных срабатываний:
-
Несоответствия (alloc/dealloc) и
new - Выделения слишком большие для кучи
-
callocпереполнение иallocaпереполнение - Двойное освобождение и использование после освобождения
- Переполнение глобальной переменной
- Переполнение буфера кучи
- Недопустимое выравнивание выровненных значений
-
memcpyиstrncatперекрытие параметров - Переполнение буфера стека и недостаточное заполнение
-
Использование стека после
returnи использование после выхода из области видимости - Использование памяти после её заражения
Почему используйте AddressSanitizer
Используйте AddressSanitizer, чтобы сократить время, затраченное на:
- Базовая правильность
- Кроссплатформенная переносимость
- Безопасность
- Стресс-тестирование
- Интеграция нового кода
AddressSanitizer, первоначально представленный Google, предоставляет технологии обнаружения ошибок во время выполнения, которые используют существующие системы сборки и существующие тестовые ресурсы напрямую.
Создание интеграции и совместимости
AddressSanitizer интегрирован с системой проектов Visual Studio, системой сборки CMake и интегрированной среды разработки. Проекты могут включить AddressSanitizer, задав свойство проекта или используя один дополнительный параметр компилятора: /fsanitize=address Этот параметр совместим со всеми уровнями оптимизации и конфигурации x86 и x64. Однако он не совместим с изменением и продолжением, добавочным связыванием и /RTC.
Поддержка дампа памяти
Начиная с Visual Studio 2019 версии 16.9 технология AddressSanitizer Майкрософт обеспечивает интеграцию с интегрированной средой разработки Visual Studio. Функционал может по желанию создавать файл аварийного дампа при обнаружении ошибки во время выполнения. Если вы устанавливаете переменную среды перед запуском ASAN_SAVE_DUMPS=MyFileName.dmp программы, файл аварийного дампа создается с дополнительными метаданными для эффективной отладки точно диагностированных ошибок. Эти файлы дампа облегчают расширенное использование AddressSanitizer для:
- Тестирование локального компьютера
- Локальное распределенное тестирование
- Облачные рабочие процессы для тестирования
Установка AddressSanitizer
Процессы C++ в установщике Visual Studio по умолчанию устанавливают библиотеки AddressSanitizer и интеграцию с интегрированной средой разработки. Однако если вы обновляете более раннюю версию Visual Studio 2019, используйте установщик, чтобы включить поддержку ASan после обновления. Установщик можно открыть в главном меню Visual Studio, выбрав Tools>Get Tools and Features. В программе установки Visual Studio выберите Изменить для уже установленной версии Visual Studio, чтобы перейти к следующему экрану.
Примечание.
Если вы запускаете Visual Studio в новом обновлении, но не установили ASan, при запуске кода возникает ошибка:
LNK1356: не удается найти библиотеку "clang_rt.asan_dynamic-i386.lib".
Используйте AddressSanitizer
Начните создавать исполняемые файлы с параметром компилятора /fsanitize=address с помощью любого из следующих распространенных методов разработки:
- Сборки командной строки
- Система проектов Visual Studio
- Интеграция Visual Studio CMake
Перекомпилируйте код, а затем запустите программу как обычно, чтобы выявить многие типы точно диагностируемых ошибок. Проблемы можно просмотреть в интегрированной среде разработки отладчика, командной строке или файле дампа.
Корпорация Майкрософт рекомендует использовать AddressSanitizer в следующих трех стандартных рабочих процессах:
Внутренний цикл разработчика
- Visual Studio — командная строка
- Visual Studio — система проектов
- Visual Studio — CMake
CI/CD — непрерывная интеграция и непрерывная доставка
- Отчеты об ошибках — файлы дампа AddressSanitizer
Фаззинг - построение с использованием оболочки libFuzzer
- Azure OneFuzz
- Локальный компьютер
В этой статье рассматриваются сведения, необходимые для включения трех рабочих процессов, перечисленных ранее. Сведения относятся к реализации AddressSanitizer, зависящей от платформы Windows 10 (и более поздних версий). Эта документация дополняет документацию из Google, Apple и GCC.
Примечание.
Поддержка ограничена x86 и x64 в Windows 10 и более поздних версий.
Отправьте нам отзыв о том, что вы хотите увидеть в будущих выпусках. Ваши отзывы помогают нам определять приоритеты других санитизаторов в будущем, таких как /fsanitize=thread, , /fsanitize=leak/fsanitize=memoryили /fsanitize=undefined/fsanitize=hwaddress. При возникновении проблем можно сообщить об ошибках .
Использование AddressSanitizer из командной строки разработчика
/fsanitize=address Используйте параметр компилятора в командной строкеразработчика, чтобы включить компиляцию для среды выполнения AddressSanitizer. Параметр /fsanitize=address совместим с существующими уровнями оптимизации C++ или C, например , /Od, /O1/O2и /O2 /GL. Опция работает со статическими и динамическими CRT (например, /MD, /MDd, /MT, и /MTd). Он работает независимо от того, создаете ли файл EXE или библиотеку DLL. Сведения об отладке необходимы для оптимального форматирования стеков вызовов. В следующем примере cl /fsanitize=address /Zi передается в командной строке.
Примечание.
AddressSanitizer не поддерживает оптимизацию на основе профилей (PGO). AddressSanitizer не следует использовать в рабочей среде.
Библиотеки AddressSanitizer (.lib файлы) подключаются для вас автоматически. Дополнительные сведения см. в справочнике по AddressSanitizer: языку, сборке и отладке.
Пример: глобальное базовое переполнение буфера
// basic-global-overflow.cpp
#include <stdio.h>
int x[100];
int main() {
printf("Hello!\n");
x[100] = 5; // Boom!
return 0;
}
С помощью командной строки разработчика для Visual Studio 2019 скомпилируйте basic-global-overflow.cpp с помощью /fsanitize=address /Zi.
При запуске результирующего basic-global-overflow.exe в командной строке создается отформатированный отчет об ошибке, который следует.
Рассмотрим наложенные красные коробки, которые выделяют семь ключевых элементов информации:
Красные выделения, от верхнего до нижнего
- Ошибка безопасности памяти — это переполнение глобального буфера.
- Существовало 4 байта (32 бита), хранящихся вне любой определяемой пользователем переменной.
- Операция записи произошла в функции
main(), определенной в файлеbasic-global-overflow.cppна 7 строке. - Переменная с именем
xопределяется в basic-global-overflow.cpp в строке 3, начиная с столбца 8. - Эта глобальная переменная
xимеет размер 400 байт. - Точный байт тени , описывающий адрес, предназначенный для хранилища, имел значение
0xf9. - Согласно легенде теневого байта,
0xf9— это область заполнения справа отint x[100].
Примечание.
Когда AddressSanitizer сообщает об ошибке, среда выполнения ASan вызывает символизатор LLVM для создания имен функций в стеке вызовов.
Использование AddressSanitizer в Visual Studio
AddressSanitizer интегрирован в среду разработки Visual Studio. Чтобы включить AddressSanitizer для проекта MSBuild, щелкните проект правой кнопкой мыши в Обозреватель решений и выберите "Свойства". В диалоговом окне "Страницы свойств" выберите Свойства конфигурации>>, а затем измените параметр Enable AddressSanitizer. Нажмите ОК, чтобы сохранить внесенные изменения.
Чтобы выполнить сборку из интегрированной среды разработки, отказаться от любых несовместимых параметров. Для существующего проекта, скомпилированного с помощью /Od (или режима отладки), может потребоваться отключить следующие параметры:
-
/ZIОтключение (формат сведений отладки) -
/RTC1Выключите (проверки среды выполнения) -
/INCREMENTALОтключить (добавочное связывание)
Чтобы создать и запустить отладчик, нажмите клавишу F5. В Visual Studio появляется окно "Исключение выброшено"
Использование AddressSanitizer с использованием Visual Studio: CMake
Чтобы включить AddressSanitizer для проекта CMake, созданного для целевой платформы Windows, выполните следующие действия:
Откройте раскрывающееся меню "Конфигурации" на панели инструментов в верхней части интегрированной среды разработки и выберите пункт "Управление конфигурациями".
Это действие открывает редактор параметров CMake Project, который отражает содержимое файла
CMakeSettings.jsonproject.Выберите ссылку "Изменить JSON ". Этот выбор переключает представление на необработанный JSON.
Чтобы включить AddressSanitizer, добавьте следующий фрагмент кода в предустановку
"windows-base"внутри"configurePresets":."environment": { "CFLAGS": "/fsanitize=address", "CXXFLAGS": "/fsanitize=address" }"configurePresets"выглядит примерно так, после этого:"configurePresets": [ { "name": "windows-base", "hidden": true, "generator": "Ninja", "binaryDir": "${sourceDir}/out/build/${presetName}", "installDir": "${sourceDir}/out/install/${presetName}", "cacheVariables": { "CMAKE_C_COMPILER": "cl.exe", "CMAKE_CXX_COMPILER": "cl.exe" }, "condition": { "type": "equals", "lhs": "${hostSystemName}", "rhs": "Windows" }, "environment": { "CFLAGS": "/fsanitize=address", "CXXFLAGS": "/fsanitize=address" } },AddressSanitizer не работает, если указан параметр edit-and-continue (
/ZI), который включен по умолчанию для новых проектов CMake. ВCMakeLists.txt, оставьте комментарий (добавьте префикс#) к строке, начинающейся сset(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT". Эта строка выглядит примерно так:# set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")Используйте ctrl+S , чтобы сохранить этот JSON-файл.
Очистите каталог кэша CMake и выполните перенастройку, выбрав в меню Visual Studio: Проект>Удалить кэш и Перенастроить. Нажмите кнопку "Да", когда появится запрос, чтобы очистить каталог кэша и перенастроить его.
Замените содержимое исходного файла, например,
CMakeProject1.cppследующим кодом:// CMakeProject1.cpp : Defines the entry point for the application #include <stdio.h> int x[100]; int main() { printf("Hello!\n"); x[100] = 5; // Boom! return 0; }Выберите F5 для повторной компиляции и запуска под отладчиком.
Скриншот демонстрирует ошибку при сборке с использованием CMake.
Аварийные дампы AddressSanitizer
AddressSanitizer включает функции для использования с облачными и распределенными рабочими процессами. Эта функция позволяет в автономном режиме просматривать ошибку AddressSanitizer в интегрированной среде разработки. Ошибка отображается поверх вашего исходного кода, так же как и в интерактивном сеансе отладки.
Эти файлы дампа могут повысить эффективность анализа ошибки. Вам не нужно повторно запускать, находить удаленные данные или искать компьютер, который был отключен.
Чтобы создать файл дампа, который можно просмотреть в Visual Studio на другом компьютере позже:
set ASAN_SAVE_DUMPS=MyFileName.dmp
Начиная с Visual Studio 16.9, вы можете отобразить точно определённую ошибку, сохранённую в файле *.dmp, поверх исходного кода.
Эта функция аварийного дампа обеспечивает облачные рабочие процессы или распределенное тестирование. Его также можно использовать для регистрации подробной ошибки, подлежащей исправлению, в любой ситуации.
Примеры ошибок
AddressSanitizer может обнаружить несколько типов ошибок неправильного использования памяти. Ниже приведено множество ошибок среды выполнения при запуске двоичных файлов, скомпилированных с помощью параметра компилятора AddressSanitizer (/fsanitize=address).
alloc-dealloc-mismatchallocation-size-too-bigcalloc-overflowdouble-freedynamic-stack-buffer-overflowglobal-buffer-overflowheap-buffer-overflowheap-use-after-freeinvalid-allocation-alignmentmemcpy-param-overlapnew-delete-type-mismatchstack-buffer-overflowstack-buffer-underflowstack-use-after-returnstack-use-after-scopestrncat-param-overlapuse-after-poison
Дополнительные сведения о примерах см. в разделе Примеры ошибок AddressSanitizer.
Различия с Clang 12.0
В настоящее время MSVC отличается от Clang 12.0 в двух функциональных областях:
- stack-use-after-scope: этот параметр включен по умолчанию и не может быть отключен.
-
stack-use-after-return: эта возможность требует дополнительного параметра компилятора и недоступна, если задан только
ASAN_OPTIONS.
Эти решения были приняты для уменьшения матрицы тестов, необходимой для доставки этой первой версии.
Функции, которые могут привести к ложным срабатываниям в Visual Studio 2019 16.9, не были включены. Эта дисциплина обеспечивает поддержание целостности тестирования, необходимой при рассмотрении совместимости с десятилетиями существующего кода. Дополнительные возможности можно рассмотреть в последующих выпусках:
- Порядок инициализации Fiasco
- Внутриобъектное переполнение
- Переполнение контейнера
- Вычитание/сравнение указателей
Дополнительные сведения см. в разделе "Создание для AddressSanitizer" с помощью MSVC.
Документация по отрасли
Обширная документация существует для этих языковых и зависимых от платформ реализаций технологии AddressSanitizer.
В этой основополагающей статье о AddressSanitizer (external) описывается реализация.