c-cpp-cookies
  • Полезные материалы
    • About
  • Настройка окружения
    • Git
      • Git CLI
      • Git GUI
      • Git Web
      • Git в среде разработке
        • Visual Studio
        • Visual Studio Code
        • CLion
        • Qt Creator
    • Стандарты (они же ISO)
    • Qt about
    • IDE
      • Visual Studio Code
        • Код в Visual Studio Code
        • Разработка в Visual Studio Code
      • Visual Studio
        • Настройки Visual Studio и проектов
        • Код в Visual Studio
        • Visual Studio + GitHub
      • Qt + Qt Creator
        • Установка Qt и QtCreator
        • Примеры проектов на Qt
      • CLion
        • Настройки CLion
        • Код в CLion
        • CLion + GitHub
    • Компиляторы
      • Clang + Visual Studio
      • Clang + CLion
  • Best practices
    • Антипаттерны и способы улучшения кода
      • 0. Освобождение ресурсов
      • 1. Чтение данных из файла
      • 2. Открытие файлов
      • 3. Объявление переменных
      • 4. Выделение памяти
      • 5. Необдуманный код
      • 6. Глубокие if
      • 7. Длинные if
      • 9. Non-void функции
      • 10. Создание массивов
      • 11. Проверка формата файла
  • Сборка программы
    • Сборка программы
    • Системы сборки / Build systems
      • Проект и решение
      • Make
      • Ninja
      • CMake
      • MSBuild
    • Подключение внешних библиотек
    • Библиотеки
  • Отладка
    • Отладка / Debugging
    • Запуск программы
    • Точки останова / Breakpoints
      • Обычные точки останова / General breakpoint
      • Условные точки останова / Conditional breakpoint
      • Зависимые точки останова / Dependent breakpoint
      • Временные точки останова / Temporary breakpoint
      • Точки трассировки / Breakpoint actions и tracepoints
    • Стек вызовов / Call stack
    • Локальные переменные / Locals
    • Просмотр области памяти / Memory view
    • Исключения / Exceptions
  • Анализ
    • Поиск утечек памяти
    • Санитайзеры
  • Возможности IDE
    • Возможности IDE
    • Продвинутый текстовый редактор
    • Закладки / Bookmarks
    • Платформы / Platforms
    • Конфигурации сборки / Build configurations
    • Шаблонные проекты / Project templates
    • Терминал / Terminal
    • Сборка / Build
    • Запуск программы / Run program
    • Code style
    • Работа с Github Actions
  • Тестирование
    • Тестирование
    • Google test
      • Gtest в VS
      • Gtest в CLion
      • Gtest в VSCode
    • Покрытие кода (code coverage)
Powered by GitBook
On this page
  • Настройка окружения
  • Windows
  • Linux
  • MacOS
  1. Анализ

Санитайзеры

PreviousПоиск утечек памятиNextВозможности IDE

Last updated 9 months ago

Санитайзеры – инструменты отладки, позволяющие проводить более продвинутые анализы во время исполнения программного обеспечения. Компилятор Clang (фронтенд LLVM) поддерживает шесть видов санитайзеров:

  • – детектор ошибок при работе с адресацией (выход за границы выделенной области памяти, стека, двойное высвобождение памяти и другое).

  • – детектор ошибок при взаимодействиями между потоками (data race).

  • – детектор специфических ошибок, чаще всего регламентированных в стандарте как .

  • – детектор чтения из неинициализированной области памяти.

  • – детектор утечки (не освобождаемой) памяти.

  • – обобщенный анализ потока данных.

Все виды детекторов . Можете попробовать проанализировать код всеми видами санитайзеров, однако нас будет интересовать только: ASan, UBSan и LSan – почти всегда достаточный набор для диагностики кода.

Чтобы собрать программу с таким набором санитайзеров, необходимо установить флаг -fsanitize с желаемыми детекторами, и, обязательно, выбрать сборку под отладчиком:

clang -O0 -g -fno-sanitize-recover=all -fsanitize=address,undefined,leak main.c -o main.exe

Примечание: на MacOS без leak – по документации, address уже включает обнаружение утечки памяти

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

Настройка окружения

Ниже приведены (почти наверняка) рабочие инструкции для разных операционных систем.

Windows

Нативный метод

cl.exe /Od /Z7 /fsanitize=address main.c

WSL

  1. Активируйте компоненты Windows.

    • Откройте Панель управления – Все элементы панели управления – Программы и компоненты – Включение и отключение компонентов Windows.

    • В списке найдите пункт Подсистема Windows для Linux и убедитесь, что перед пунктом стоит галочка. В ином случае: поставьте, сохраните изменения и перезагрузите компьютер.

  2. Запустите терминал/командную строку (далее – терминал), введите следующее ниже и перезагрузите компьютер:

    wsl.exe --update
    wsl.exe --set-default-version 2

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

    [wsl2]
    nestedVirtualization=true
    memory=2048MB
    processors=2

    Первые две строки должны быть по умолчанию после установки версии WSL на 2. Значение memory ограничивает подсистеме использование оперативной памяти, processors, соответственно, на количество процессоров.

  3. Запустите терминал и установите Ubuntu 22.04.3 LTS с помощью следующей команды:

    wsl.exe --install Ubuntu-22.04
  4. Запустите дистрибутив (это можно сделать, введя в терминал wsl), проследуйте инструкциям установки. Введите в терминал WSL:

   sudo apt-get update && sudo apt-get upgrade -y # обновление пакетов  
   sudo apt-get install build-essential libc++-dev libc++abi-dev binutils binutils-dev clang gdb pkg-config    

