AddressSanitizer

Обзор

Языки C & ++ являются мощными, но могут страдать от класса ошибок, влияющих на правильность программы и безопасность программы. Начиная с Visual Studio 2019 версии 16.9 компилятор Microsoft C/C++ (MSVC) и интегрированная среда разработки поддерживают AddressSanitizer. AddressSanitizer (ASan) — это технология компилятора и среды выполнения, которая предоставляет множество сложных ошибок с нулевыми ложными срабатываниями:

Используйте AddressSanitizer, чтобы сократить время, затраченное на:

  • Базовая правильность
  • Переносимость между платформами
  • Безопасность
  • нагрузочное тестирование
  • Интеграция нового кода

AddressSanitizer, первоначально представленный Google, является мощной альтернативой как (проверка ошибок во время выполнения), так/RTC и /analyze (статический анализ). Она предоставляет технологии обнаружения ошибок во время выполнения, которые используют существующие системы сборки и существующие тестовые ресурсы напрямую.

AddressSanitizer интегрирован с системой проектов Visual Studio, системой сборки CMake и интегрированной среде разработки. Проекты могут включить AddressSanitizer, задав свойство проекта или используя один дополнительный параметр компилятора: /fsanitize=address. Новый параметр совместим со всеми уровнями оптимизации и конфигураций x86 и x64. Однако он несовместим с изменением и продолжением, добавочным связыванием и /RTC.

Начиная с Visual Studio 2019 версии 16.9 технология Microsoft AddressSanitizer обеспечивает интеграцию с интегрированной средой разработки Visual Studio. При необходимости функция может создать файл аварийного дампа, когда санитизатор находит ошибку во время выполнения. Если задать ASAN_SAVE_DUMPS=MyFileName.dmp переменную среды перед запуском программы, то создается файл аварийного дампа с дополнительными метаданными для эффективной отладки точно диагностированных ошибок. Эти файлы дампа упрощают расширенное использование AddressSanitizer:

  • Тестирование локального компьютера,
  • Локальное распределенное тестирование и
  • Облачные рабочие процессы для тестирования.

Установка AddressSanitizer

Интеграция и библиотеки IDE AddressSanitizer устанавливаются по умолчанию с рабочими нагрузками C++ в Visual Studio Installer. Однако при обновлении более старой версии Visual Studio 2019 используйте установщик, чтобы включить поддержку ASan после обновления:

Visual Studio Installer screenshot highlighting the C++ AddressSanitizer component

Вы можете выбрать "Изменить" в существующей Visual Studio установки из Visual Studio Installer, чтобы открыть экран выше.

Примечание

Если вы запускаете Visual Studio в новом обновлении, но не установили ASan, при запуске кода появится сообщение об ошибке:

LNK1356: не удается найти библиотеку "clang_rt.asan_dynamic-i386.lib"

Использование AddressSanitizer

Начните создавать исполняемые файлы с /fsanitize=address помощью параметра компилятора с помощью любого из следующих распространенных методов разработки:

  • Сборки командной строки
  • Система проектов Visual Studio
  • интеграция cMake Visual Studio

Выполните повторную компиляцию, а затем запустите программу в обычном режиме. Это поколение кода предоставляет множество типов точно диагностированных ошибок. Эти ошибки передаются тремя способами: в интегрированной среде разработки отладчика, в командной строке или в новом файле дампа для точной обработки внестрочный режим.

Корпорация Майкрософт рекомендует использовать AddressSanitizer в трех стандартных рабочих процессах:

В этой статье рассматриваются сведения, необходимые для включения трех рабочих процессов, перечисленных выше. Информация зависит от платформы Windows 10 реализации 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 /GL/O2и PGO). Этот параметр работает со статическими и динамическими crT (например, , /MD, /MDdи /MTd/MT). Он работает независимо от того, создаете ли вы 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

Screenshot of a command prompt showing the command to compile with AddressSanitizer options.

При запуске результирующего main.exe файла в командной строке создается отформатированный отчет об ошибке, показанный ниже.

Рассмотрим наложенные красные ящики, которые выделяют семь ключевых фрагментов информации:

Screenshot of the debugger showing a basic global overflow error.

Красные выделения, сверху вниз

  1. Ошибка безопасности памяти — это глобальный буфер переполнения.
  2. За пределами любой пользовательской переменной хранилось4 байта (32 бита).
  3. Хранилище выполнялось в функции main() , определенной в файле basic-global-overflow.cpp в строке 7.
  4. Именованной x переменной определяется в файле basic-global-overflow.cpp в строке 3, начиная со столбца 8.
  5. Эта глобальная переменная x размером 400 байт
  6. Точный байт тени , описывающий адрес, предназначенный магазином, имел значение 0xf9
  7. Легенда теневого байта говорит 0xf9 , что область заполнения справа от int x[100]

