AddressSanitizer

Обзор

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

Используйте 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, чтобы открыть следующий экран.

Screenshot of the Visual Studio Installer. The C++ AddressSanitizer component, under the Optional section, is highlighted.

Примечание.

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

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

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

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

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

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

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

В этой статье рассматриваются сведения, необходимые для включения трех рабочих процессов, перечисленных ранее. Сведения относятся к реализации 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и ).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

Screenshot of a command prompt showing the command to compile with AddressSanitizer options. The command is: `cl main.cpp -faanitize-address /Zi`.

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

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

Screenshot of the debugger showing a basic global overflow error.

В отчете об ошибке есть семь красных выделений, определяющих ключевые фрагменты информации. Они сопоставляются с нумерованным списком, который следует на этом снимках экрана. Нумерованные поля выделяют следующий текст: 1) global-buffer-overflow 2) WRITE размером 4 3) basic-global-overflow.cpp 7 4) справа от глобальной переменной x, определенной в "basic-global---global-" overflow.cpp:3:8' 5) размером 400 6) 00 00[f9]f9 f9 7) Box находится в области условных обозначений тени байтов и содержит глобальную красную зону: f9

Красные выделения, от верхнего до нижнего

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

Примечание.

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

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

AddressSanitizer интегрирован с интегрированной интегрированной среду разработки Visual Studio. Чтобы включить AddressSanitizer для проекта MSBuild, щелкните проект правой кнопкой мыши в Обозреватель решений и выберите "Свойства". В диалоговом окне "Страницы свойств" выберите свойства>конфигурации C/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. It displays options like x64 Debug, x64 Release, and so on. At the bottom of the list, Manage Configurations... is highlighted.

    Откроется редактор проекта CMake Параметры, который отражает содержимое файла проектаCMakeSettings.json.

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

  3. Добавьте следующий фрагмент кода в "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"
            }
          },
    
  4. Средство очистки адресов не работает, если указан/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>>")
    
  5. Введите CTRL+S , чтобы сохранить этот JSON-файл

  6. Очистите каталог кэша CMake и перенастройку, выбрав в меню Visual Studio: кэш удаления проекта>и перенастройка. Нажмите кнопку "Да", когда появится запрос, чтобы очистить каталог кэша и перенастроить его.

  7. Замените содержимое исходного файла (например, 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;
    }
    
  8. Выберите F5 для повторной компиляции и запуска под отладчиком.

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

    Screenshot of an exception that says: Address Sanitizer Error: Global buffer overflow. In the background, address sanitizer output is visible in command window.

Аварийные дампы 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 в двух функциональных областях:

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

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

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

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

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

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

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

См. также

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