- Регистрация
- 21.07.20
- Сообщения
- 40.408
- Реакции
- 1
- Репутация
- 0
Устав от нескончаемого code review или отладки, временами задумываешься, как бы упростить себе жизнь. И немного поискав, ну или случайно наткнувшись, можно увидеть волшебное словосочетание: "Статический анализ". Давайте посмотрим, что это такое и как он может взаимодействовать с вашим проектом.
Собственно говоря, если вы пишете на каком-либо современном языке, тогда, даже не догадываясь об этом, вы пропускали его через статический анализатор. Дело в том, что любой современный компилятор предоставляет пусть и крохотный, но набор предупреждений о потенциальных проблемах в коде. Например, компилируя C++ код в Visual Studio вы можете увидеть следующее:
В этом выводе мы видим, что переменная var так и не была использована нигде в функции. Так что на самом деле вы почти всегда пользовались простеньким статическим анализатором кода. Однако, в отличие от профессиональных анализаторов, таких как Coverity, Klocwork или PVS-Studio, предоставляемые компилятором предупреждения могут указывать только на небольшой спектр проблем.
Если вы не знаете наверняка, что такое статический анализ и как его внедрять,
Зачем нужен статический анализ?
В двух словах: ускорение и упрощение.
Статический анализ позволяет найти уйму различных проблем в коде: начиная от неправильного использования конструкций языка, заканчивая опечатками. Например, вместо
auto x = obj.x;
auto y = obj.y;
auto z = obj.z;
Вы написали следующий код:
auto x = obj.x;
auto y = obj.y;
auto z = obj.x;
Как видите, в последней строке появилась опечатка. Например, PVS-Studio выдаёт следующее предупреждение:
Если хотите потыкать в эту ошибку руками, то попробуйте готовый пример на Compiler Explorer: *
И как вы понимаете, не всегда можно обратить внимания на подобные участки кода сразу и из-за этого можно засесть за отладку на добрый час, недоумевая, почему всё работает так странно.
Однако это явная ошибка. А если разработчик написал неоптимальный код из-за того, что позабыл какую-либо тонкость языка? Или же вовсе допустил в коде
Именно для этих ситуаций и появился статический анализ. Это помощник для разработчика, который укажет ему на различные проблемы в коде и объяснит в документации почему так писать не нужно, к чему это может привести и как это исправить. Вот пример как это может выглядеть: *
Больше интересных ошибок, которые может обнаружить анализатор, вы можете найти в статьях:
Теперь, прочитав этот материал и убедившись в пользе статического анализа, вы могли захотеть испытать его в деле. Но с чего начать? Как интегрировать новый инструмент в текущий проект? И как познакомить команду с ним? На эти вопросы вы найдёте ответы ниже.
Примечание. Статический анализ не заменяет и не отменяет такую полезную вещь, как обзоры кода. Он дополняет этот процесс, помогая заранее заметить и исправить опечатки, неточности, опасные конструкции. Намного продуктивнее сосредоточиться при обзорах кода на алгоритмах и понятности кода, а не над высматриванием не там поставленной скобки или
0. Знакомство с инструментом
Всё начинается с пробной версии. Действительно, сложно решиться внедрять что-либо в процесс разработки, если никогда до этого не видел инструмента вживую. Поэтому первым делом стоит скачать
Что вы узнаете на этом этапе:
После того, как вы установили себе всё необходимое, то первым делом стоит запустить анализ всего проекта (
Дело в том, что обычно на проекты с большой кодовой базой статические анализаторы выдают огромное количество предупреждений. Нет необходимости исправлять их все, так как ваш проект уже работает, а значит эти проблемы не являются критичными. Однако вы
Действительно, 178 предупреждений просмотреть значительно проще, чем несколько тысяч…
Во вкладках Medium и Low часто попадаются хорошие предупреждения, однако в эти категории занесены те диагностики, которые имеют меньшую точность (достоверность). Подробнее про уровни предупреждений и варианты работы под Windows можно посмотреть тут: *
Успешно просмотрев самые интересные ошибки (и успешно исправив их) стоит
1. Автоматизация
После знакомства наступает время настройки плагинов и интеграции в CI. Это необходимо сделать до того, как программисты начнут использовать статический анализатор. Дело в том, что программист может забыть включить анализ или вовсе не захотеть. Для этого нужно сделать некоторую финальную проверку всего, чтобы непроверенный код не мог попасть в общую ветку разработки.
Что вы узнаете на данном этапе:
Так как идеальной документации не существует, иногда приходится писать в
А теперь приступим к сервисам непрерывной интеграции (CI). Любой анализатор можно внедрить в них без каких-либо серьезных проблем. Для этого нужно создать отдельный этап в pipeline, который обычно находится после сборки и юнит-тестов. Делается это при помощи различных консольных утилит. Например, PVS-Studio предоставляет следующие утилиты:
Для интеграции анализа в CI нужно сделать три вещи:
Например, для установки PVS-Studio на Linux (Debian-base) нужно выполнить следующие команды:
wget -q -O -
| sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list \
sudo apt-get update -qq
sudo apt-get install -qq pvs-studio
В системах под управлением Windows отсутствует возможность установить анализатор из пакетного менеджера, однако есть возможность развернуть анализатор из командной строки:
PVS-Studio_setup.exe /verysilent /suppressmsgboxes
/norestart /nocloseapplications
Подробнее о развёртывании PVS-Studio в системах под управлением Windows можно почитать *
После установки нужно запустить непосредственно анализ. Однако делать это рекомендуется только после того, как прошла компиляция и тесты. Это связано с тем, что для статического анализа обычно требуется в два раза больше времени, чем для компиляции.
Так как способ запуска зависит от платформы и особенностей проекта, я покажу вариант для C++ (Linux) в качестве примера:
pvs-studio-analyzer analyze -j8 \
-o PVS-Studio.log
plog-converter -t errorfile PVS-Studio.log --cerr -w
Первая команда выполнит анализ, а вторая
Примечание. Текстовый формат — это неудобно. Он приводится просто для примера. Обратите внимание на более интересный формат отчёта — FullHtml. Он позволяет осуществлять навигацию по коду.
Подробнее про настройку анализа на CI можно прочитать в статье "
Хорошо, вы настроили работу анализатора на сборочном сервере. Теперь, если кто-то залил непроверенный код, будет падать этап проверки, и вы сможете обнаружить проблему, однако это не совсем удобно, так как эффективнее проверять проект не после того, как произошло слияние веток, а до него, на этапе pull request'а.
В целом настройка анализа pull request'а не сильно отличается от обычного запуска анализа на CI. За исключением необходимости получить список изменённых файлов. Обычно их можно получить, запросив разницу между ветками при помощи git:
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
Теперь нужно передать анализатору на вход этот список файлов. Например, в PVS-Studio это реализовано при помощи флага -S:
pvs-studio-analyzer analyze -j8 \
-o PVS-Studio.log \
-S .pvs-pr.list
Подробнее про анализ pull request'ов можно узнать *
Настроив анализ pull request'ов вы сможете блокировать содержащие предупреждения коммиты, тем самым создав границу, которую непроверенный код не сможет пересечь.
Это всё безусловно хорошо, однако хотелось бы иметь возможность посмотреть все предупреждения в одном месте. Не только от статического анализатора, но и от юнит-тестов или от динамического анализатора. Для это существуют различные сервисы и плагины. PVS-Studio, например, имеет
2. Интеграция на машины разработчиков
Теперь пришло время установки и настройки анализатора для повседневного использования при разработке. К этому моменту вы уже познакомились с большей частью способов работы, поэтому это можно назвать самой лёгкой частью.
Как самый простой вариант – разработчики сами могут установить необходимый анализатор. Однако это займёт много времени и отвлечёт их от разработки, поэтому вы можете автоматизировать этот процесс, используя установщик и нужные флаги. Для PVS-Studio есть различные
Затем нужно будет установить необходимые плагины, например, для
3. Ежедневное использование
На этом этапе пора сказать пару слов о способах ускорения работы анализатора при ежедневном использовании. Полный анализ всего проекта занимает очень много времени, однако часто ли мы меняем код разом во всём проекте? Едва ли существует настолько масштабный рефакторинг, что сразу затронет всю кодовую базу. Количество изменяемых файлов за раз редко превышает десяток, поэтому их и есть смысл анализировать. Для подобной ситуации существует
В случае, если анализатор обнаружит в недавно измененном коде проблемы, то сообщит об этом самостоятельно. Например, PVS-Studio скажет вам об этом при помощи оповещения:
Само собой недостаточно сказать разработчикам использовать инструмент. Нужно как-то им рассказать, что это вообще и как это есть. Вот, например, статьи про быстрый старт для PVS-Studio, однако подобные туториалы вы сможете найти для любого предпочитаемого вами инструмента:
Подобные статьи дают всю необходимую для повседневного использования информацию и не отнимают много времени.
Ещё на этапе знакомства с инструментом мы подавили очень много предупреждений во время одного из первых запусков. Увы, но статические анализаторы не идеальны, поэтому время от времени выдают ложные срабатывания. Подавить их обычно легко, например в плагине PVS-Studio для Visual Studio достаточно нажать на одну кнопку:
Однако вы можете не только подавлять их. Например, вы можете сообщить в поддержку о наличии проблемы. Если ложное срабатывание возможно исправить, то в будущих обновлениях вы можете обратить внимание на то, что с каждым разом становится всё меньше и меньше специфичных для вашей кодовой базы ложных срабатываний.
После интеграции
Вот мы и прошли все этапы по интеграции статического анализа в процесс разработки. Несмотря на важность настройки подобных инструментов на CI, самым главным местом запуска является именно компьютер разработчика. Ведь статический анализатор – это не судья, который говорит где-то далеко от вас, что код никуда не годится. Напротив, это помощник, который подсказывает, если вы устали и напоминает, если вы о чём-либо забыли.
Правда без регулярного использования статический анализ вряд ли значительно упростит разработку. Ведь самая его главная польза для разработчика заключается не столько в поиске сложных и спорных участков кода, сколько в раннем их обнаружении. Согласитесь, что обнаружить проблему, когда правки ушли на тестирование, не только неприятно, но и очень долго. Статический анализ же при регулярном использовании просматривает каждое изменение прямо на вашем компьютере и сообщает о подозрительных местах во время работы над кодом.
А если вы или ваши коллеги всё ещё не уверены, стоит ли внедрять анализатор, то предлагаю сейчас перейти к чтению статьи "
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Maxim Zvyagintsev.

Собственно говоря, если вы пишете на каком-либо современном языке, тогда, даже не догадываясь об этом, вы пропускали его через статический анализатор. Дело в том, что любой современный компилятор предоставляет пусть и крохотный, но набор предупреждений о потенциальных проблемах в коде. Например, компилируя C++ код в Visual Studio вы можете увидеть следующее:

В этом выводе мы видим, что переменная var так и не была использована нигде в функции. Так что на самом деле вы почти всегда пользовались простеньким статическим анализатором кода. Однако, в отличие от профессиональных анализаторов, таких как Coverity, Klocwork или PVS-Studio, предоставляемые компилятором предупреждения могут указывать только на небольшой спектр проблем.
Если вы не знаете наверняка, что такое статический анализ и как его внедрять,
You must be registered for see links
, чтобы более подробно ознакомиться с этой методологией. Зачем нужен статический анализ?
В двух словах: ускорение и упрощение.
Статический анализ позволяет найти уйму различных проблем в коде: начиная от неправильного использования конструкций языка, заканчивая опечатками. Например, вместо
auto x = obj.x;
auto y = obj.y;
auto z = obj.z;
Вы написали следующий код:
auto x = obj.x;
auto y = obj.y;
auto z = obj.x;
Как видите, в последней строке появилась опечатка. Например, PVS-Studio выдаёт следующее предупреждение:
You must be registered for see links
Consider reviewing the correctness of 'y' item's usage.Если хотите потыкать в эту ошибку руками, то попробуйте готовый пример на Compiler Explorer: *
You must be registered for see links
*.И как вы понимаете, не всегда можно обратить внимания на подобные участки кода сразу и из-за этого можно засесть за отладку на добрый час, недоумевая, почему всё работает так странно.
Однако это явная ошибка. А если разработчик написал неоптимальный код из-за того, что позабыл какую-либо тонкость языка? Или же вовсе допустил в коде
You must be registered for see links
? К сожалению, подобные случаи совершенно обыденны и львиная часть времени тратится на то, чтобы отладить специфично работающий код, который содержит опечатки, типичные ошибки или undefined behavior.Именно для этих ситуаций и появился статический анализ. Это помощник для разработчика, который укажет ему на различные проблемы в коде и объяснит в документации почему так писать не нужно, к чему это может привести и как это исправить. Вот пример как это может выглядеть: *
You must be registered for see links
*.Больше интересных ошибок, которые может обнаружить анализатор, вы можете найти в статьях:
-
You must be registered for see links
-
You must be registered for see links
-
You must be registered for see links
Теперь, прочитав этот материал и убедившись в пользе статического анализа, вы могли захотеть испытать его в деле. Но с чего начать? Как интегрировать новый инструмент в текущий проект? И как познакомить команду с ним? На эти вопросы вы найдёте ответы ниже.
Примечание. Статический анализ не заменяет и не отменяет такую полезную вещь, как обзоры кода. Он дополняет этот процесс, помогая заранее заметить и исправить опечатки, неточности, опасные конструкции. Намного продуктивнее сосредоточиться при обзорах кода на алгоритмах и понятности кода, а не над высматриванием не там поставленной скобки или
You must be registered for see links
.0. Знакомство с инструментом
Всё начинается с пробной версии. Действительно, сложно решиться внедрять что-либо в процесс разработки, если никогда до этого не видел инструмента вживую. Поэтому первым делом стоит скачать
You must be registered for see links
.Что вы узнаете на этом этапе:
- Какие есть способы взаимодействия с анализатором;
- Совместим ли анализатор с вашей средой разработки;
- Какие проблемы есть сейчас в ваших проектах.
После того, как вы установили себе всё необходимое, то первым делом стоит запустить анализ всего проекта (
You must be registered for see links
,
You must be registered for see links
,
You must be registered for see links
). В случае с PVS-Studio в Visual Studio вы увидите подобную картину (кликабельно):
Дело в том, что обычно на проекты с большой кодовой базой статические анализаторы выдают огромное количество предупреждений. Нет необходимости исправлять их все, так как ваш проект уже работает, а значит эти проблемы не являются критичными. Однако вы
You must be registered for see links
и исправить их при необходимости. Для этого нужно отфильтровать вывод и оставить только наиболее достоверные сообщения. В плагине PVS-Studio для Visual Studio это делается фильтрацией по уровням и категориям ошибок. Для наиболее точного вывода оставьте включёнными только High и General (тоже кликабельно):
Действительно, 178 предупреждений просмотреть значительно проще, чем несколько тысяч…
Во вкладках Medium и Low часто попадаются хорошие предупреждения, однако в эти категории занесены те диагностики, которые имеют меньшую точность (достоверность). Подробнее про уровни предупреждений и варианты работы под Windows можно посмотреть тут: *
You must be registered for see links
*.Успешно просмотрев самые интересные ошибки (и успешно исправив их) стоит
You must be registered for see links
. Это нужно для того, чтобы новые предупреждения не терялись среди старых. К тому же статический анализатор – это помощник для программиста, а не список для багов. 1. Автоматизация
После знакомства наступает время настройки плагинов и интеграции в CI. Это необходимо сделать до того, как программисты начнут использовать статический анализатор. Дело в том, что программист может забыть включить анализ или вовсе не захотеть. Для этого нужно сделать некоторую финальную проверку всего, чтобы непроверенный код не мог попасть в общую ветку разработки.
Что вы узнаете на данном этапе:
- Какие варианты автоматизации предоставляет инструмент;
- Совместим ли анализатор с вашей сборочной системой.
Так как идеальной документации не существует, иногда приходится писать в
You must be registered for see links
. Это нормально, и мы рады вам помочь. А теперь приступим к сервисам непрерывной интеграции (CI). Любой анализатор можно внедрить в них без каких-либо серьезных проблем. Для этого нужно создать отдельный этап в pipeline, который обычно находится после сборки и юнит-тестов. Делается это при помощи различных консольных утилит. Например, PVS-Studio предоставляет следующие утилиты:
-
You must be registered for see links(анализ решений, C#, C++ проектов на Windows)
-
You must be registered for see links(мониторинг компиляции)
-
You must be registered for see links(анализ C++ проектов на Linux / macOS)
-
You must be registered for see links(анализ решений, C# проектов на Linux / macOS)
-
You must be registered for see links(анализ Java проектов)
-
You must be registered for see links(конвертер файлов отчёта)
Для интеграции анализа в CI нужно сделать три вещи:
- Установить анализатор;
- Запустить анализ;
- Доставить результаты.
Например, для установки PVS-Studio на Linux (Debian-base) нужно выполнить следующие команды:
wget -q -O -
You must be registered for see links
\| sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list \
You must be registered for see links
sudo apt-get update -qq
sudo apt-get install -qq pvs-studio
В системах под управлением Windows отсутствует возможность установить анализатор из пакетного менеджера, однако есть возможность развернуть анализатор из командной строки:
PVS-Studio_setup.exe /verysilent /suppressmsgboxes
/norestart /nocloseapplications
Подробнее о развёртывании PVS-Studio в системах под управлением Windows можно почитать *
You must be registered for see links
*.После установки нужно запустить непосредственно анализ. Однако делать это рекомендуется только после того, как прошла компиляция и тесты. Это связано с тем, что для статического анализа обычно требуется в два раза больше времени, чем для компиляции.
Так как способ запуска зависит от платформы и особенностей проекта, я покажу вариант для C++ (Linux) в качестве примера:
pvs-studio-analyzer analyze -j8 \
-o PVS-Studio.log
plog-converter -t errorfile PVS-Studio.log --cerr -w
Первая команда выполнит анализ, а вторая
You must be registered for see links
рует отчёт в текстовый формат, выведет его на экран и вернёт отличный от 0 код возврата в случае наличия предупреждений. Подобный механизм удобно использовать для блокировки сборки при наличии сообщений об ошибках. Однако, вы всегда можете убрать флаг -w и не блокировать сборку, содержащую предупреждения.Примечание. Текстовый формат — это неудобно. Он приводится просто для примера. Обратите внимание на более интересный формат отчёта — FullHtml. Он позволяет осуществлять навигацию по коду.
Подробнее про настройку анализа на CI можно прочитать в статье "
You must be registered for see links
" (Windows) или "
You must be registered for see links
" (Linux).Хорошо, вы настроили работу анализатора на сборочном сервере. Теперь, если кто-то залил непроверенный код, будет падать этап проверки, и вы сможете обнаружить проблему, однако это не совсем удобно, так как эффективнее проверять проект не после того, как произошло слияние веток, а до него, на этапе pull request'а.
В целом настройка анализа pull request'а не сильно отличается от обычного запуска анализа на CI. За исключением необходимости получить список изменённых файлов. Обычно их можно получить, запросив разницу между ветками при помощи git:
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
Теперь нужно передать анализатору на вход этот список файлов. Например, в PVS-Studio это реализовано при помощи флага -S:
pvs-studio-analyzer analyze -j8 \
-o PVS-Studio.log \
-S .pvs-pr.list
Подробнее про анализ pull request'ов можно узнать *
You must be registered for see links
*. Даже если вашего CI нет в списке указанных в статье сервисов, вам будет полезен общий раздел, посвященный теории этого типа анализа.Настроив анализ pull request'ов вы сможете блокировать содержащие предупреждения коммиты, тем самым создав границу, которую непроверенный код не сможет пересечь.
Это всё безусловно хорошо, однако хотелось бы иметь возможность посмотреть все предупреждения в одном месте. Не только от статического анализатора, но и от юнит-тестов или от динамического анализатора. Для это существуют различные сервисы и плагины. PVS-Studio, например, имеет
You must be registered for see links
.2. Интеграция на машины разработчиков
Теперь пришло время установки и настройки анализатора для повседневного использования при разработке. К этому моменту вы уже познакомились с большей частью способов работы, поэтому это можно назвать самой лёгкой частью.
Как самый простой вариант – разработчики сами могут установить необходимый анализатор. Однако это займёт много времени и отвлечёт их от разработки, поэтому вы можете автоматизировать этот процесс, используя установщик и нужные флаги. Для PVS-Studio есть различные
You must be registered for see links
. Впрочем, всегда есть пакетные менеджеры, например, Chocolatey (Windows), Homebrew (macOS) или десятки вариантов для Linux.Затем нужно будет установить необходимые плагины, например, для
You must be registered for see links
,
You must be registered for see links
,
You must be registered for see links
etc.3. Ежедневное использование
На этом этапе пора сказать пару слов о способах ускорения работы анализатора при ежедневном использовании. Полный анализ всего проекта занимает очень много времени, однако часто ли мы меняем код разом во всём проекте? Едва ли существует настолько масштабный рефакторинг, что сразу затронет всю кодовую базу. Количество изменяемых файлов за раз редко превышает десяток, поэтому их и есть смысл анализировать. Для подобной ситуации существует
You must be registered for see links
. Только не пугайтесь, это не ещё один инструмент. Это специальный режим, который позволяет анализировать только изменённые файлы и их зависимости, причём это происходит автоматически после сборки, если вы работаете в IDE c установленным плагином. В случае, если анализатор обнаружит в недавно измененном коде проблемы, то сообщит об этом самостоятельно. Например, PVS-Studio скажет вам об этом при помощи оповещения:

Само собой недостаточно сказать разработчикам использовать инструмент. Нужно как-то им рассказать, что это вообще и как это есть. Вот, например, статьи про быстрый старт для PVS-Studio, однако подобные туториалы вы сможете найти для любого предпочитаемого вами инструмента:
-
You must be registered for see links
-
You must be registered for see links
-
You must be registered for see links
Подобные статьи дают всю необходимую для повседневного использования информацию и не отнимают много времени.
Ещё на этапе знакомства с инструментом мы подавили очень много предупреждений во время одного из первых запусков. Увы, но статические анализаторы не идеальны, поэтому время от времени выдают ложные срабатывания. Подавить их обычно легко, например в плагине PVS-Studio для Visual Studio достаточно нажать на одну кнопку:

Однако вы можете не только подавлять их. Например, вы можете сообщить в поддержку о наличии проблемы. Если ложное срабатывание возможно исправить, то в будущих обновлениях вы можете обратить внимание на то, что с каждым разом становится всё меньше и меньше специфичных для вашей кодовой базы ложных срабатываний.
После интеграции
Вот мы и прошли все этапы по интеграции статического анализа в процесс разработки. Несмотря на важность настройки подобных инструментов на CI, самым главным местом запуска является именно компьютер разработчика. Ведь статический анализатор – это не судья, который говорит где-то далеко от вас, что код никуда не годится. Напротив, это помощник, который подсказывает, если вы устали и напоминает, если вы о чём-либо забыли.
Правда без регулярного использования статический анализ вряд ли значительно упростит разработку. Ведь самая его главная польза для разработчика заключается не столько в поиске сложных и спорных участков кода, сколько в раннем их обнаружении. Согласитесь, что обнаружить проблему, когда правки ушли на тестирование, не только неприятно, но и очень долго. Статический анализ же при регулярном использовании просматривает каждое изменение прямо на вашем компьютере и сообщает о подозрительных местах во время работы над кодом.
А если вы или ваши коллеги всё ещё не уверены, стоит ли внедрять анализатор, то предлагаю сейчас перейти к чтению статьи "
You must be registered for see links
". В ней разобраны типовые опасения разработчиков о том, что статический анализ будет отнимать их время и так далее.
You must be registered for see links
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Maxim Zvyagintsev.
You must be registered for see links
.