Примечание

Имена функций в стеке вызовов создаются с помощью символизатора LLVM , вызываемого средой выполнения при ошибке.

Использование AddressSanitizer в Visual Studio

AddressSanitizer интегрирован с интегрированной Visual Studio интегрированной среды разработки. Чтобы включить AddressSanitizer для проекта MSBuild, щелкните правой кнопкой мыши проект в Обозреватель решений и выберите пункт "Свойства". В диалоговом окне "Страницы свойств" выберите "Свойства> конфигурации" /C++>General, а затем измените свойство Enable AddressSanitizer. Выберите ОК для сохранения внесенных изменений.

Screenshot of the Property Pages dialog showing the Enable AddressSanitizer property.

Чтобы выполнить сборку из интегрированной среды разработки, отказаться от любых несовместимых параметров. Для существующего проекта, скомпилированного с помощью /Od (или режима отладки), может потребоваться отключить следующие параметры:

Чтобы выполнить сборку и запуск отладчика, введите клавишу F5. Это окно появится в Visual Studio:

Screenshot of the debugger showing a global buffer overflow error.

Использование AddressSanitizer из Visual Studio: CMake

Чтобы включить AddressSanitizer для проекта CMake, созданного для целевого Windows, выполните следующие действия:

  1. Откройте раскрывающийся список "Конфигурации " на панели инструментов в верхней части интегрированной среды разработки и выберите "Управление конфигурациями".

    Screenshot of the CMake configuration dropdown.

    При выборе откроется редактор CMake Project Параметры, сохраненный в файле CMakeSettings.json.

  2. Выберите ссылку "Изменить JSON " в редакторе. Этот выбор переключит представление на необработанный JSON.

  3. Добавьте свойство : addressSanitizerEnabled: true

    Это изображение CMakeSettings.json после этого изменения:

    Screenshot of the text editor view of CMakeSettings.json.

  4. Нажмите клавиши CTRL+S , чтобы сохранить этот JSON-файл, а затем введите F5 для повторной компиляции и запуска под отладчиком.

На этом снимке экрана показано сообщение об ошибке из сборки CMake.

Screenshot of the CMake build error message.

Аварийные дампы AddressSanitizer

Мы представили новые функции в AddressSanitizer для использования с облачными и распределенными рабочими процессами. Эта функция позволяет автономно просматривать ошибку AddressSanitizer в интегрированной среде разработки. Ошибка накладывается на источник так же, как и в сеансе динамической отладки.

Эти новые файлы дампа могут привести к эффективности при анализе ошибки. Вам не нужно повторно запускать или находить удаленные данные или искать компьютер, который был отключен.

Чтобы создать новый тип файла дампа, который можно просмотреть в Visual Studio на другом компьютере позже:

set ASAN_SAVE_DUMPS=MyFileName.dmp

Начиная с Visual Studio 16.9, вы можете отобразить точно диагностированную ошибку, хранящуюся в *.dmp файле, поверх исходного кода.

Эта новая функция аварийного дампа позволяет выполнять облачные рабочие процессы или распределенное тестирование. Его также можно использовать для отправки подробной и практической ошибки в любом сценарии.

Примеры ошибок

AddressSanitizer может обнаружить несколько типов ошибок неправильного использования памяти. Ниже приведены многие ошибки среды выполнения при запуске двоичных файлов, скомпилированных с помощью параметра компилятора AddressSanitizer (/fsanitize=address).

Дополнительные сведения о примерах см. в примерах ошибок AddressSanitizer.

Различия с Clang 12.0

MSVC в настоящее время отличается от Clang 12.0 в двух функциональных областях:

  • стек-use-after-scope — этот параметр включен по умолчанию и не может быть отключен.
  • стек-use-after-return — для этой функции требуется дополнительный параметр компилятора, который недоступен только ASAN_OPTIONSпараметром.

Эти решения были приняты для сокращения матрицы тестирования, необходимой для предоставления первой версии.

Признаки, которые могут привести к ложным срабатываниям в Visual Studio 2019 16.9, не были включены. Эта дисциплина обеспечивает эффективную целостность тестирования, необходимую при рассмотрении взаимодействия с десятилетиями существующего кода. Дополнительные возможности могут рассматриваться в последующих выпусках:

Дополнительные сведения см. в разделе "Сборка для AddressSanitizer" с MSVC.

Существующая отраслевая документация

Подробная документация уже существует для этих языковых и зависящих от платформ реализаций технологии AddressSanitizer.

В этом частичном документе на addressSanitizer описывается реализация.

См. также раздел

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