Установка valgrind:

sudo apt-get install -y valgrind

Компиляция с valgrind:

clang -O0 -gdwarf-4 main.c -o main.exe      

Запуск с valgrind:

valgrind --tool=memcheck --gen-suppressions=all --leak-check=full --show-leak-kinds=all --track-origins=yes -s ./main.exe      

VirtualBox

  1. Установите операционную систему Ubuntu Server.

    1. Создайте новую машину, New.

      • В поле Name введите имя машины, например, SanitizerRunner.

      • В поле Type выберите тип Linux.

      • В поле Version выставите Ubuntu (64-bit) или Ubuntu (32-bit).

    2. Далее нажимаете всё время Next. Из интересного стоит отметить количество места для операционной системы – хватает и 10 ГБ (утверждается, что можно поставить чуть поменьше). Также, по умолчанию, на ОС будет приходиться 2 ГБ оперативной памяти.

    3. Настройте виртуальную машину, Settings. В разделе Storage, в Empty нажмите на значок диска – Choose a disk file – выберите скачанный .iso.

    4. Запустите виртуальную машину, Start. В разделе Guided storage configuration рекомендуется убрать пункт Set up this disk as an LVM group.

    5. Во всех оставшихся разделах нажимаете всё время Next, создайте пользователя и ничего лишнего не выбирайте для экономия места и времени.

    В случае с Ubuntu Desktop потребуется 20 ГБ и 4 ГБ оперативной памяти (рекомендация), установка более очевидная из-за графического интерфейса. Рекомендуется в разделе Updates and other software:

    • Выбрать Minimal installation.

    • В пункте Other options: выбрать Download updates while installing Ubuntu и Install third-party software for graphics and Wi-Fi hardware and additional media formats.

    В дальнейшем все действия на серверной версии не будут отличаться от пользовательской.

Для более удобной работы с виртуальной машиной рекомендуется прочитать в Интернете про SSH подключения в локальной сети.

Linux

MacOS

С MacOS как и в случае с Windows с санитайзерами всё довольно грустно и печально, если хочется компилировать с терминала. В качестве решений данной проблемы могут послужить:

/path/to/homebrew/clang -O0 -g -fno-sanitize-recover=all -fsanitize=address,undefined main.c -o main.exe

и запускаетесь с:

ASAN_OPTIONS=verbosity=1:detect_leaks=1 ./main.exe

Возможности даже при большом желании использования интересных нам санитайзеров через легальные схемы на операционной системе Windows через нативный (то есть тот, который ожидается) MSVC или clang-cl не получится. Для решения этой проблемы предлагается два варианта: использование (WSL, должна быть поддержка Hyper-V) и использование (медленнее, но никаких требований от вашего железа не требуется).

Как уже сказано, на MSVC и clang-cl поддерживают только AddressSanitizer. Тем не менее, это может быть полезно, если у вас внезапная поломка программы на ровном месте. Для компиляции необходимо подать соответствующий флаг и : рекомендуется использовать полную статистику, то есть, /Z7.

Более информации .

В качестве дистрибутива рассмотрим самый простой и рекомендуемый для всех новичков в Линукс – .

В Microsoft Store установите приложение .

Альтернативный вариант: установить .

Альтернатива – программа . Введите в терминал WSL:

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

Данная часть ничем не отличается от главы , кроме установки и настройки системы.

Скачайте и установите и образ диска . Если хватает ресурсов, можно скачать пользовательскую версию .

Дальнейшие шаги ничем не отличаются от шага 5 из пункта про .

Данная инструкция целиком и полностью копирует последовательность действий рассмотренных выше и . Обратите внимание, что в разных дистрибутивах названия тех или иных пакетов могут отличаться.

. В случае платформы ARM, в UTM выбираете пункт emulate. Если ваш Mac поддерживает VirtualBox и имеет возможность запустить виртуальную машину с образом Ubuntu, тогда вам следует обратиться к .

Нативные компиляторы и приложения. В этом случае устанавливаете все необходимые для работы компилятора Clang через компилируетесь через терминал (clang из Homebrew):

либо используйте в качестве средства разработки и .

подсистемы Linux для Windows
виртуальной машины VirtualBox
отладочную информацию
здесь
Ubuntu
Подсистема Windows для Linux
приложение с Microsoft Store
valgrind
поменяли флаг добавления отладочной информации
VirtualBox
Ubuntu Server
Ubuntu Desktop
пакетный менеджер brew
Xcode
запуска санитайзеров
про WSL
WSL
WSL
VirtualBox
Использование виртуальной машины
этому пункту
AddressSanitizer
ThreadSanitizer
UndefinedBehaviorSanitizer
Undefined Behavior
MemorySanitizer
LeakSanitizer
DataFlowSanitizer
совместить нельзя
Обнаружение утечки памяти в простейшей программе