В этой статье я хочу познакомить вас с анализатором C и C++ кода PVS-Studio и как с ним работать в среде Visual C++. Данная статья будет полезна для начинающих пользователей.
PVS-Studio поддерживает среды Microsoft Visual Studio 2019, 2017, 2015, 2013, 2012, 2010. Системные требования можно узнать в документации. На данный момент PVS-Studio анализирует проекты, написанные на языке C, C++, C# и Java. Однако данная заметка посвящена программистам, использующим Visual C++ и желающим впервые познакомиться со статическим анализатором кода PVS-Studio.
Скачать установочный пакет можно по этой ссылке. После запуска пакета будут предложены варианты интеграции (см. рисунок 1). Недоступные варианты будут затемнены.
Рисунок 1. Окно с компонентами интеграции.
После установки стоит открыть окно About в Visual Studio и проверить присутствие PVS-Studio в списке установленных продуктов.
По завершении установки вы можете приступить к проверке проекта. Также можно сразу попробовать проверить решение целиком. Для этого выберите пункт меню Extensions > PVS-Studio > Check > Solution (см. рисунок 2).
Рисунок 2. Проверка решения (Solution) с помощью анализатора PVS-Studio.
Если с проверкой возникнут какие-то трудности, мы рекомендуем обратиться к разделу "Не удается проверить?" на нашем сайте. Это не бестолковые рекомендации в духе "проверьте, что вилка вставлена в розетку". В разделе описаны типовые ситуации, с которыми к нам обращались пользователи, и предложены варианты действий.
После проверки все диагностические сообщения будут отображены в специальном окне. Окно имеет много элементов для управления. Все они служат для того, чтобы показать именно те диагностические сообщения, которые интересны пользователю. Однако в первый момент окно может показаться сложным.
Рисунок 3. Окно с диагностическими сообщениями. Нажмите на рисунок для его увеличения.
Все элементы окна рассмотрены в документации, но сейчас мы остановимся на основных:
PVS-Studio является средством статического тестирования защищённости приложений (Static Application Security Testing, SAST) - анализатор может выявлять потенциальные уязвимости в коде проекта и показывать соответствующий идентификатор ошибки в определенной классификации.
PVS-Studio поддерживает следующие классификации ошибок:
Включить отображение кодов CWE можно по контекстному меню в окне анализатора по пути Show Columns > CWE
Рисунок 4. Контекстное меню и пример вывода CWE-кодов.
Либо в меню сверху (Extensions > PVS-Studio > Display CWE Codes in Output Window)
Рисунок 5. Меню расширения.
Диагностики MISRA включаются отдельно в настройках:
Рисунок 6. Список определяемых ошибок.
Подробнее про эти классификации можно прочитать здесь.
PVS-Studio_Cmd.exe - утилита для проверки C++ проектов .vcxproj и решений из командной строки. Она может быть полезна для автоматизации анализа. Программа находится в директории, куда была произведена установка - по умолчанию это 'C:\Program Files (x86)\PVS-Studio'.
Программа имеет множество параметров, но для начала нам понадобится только три из них:
Вот так будет выглядеть запуск:
Рисунок 7. Вывод программы PVS-Studio_Cmd.exe
После выполнения мы получим plog-файл с отчетом, путь до которого мы указали в параметрах запуска. Этот отчет можно преобразовать в другие форматы с помощью утилиты PlogConverter.exe, а для просмотра отчета в IDE достаточно двойного клика по plog-файлу в проводнике.
Также файл отчета можно открыть в меню расширения по пути Extensions > PVS-Studio > Open/Save > Open Analysis Report...
Рисунок 8. Открытие отчета из меню плагина.
Подробную информацию по утилите и ее параметрам можно найти в документации.
Для борьбы с ложными срабатываниями в анализаторе предусмотрен набор различных механизмов. Подробно они описаны в следующих разделах:
Рассмотрим пример ошибки, выявленной анализатором. Следующий код был взят из проекта ReactOS:
VOID NTAPI
AtapiDmaInit(....)
{
....
ULONG treg = 0x54 + (dev < 3) ? (dev << 1) : 7;
....
}
Предупреждение PVS-Studio: V502 Perhaps the '?:' operator works in a different way than it was expected. The '?:' operator has a lower priority than the '+' operator. uniata id_dma.cpp 1610
Выражение 0x54 + (dev < 3) будет всегда true - в первую очередь ненулевая константа 0x54 суммируется с результатом выражения (dev < 3), которое может иметь значение 0 или 1, и уже затем результат сравнивается с нулем.
Правильный код должен иметь вид:
VOID NTAPI
AtapiDmaInit(....)
{
....
ULONG treg = 0x54 + ((dev < 3) ? (dev << 1) : 7);
....
}
В этом случае мы обернули оператор '?:' в скобки, теперь он будет принимать значение в зависимости от выражения (dev < 3).
Это было краткое введение в то, как работать с PVS-Studio для Visual C++. Конечно, тут было рассмотрено далеко не всё. Более подробно мы разбираем работу анализатора в нашем блоге, а описание всех сообщений и настроек есть в документации.