В PVS-Studio уже некоторое время есть плагины для таких IDE от JetBrains, как Rider, IntelliJ IDEA и Android Studio. Другую известную среду разработки, CLion, мы долгое время незаслуженно обходили стороной. Исправляемся! Но зачем вообще вам PVS-Studio, если в CLion уже есть анализ кода? Какие проблемы возникли при разработке? На эти вопросы мы ответим ниже.
Сразу хочу оговориться, что в статье не будет какой-то техно-жести. Это, скорее, история об интересных моментах и проблемах, возникших в процессе разработки. Расслабляющее чтиво на вечер, если хотите. ;)
Примечание. Кстати, на сайте JetBrains есть результаты различных опросов за 2021 год: по используемым стандартам языка, IDE, инструментам и т.п. Рекомендую посмотреть, это интересно. CLion входит в тройку наиболее используемых IDE / редакторов. А какую среду разработки для C / C++ используете вы?
Зачем мне PVS-Studio, если в CLion уже есть статический анализ?
Рад, что вы спросили! Позвольте рассказать об этом на примере небольшой истории.
JetBrains ведут отдельный Twitter-аккаунт о CLion, где делятся различными новостями, рассказывают о новых возможностях IDE и т.п. В одном из твиттов был продемонстрирован пример работы межпроцедурного анализа потока данных (как они его называют, global DFA).
В примере демонстрируется, как статический анализ умеет обнаруживать разыменование нулевого указателя buffer, полученного из функции foo, в bar. Андрей, наш DevRel, решил немного модифицировать пример и посмотреть, как CLion поведёт себя с ним.
Итого: всё то же одно предупреждение со стороны CLion. В это же время PVS-Studio сообщает уже о двух проблемах:
V522 There might be dereferencing of a potential null pointer 'buffer'.
V611 The memory was allocated using 'new' operator but was released using the 'free' function. Consider inspecting operation logics behind the 'buffer' variable.
Здесь и кроется ответ на вопрос, который мы обсуждаем, – связка CLion и PVS-Studio позволит вам выявлять ещё больше проблем на этапе написания кода. CLion позволит подсвечивать ошибки "on the fly", но из-за этого же будет несколько ограничен в возможностях анализа. PVS-Studio же не подсвечивает ошибки непосредственно во время набора кода, но при этом способен проводить более глубокий анализ. На всякий случай уточню, что в PVS-Studio есть инкрементальный анализ - режим работы, когда анализируются только изменённые файлы.
В итоге выходит, что анализ в CLion и анализ в PVS-Studio не заменяют, а дополняют друг друга. А если ещё предупреждения компилятора выкрутить... :)
Второе рождение
Сказать по правде, прототип плагина для CLion у нас уже был... несколько лет. Да, какое-то время назад мы начали разработку, но закончить её тогда по ряду причин было не суждено. В итоге прототип отправился "на полку".
Сейчас же, когда пользователи стали проявлять всё больше и больше интереса, было решено всё-таки закончить начатое. Точнее, было несколько возможных путей: либо попробовать доработать существующий прототип, либо сделать всё заново.
Спойлер: оба пути оказались тернистыми.
После того как исходники прототипа были найдены в системе контроля версий, мы решили оценить степень его готовности. Вдруг доделать нужно совсем немного? На удивление код даже сходу скомпилировался, что сразу настроило на позитивный лад.
Примечание. Привет из C# отдела! Чуть больше года назад мы портировали C# анализатор под Linux и macOS. И вот что интересно – запустить анализатор под Linux удалось в первый же день работы над задачей! При этом релиз PVS-Studio C# для Linux/macOS состоялся через полгода. К разговору о том, сколько может быть нюансов...
Несмотря на то, что код компилировался и какая-то функциональность уже была в прототипе, его ещё нужно было полноценно интегрировать в IDE. При этом будущий плагин должен иметь основные общие черты, присущие другим плагинам PVS-Studio для IDE от JetBrains: Rider, IntelliJ IDEA, Android Studio. Понятно, что какая-то специфика будет, но в общем и целом пользователь, пробующий связку PVS-Studio с разными IDE, должен +/- придерживаться одинаковых сценариев работы с анализатором, взаимодействовать с одинаковыми настройками и UI.
В итоге за основу попробовали взять одно из уже готовых решений – наиболее подходящим кандидатом оказался плагин для Rider. Однако быстро выяснилось, что сходу переиспользовать эти наработки для CLion не получится — слишком много специфики.
Здесь может возникнуть естественный вопрос: а не легче ли сделать основу с нуля? Взять готовый 'шаблон' и навесить на него имеющийся функционал из прототипа? Что ж, можно попробовать.
Где взять шаблон, как не на официальном сайте JetBrains? Такой действительно нашёлся, однако после загрузки выяснилось, что пример... не компилируется.
После недолгого разбирательства стало понятно, что пример был создан для более старых версий CLion. В новых поменялся API – отсюда и проблемы.
Что интересно, в блоге JetBrains есть инструкция, в которой объясняется, что и как нужно исправить в примере, чтобы он заработал. Правки помогли запустить пример, хотя сам подход вызывает вопросы – почему бы просто не сделать отдельный пример?
В итоге, после совмещения прототипа с шаблоном выяснилось, что... ничего не работает. Здесь может возникнуть порыв выкинуть прототип и вообще всё написать с нуля. Кажется, для этого нужно всего лишь немного документации – описание API взаимодействия с IDE. Но не тут-то было.
Результаты поисков документации по API были примерно такими:
Без шуток, на сайте JetBrains не удалось ничего найти. Совсем. Перебирать все доступные классы для поиска нужных – идея, скажем прямо, сомнительная. Наши разработчики, которые делали плагин PVS-Studio для Rider, подтвердили опасения – документации нет.
Если доки всё же есть и вы знаете, где именно, просьба написать в комментариях. И нам пригодится, и другим полезно будет.
Пожалуй, хватит уже метаний и порывов всё сделать с 0 – нужно дорабатывать то, что есть. Возможно, будет больно, но явно легче, чем начинать разработку заново. Это решение оказалось правильным, так как после некоторого времени, проведённого за отладкой и правками, оказалось, что в целом прототип уже делал то, что нужно. Как следствие, удалось достаточно быстро научить его получать список файлов исходного кода из проекта.
Код постепенно переносился, плагин обрастал функциональностью и в итоге стал делать то, что нужно. Но только под Windows, так как под этой ОС и велась основная разработка. Несмотря на то, что код сразу писался с заделом на кроссплатформенность, без нюансов никуда — поэтому дополнительно пришлось сделать несколько доработок после тестирования под Linux и macOS.
В некоторых случаях отделаться правками лишь кода плагина не удалось. Приходилось погружаться и в ядро C++ анализатора. Мультиязыковая задача получилась — пригодились знания как Java, так и C++.
Глобальных доработок было две:
в C++ анализаторе теперь учитываются переменные окружения при анализе через JSON Compilation DB;
также анализатор научили выдавать обнаруженные проблемы постепенно, по мере работы, а не всё скопом после того, как всё было проанализировано. Это позволило добавить больше интерактивности. Теперь при работе с плагином не нужно дожидаться окончания анализа, чтобы начать разбирать ошибки. Делать это можно в уже процессе работы.
Как попробовать?
Если бы итог всей этой истории не был очевиден, то и статьи не было бы. Интриги тут, увы, не вышло. :)
Плагин PVS-Studio для CLion уже доступен для использования.
Чтобы попробовать, нужно:
запросить триальную лицензию;
установить сам анализатор и плагин.
Запросить лицензию и загрузить анализатор можно здесь. Кстати, по указанной ссылке можно получить лицензию не на 7, а на 30 дней. ;)
С установкой плагина всё тоже достаточно просто. Подробности описаны в соответствующем разделе документации: как установить плагин, ввести лицензию и что вообще делать дальше.
Пробуйте, пользуйтесь, пишите нам, если вдруг что-то не работает или есть идеи по улучшению интеграции.
Ну и напоследок не можем не закинуть вопрос: интеграцию PVS-Studio с какой IDE / редактором вам было бы интересно видеть? Может быть с Visual Studio Code? ;)
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Evgeniy Ovsyannikov, Sergey Vasiliev. PVS-Studio for JetBrains CLion: ad astra per aspera.