AddressSanitizer
Обзор
Языки C и C++ являются мощными, но могут страдать от класса ошибок, влияющих на правильность программы и безопасность программы. Начиная с Visual Studio 2019 версии 16.9 компилятор Microsoft C/C++ (MSVC) и интегрированная среда разработки поддерживает санитизатор AddressSanitizer . AddressSanitizer (ASan) — это технология компилятора и среды выполнения, которая предоставляет множество сложных ошибок с нуля ложных срабатываний:
- Несоответствия alloc/dealloc и/
new
delete
несоответствия типов - Выделение слишком большого размера для кучи
calloc
переполнение иalloca
переполнение- Двойной бесплатный и использовать после бесплатного
- Глобальный переполнение переменной
- Переполнение буфера кучи
- Недопустимое выравнивание выровненных значений
memcpy
иstrncat
перекрытие параметров- Переполнение буфера стека и переполнение
- Использование стека после
return
и использование после области - Использование памяти после того, как оно отравлено
Используйте 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 с помощью инструментов>получения инструментов и компонентов... Выберите "Изменить" в существующей установке 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, зависящей от платформы (и более поздних версий). Эта документация дополняет отличную документацию от 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
и ).PGO
Параметр работает со статическими и динамическими crT (например, , /MD
, /MT
/MDd
и /MTd
). Он работает независимо от того, создаете ли файл EXE или библиотеку DLL. Сведения об отладке необходимы для оптимального форматирования стеков вызовов. В следующем примере cl /fsanitize=address /Zi
передается в командной строке.
Библиотеки 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, компиляция main.cpp
с помощью /fsanitize=address /Zi
При запуске результирующего main.exe
файла в командной строке создается отформатированный отчет об ошибке, следующий.
Рассмотрим наложенные красные коробки, которые выделяют семь ключевых элементов информации:
В отчете об ошибке есть семь красных выделений, определяющих ключевые фрагменты информации. Они сопоставляются с нумерованным списком, который следует на этом снимках экрана. Нумерованные поля выделяют следующий текст: 1) global-buffer-overflow 2) WRITE размером 4 3) basic-global-overflow.cpp 7 4) справа от глобальной переменной x, определенной в области условных обозначений basic-global-overflow.cpp:3:8) размером 400 6) 00 00[f9]f9 f9 7) Box находится в области условных обозначений тени байтов и содержит глобальную красную зону: f9
Красные выделения, от верхнего до нижнего
- Ошибка безопасности памяти — это глобальный буфер-переполнение.
- Существовало 4 байта (32 бита), хранящихся вне любой определяемой пользователем переменной.
- Хранилище произошло в функции
main()
, определенной в файлеbasic-global-overflow.cpp
в строке 7. - Переменная с именем
x
определяется в basic-global-overflow.cpp в строке 3, начиная с столбца 8 - Эта глобальная переменная
x
имеет размер 400 байт - Точный байт тени, описывающий адрес, предназначенный для хранилища, имел значение
0xf9
- Легенда теневого байта говорит, что
0xf9
область заполнения справа отint x[100]
Примечание.
Имена функций в стеке вызовов создаются с помощью символа LLVM, вызываемого средой выполнения при ошибке.
Использование AddressSanitizer в Visual Studio
AddressSanitizer интегрирован с интегрированной интегрированной среду разработки Visual Studio. Чтобы включить AddressSanitizer для проекта MSBuild, щелкните проект правой кнопкой мыши в Обозреватель решений и выберите "Свойства". В диалоговом окне "Страницы свойств" выберите свойства>конфигурации C/C++>General, а затем измените свойство Enable AddressSanitizer. Нажмите ОК, чтобы сохранить внесенные изменения.
Чтобы выполнить сборку из интегрированной среды разработки, отказаться от любых несовместимых параметров. Для существующего проекта, скомпилированного с помощью /Od
(или режима отладки), может потребоваться отключить следующие параметры:
- Отключение редактирования и продолжения
/RTC1
Отключение (проверки среды выполнения)/INCREMENTAL
Отключить (добавочное связывание)
Чтобы создать и запустить отладчик, нажмите клавишу F5. В Visual Studio появится окно "Исключение"
Использование AddressSanitizer из Visual Studio: CMake
Чтобы включить AddressSanitizer для проекта CMake, созданного для целевой платформы Windows, выполните следующие действия:
Откройте раскрывающийся список "Конфигурации" на панели инструментов в верхней части интегрированной среды разработки и выберите пункт "Управление конфигурациями".
Откроется редактор параметров проекта CMake, который отражает содержимое файла проекта
CMakeSettings.json
.Выберите ссылку "Изменить JSON " в редакторе. Этот выбор переключает представление на необработанный JSON.
Добавьте следующий фрагмент кода в
"windows-base"
предустановку, чтобы"configurePresets":
включить sanitizer address:"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" } },
Средство очистки адресов не работает, если указан
/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-mismatch
allocation-size-too-big
calloc-overflow
double-free
dynamic-stack-buffer-overflow
global-buffer-overflow
heap-buffer-overflow
heap-use-after-free
invalid-allocation-alignment
memcpy-param-overlap
new-delete-type-mismatch
stack-buffer-overflow
stack-buffer-underflow
stack-use-after-return
stack-use-after-scope
strncat-param-overlap
use-after-poison
Дополнительные сведения об примерах см . в примерах ошибок AddressSanitizer.
Различия с Clang 12.0
В настоящее время MSVC отличается от Clang 12.0 в двух функциональных областях:
- stack-use-after-scope — этот параметр включен по умолчанию и не может быть отключен.
- стек-use-after-return — эта функция требует дополнительного параметра компилятора и не доступна только параметром
ASAN_OPTIONS
.
Эти решения были приняты для уменьшения матрицы тестов, необходимой для доставки этой первой версии.
Функции, которые могут привести к ложным срабатываниям в Visual Studio 2019 16.9, не были включены. Эта дисциплина применяет эффективную целостность тестирования, необходимую при рассмотрении взаимодействия с десятилетиями существующего кода. Дополнительные возможности можно рассмотреть в последующих выпусках:
- Порядок инициализации Fiasco
- Переполнение объекта внутри объекта
- Переполнение контейнера
- Вычитание указателя и сравнение
Дополнительные сведения см. в разделе "Создание для AddressSanitizer" с помощью MSVC.
Существующая индустрия документация
Обширная документация уже существует для этих языковых и зависимых от платформ реализаций технологии AddressSanitizer.
В этом частичном документе по адресу AddressSanitizer (external) описывается реализация.
См. также
Известные проблемы AddressSanitizer
Справочник по сборке и языку AddressSanitizer
Справочник по среде выполнения AddressSanitizer
Теневой байт AddressSanitizer
Облачное или распределенное тестирование AddressSanitizer
Интеграция отладчика AddressSanitizer
Примеры ошибок AddressSanitizer