Проблемы legacy-кода знакомы подавляющему большинству разработчиков программного обеспечения. Процесс превращения кода в legacy неизбежен, ведь прогресс в программировании не стоит на месте. Проекты либо «умирают» навсегда, либо требуют постоянной поддержки и написания новых функций. Таким образом, в любом проекте на любом языке программирования legacy-код возникает и доставляет разные неудобства при дальнейшей разработке. На примере PVS-Studio, в этой статье я расскажу, как сразу начать использовать статический анализатор кода в своём проекте.

Введение


Для начала разберёмся в определении legacy-кода и познакомимся со статическим анализатором PVS-Studio.

Не всегда термин legacy связан с возрастом кода. Вот некоторые самые распространённые определения:

  1. Код не покрыт тестами — обычно очень серьёзный повод как можно меньше вносить изменения в такой код;
  2. Устаревший код — давно забыто, как он работает. А если он ещё и тестами не покрыт, то ситуация совсем печальная, ведь код ещё используется и требует поддержки.
  3. Код сторонних разработчиков — похоже на предыдущее определение, но даже в новом чужом коде могут возникнуть описанные проблемы;
  4. Код сохранён для совместимости — такой код обычно стар и с большой вероятностью не тестируется с тем, с чем должен быть совместим;
  5. Другие схожие определения.

В любой из описанных ситуаций разработчики стараются как можно аккуратнее изменять код при разработке проекта, чтобы ничего не сломать. Дополнительно в проекте могут использоваться методики и инструменты для написания более эффективного и качественного кода. В таком случае, в старый код может потребоваться внести ещё больше изменений. В качестве нескольких примеров можно привести использование современного стандарта языка, соответствие некому style guide и внедрение статического анализатора кода. К сожалению, любая из этих идей сталкивается с препятствием в виде legacy-кода. Он может быть повсюду: его невозможно отделить как файлы тестов или сторонних библиотек. Практически все инструменты, предлагающие модификацию кода, имеют возможность размечать код для отключения предупреждений, но на практике этот способ невозможно применить. При первом использовании такого инструмента никто не позволит разметить сотни файлов исходного кода тысячами комментариев — это очень большой объём изменённого кода, из-за которого просмотр изменений в системах SCM (Source Control Management) станет очень сложным. Поэтому для статического анализатора PVS-Studio была разработана система массового подавления предупреждений без необходимости модифицировать исходные файлы проекта. Такая возможность позволяет легко внедрить анализатор в любой проект и СРАЗУ начать получать выгоду от этого, т.е. находить новые ошибки.

PVS-Studio — статический анализатор для выявления ошибок в исходном коде программ, написанных на языках С, C++ и C#. Умеет запускаться на Windows и Linux, интегрироваться в сборочные системы, различные IDE и системы непрерывной интеграции.

Принцип работы


Механизм подавления основан на использовании специальных файлов «баз» сообщений анализатора, которые добавляются рядом с проектом. Эти файлы содержат сообщения, размеченные для данного проекта как «ненужные». При последующих проверках файлов данного проекта анализатором, он автоматически будет проверять наличие таких файлов рядом с проектом и, в случае их обнаружения, не будет показывать сообщения, которые содержатся в такой «базе». Заметим, что модификация исходного файла, содержащего размеченные сообщения, и, в частности, сдвиг строк, не приведёт к повторному появлению этих сообщений. Однако, правка строки, содержащей это сообщение, может привести к его повторному появлению, т.к. такое сообщение уже становится «новым».

Использование механизма подавления в Visual Studio (Windows)


Для Microsoft Visual Studio доступен плагин PVS-Studio, удобно интегрированный в IDE. Он позволяет запускать анализ всего solution, конкретных проектов или файлов, а также поддерживает инкрементальный анализ.

В меню PVS-Studio (рисунок 1) доступен пункт «Suppress Messages...», открывающий окно для работы с подавленными предупреждениями анализатора (рисунок 2).

Рисунок 1 - Меню PVS-Studio в Visual Studio


Рисунок 1 — Меню PVS-Studio в Visual Studio

Рисунок 2 - Окно для подавления предупреждений анализатора


Рисунок 2 — Окно для подавления предупреждений анализатора

В открывшемся окне доступно несколько действий:

  1. Suppress Current Messages — подавление всех предупреждений анализатора;
  2. Clear Selected Files — восстановление скрытых предупреждений для всех или некоторых проектов;
  3. Display Suppressed Messages — отображение скрытых предупреждений анализатора в окне (PVS-Studio Output Window) с остальными предупреждениями. В этом режиме можно вернуться к исправлению подавленных ранее предупреждений. Такие сообщения будут помечены особым образом (зачёркнуты), поэтому их невозможно спутать с другими.

Для просмотра результатов анализа в Visual Studio существует специальное окно (рисунок 3).

Рисунок 3 - PVS-Studio Output Window


Рисунок 3 — PVS-Studio Output Window

Специальное окно позволяет выполнять навигацию по найденным предупреждениям и переходить к коду для его исправления. Окно PVS-Studio предоставляет широкие возможности фильтрации и сортировки результатов. Также присутствует возможность быстрого перехода к документации выбранной диагностики.

Дополнительные возможности работы с каждым сообщением доступны в контекстном меню по нажатию на правый клик мыши на сообщении (рисунок 4). Здесь доступна команда для подавления выделенного предупреждения. При открытии меню на уже подавленном предупреждении будет доступен пункт для возвращения срабатывания.

Рисунок 4 - Контекстное меню предупреждения анализатора


Рисунок 4 — Контекстное меню предупреждения анализатора

Использование механизма подавления в Standalone (Windows)


PVS-Studio можно использовать независимо от интегрированной среды разработки Visual Studio. Инструмент Standalone предоставляет возможности для проверки кода, независимо от используемого компилятора или сборочной системы, а затем позволяет работать с результатами анализа, предоставляя пользовательский интерфейс, схожий с Visual Studio плагином PVS-Studio (рисунок 5).

Рисунок 5 - PVS-Studio Standalone


Рисунок 5 — PVS-Studio Standalone

Также Standalone позволяет работать и с отчётом анализатора, полученным с помощью прямой его интеграции в сборочную систему, при отсутствии у пользователя среды Visual Studio.

Меню Standalone для запуска анализа и подавления предупреждений выглядит следующим образом (рисунок 6).

Рисунок 6 - Меню Tools утилиты Standalone


Рисунок 6 — Меню Tools утилиты Standalone

При выборе пункта меню для запуска анализа появится окно «Compiler Monitoring (C/C++)» (рисунок 7).

Рисунок 7 - Диалог запуска мониторинга сборки


Рисунок 7 — Диалог запуска мониторинга сборки

Для фильтрации предупреждений анализатора, перед анализом необходимо указать файл с подавленными ранее предупреждениями. Создать и пополнять такой файл можно через меню «Message Suppression...», которое является таким же, как было представлено в разделе про Visual Studio на рисунке 2. После завершения анализа в окне PVS-Studio будут отображены только новые ошибки. Без указания файла анализатор выдаст все результаты.

Использование механизма подавления в Linux


В Linux команды подавления и фильтрации сообщений анализатора выполняются только в консоли, но при автоматизации их на сервере, механизм подавления сообщений становится очень удобным.

Есть несколько способов использования этого механизма, в зависимости от варианта интеграции анализатора.

Анализ с помощью утилиты pvs-studio-analyzer


Для подавления всех предупреждений анализатора (первый раз и в последующих случаях) необходимо выполнять команду:

pvs-studio-analyzer suppress /path/to/report.log

Анализ проекта можно запускать как прежде. При этом подавленные предупреждения будут фильтроваться:

pvs-studio-analyzer analyze ... -o /path/to/report.log
plog-converter ...

При таком запуске подавленные предупреждения будут сохраняться в текущем каталоге в файле с именем suppress_base.json, который надо хранить с проектом. Новые подавленные предупреждения будут дописываться в этот файл. Если необходимо указать другое имя или расположение файла, то команды выше можно дополнить, указав путь до файла с подавленными предупреждениями.

Прямая интеграция анализатора в сборочную систему


Прямая интеграция анализатора может выглядеть следующим образом:

.cpp.o:
  $(CXX) $(CFLAGS) $(DFLAGS) $(INCLUDES) $< -o $@
  pvs-studio --cfg $(CFG_PATH) --source-file $< --language C++
     --cl-params $(CFLAGS) $(DFLAGS) $(INCLUDES) $<

В этом режиме анализатор не может одновременно проверять исходные файлы и фильтровать их. Поэтому для фильтрации и подавления предупреждений потребуются дополнительные команды.

Для подавления всех предупреждений анализатора также необходимо выполнять команду:

pvs-studio-analyzer suppress /path/to/report.log

Для фильтрации нового лога необходимо воспользоваться следующими командами:

pvs-studio-analyzer filter-suppressed /path/to/report.log
plog-converter ...

Файл с подавленными предупреждениями также имеет имя по умолчанию suppress_base.json, для которого при необходимости можно задать произвольное имя.

Использование механизма подавления в SonarQube


SonarQube (бывший Sonar) — платформа с открытым исходным кодом для непрерывного анализа (англ. continuous inspection) и измерения качества кода.Пользователям этой системы доступен плагин для PVS-Studio. SonarQube сводит результаты анализа к единой информационной панели, ведя историю прогонов и позволяя тем самым увидеть общую тенденцию изменения качества программного обеспечения в ходе разработки. Дополнительным преимуществом является возможность объединять результаты разных анализаторов.

Так, получив результаты анализа одного или нескольких анализаторов, необходимо перейти к списку предупреждений и кликнуть на кнопку «Bulk Change», после чего откроется следующее меню (рисунок 8).

Рисунок 8 - Массовое изменение статуса ошибок


Рисунок 8 — Массовое изменение статуса ошибок

В этом окне можно разметить все предупреждения анализатора как «won't fix» и в дальнейшем работать только с новыми ошибками.

Что делать после подавления всех предупреждений?


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

Дополнительный контроль за качеством кода поможет обеспечить рассылка результатов по почте. Рассылать предупреждения только для тех разработчиков, которые внесли ошибочный код, возможно с помощью утилиты BlameNotifier, которая входит в дистрибутив PVS-Studio.

Некоторым может быть удобно загружать результаты в Jenkins или TeamCity с помощью плагина PVS-Studio, и рассылать ссылку на эту страницу.

Заключение


Пропуск предупреждений анализатора на legacy-коде — не единственный сценарий использования представленных механизмов. Массовое подавление предупреждений позволяет легко внедрить анализатор в любой проект и сразу начать получать выгоду от этого, т.е. находить новые ошибки. Такая реализация позволяет запланировать исправление пропущенных предупреждений в будущем, не отвлекая разработчиков от выполнения текущих задач. Также этот механизм может использоваться в дальнейшем для подавления ложных срабатываний и предупреждений, которые по тем или иным причинам не будут исправлены.

В статье приведены все возможные способы подавления предупреждений анализатора на данный момент. Собранный материал основывается на документации к анализатору PVS-Studio, но детали по этой теме были рассмотрены подробнее, чем в документации. Общие сведения могут быть не очень информативны для новых пользователей, поэтому следует ознакомиться с документацией по ссылкам ниже.

  1. Общие сведения о принципах работы с анализатором PVS-Studio;
  2. PVS-Studio Standalone;
  3. Как запустить PVS-Studio в Linux;
  4. Встраивание PVS-Studio в процесс непрерывной интеграции;
  5. Интеграция результатов анализа PVS-Studio в SonarQube;
  6. Работа с результатами анализа (.plog файл).

Альтернативным способом сведения количества предупреждений анализатора к нулю является исправление всех предупреждений анализатора на начальном этапе. Таким способом воспользовалась компания Epic Games в проекте Unreal Engine. Подробно об этом можно прочесть в статье: "Как команда PVS-Studio улучшила код Unreal Engine".



Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Svyatoslav Razmyslov. How to Step Over Legacy and Start Using Static Code Analysis

Прочитали статью и есть вопрос?
Часто к нашим статьям задают одни и те же вопросы. Ответы на них мы собрали здесь: Ответы на вопросы читателей статей про PVS-Studio, версия 2015. Пожалуйста, ознакомьтесь со списком.

Комментарии (15)


  1. LoadRunner
    31.08.2017 11:21

    А как дела с legacy-кодом в самом PVS-Studio?


    1. SvyatoslavMC Автор
      31.08.2017 11:41

      По определению — как у всех. Хотя с тестами и стат. анализаторами всё достаточно хорошо, т.к. это всё очень давно используется.

      А вот если применить что-нибудь из VS 2017 для Code Style, то без чего-нибудь подобного, о чём речь в статье, на нашем коде тоже невозможно пользоваться.


  1. TheKnight
    31.08.2017 13:13

    Два коротких вопроса:

    1. Swift?
    2. MacOS X?


    1. SvyatoslavMC Автор
      31.08.2017 14:00

      Короткий ответ


  1. eugenebb
    31.08.2017 16:33

    Супер, попробую купить.

    Если бы еще добавить возможность подключать custom plugins к вашей системе, вообще бы было клёво.

    А то приходится в добавок к своему анализатору писать всю обвязку, чтобы интегрироваться в VS & source control, а если была бы возможность воспользоваться существующей инфраструктурой PVS-Studio, думаю что многие бы оценили и воспользовались.

    Ну и заодно что-то типа marketplace / shareplace, чтобы можно было не изобретать велосипеды и/или поделится своим творением с сообществом.


    1. Andrey2008
      31.08.2017 16:56

      попробую купить

      Это дело хорошее. Ждем Вас в почте.

      Добавить возможность подключать custom plugins к вашей системе, вообще бы было клёво

      А вот здесь мы всегда были принципиально против и не планируем создавать такую систему. Кажется, что разрабатывать диагностики просто. Но на самом деле, сделать качественную диагностику очень, очень сложно и дорого (трудозатратно). Во-первых, это сложно просто практически. Например, создавая диагностику, мы смотрим как она работает, проверяя более 100 открытых проектов. Это итерационный процесс продолжается, пока мы не добьёмся приемлемых результатов качества. Во-вторых, при создании новых диагностик нам часто приходится добавлять новые интерфейсы в ядро для сбора нужных данных. Невозможно сделать набор интерфейсов и структур данных на все случаи жизни, тем более, что язык Си++ сейчас быстро развивается и появляются новые конструкции. Поэтому не получится сделать какой-то законченный интерфейс. Все равно пользователям будет нахватать то одного, то другого.

      Итого. Сторонние программисты будут тратить много времени и сил (а это дорого), на реализацию собственных диагностик. Плюс будут постоянно отвлекать нас.

      Поэтому всем намного проще, быстрее и дешевле, будет если мы просто реализуем на заказ особую диагностику. И мы временами это делаем (см. диагностики с номером V20xx).

      Хочу еще раз выделить, что такой подход правильный. Незачем делать что-то самим, если можно использовать специалистов. Нет смысла заставлять программистов мыть полы офисе. Это лучше, быстрее и дешевле, сделает специальный человек (уборщица).


      1. eugenebb
        31.08.2017 17:19

        Если вы разрабатываете диагностики на заказ, то на 80% я с вами согласен.

        Но мне кажется, что нельзя недооценивать силу opensource, особенно если предоставить правильные примеры для jumpstart, но это ИМХО, вам лучше видно как развивать бизнес. Тем более все это требует ресурсов и особенно в начале, очень не очевидно что будет возврат вложений.


    1. alexeiz
      01.09.2017 21:30

      Если бы еще добавить возможность подключать custom plugins к вашей системе, вообще бы было клёво.

      Вам нужен clang-analyzer: https://clang-analyzer.llvm.org/checker_dev_manual.html


  1. C-4
    31.08.2017 22:16
    +1

    Два вопроса: планируется ли интеграция с SharpDevelop и как запустить режим Standalone с этой средой, если это возможно вообще (у меня не взлетело)?


    1. SvyatoslavMC Автор
      31.08.2017 22:22

      Для проверки любого нестандартного C/C++ проекта всегда поможет утилита Standalone. Но в случае с C# она может выступать только просмотрщиком/редактором отчётов, полученных в Visual Studio. Интеграция с SharpDevelop сейчас не в приоритете.


    1. foto_shooter
      01.09.2017 00:07

      Т.к. SharpDevelop использует MSBuild в качестве сборочной системы (поправьте, если не прав), Вы можете попробовать проверить .sln или .csproj с помощью PVS-Studio_Cmd.exe. А для просмотра отчёта уже использовать, например, Standalone.

      Я попробовал на синтетическом проекте — получилось.


      1. C-4
        01.09.2017 09:43
        +1

        Отличная идея. Спасибо!


  1. eugenebb
    31.08.2017 23:09

    Как мне думается, было бы полезно иметь возможность добавить собственный комментарий чтобы он выводился совместно со стандартным сообщением (особенно в отчете с билд сервера), зачастую полезно чтобы быстро глянуть и не ходить на один и тот-же дефект, по несколько раз, плюс возможность overwrite severity конкретно этого дефекта.

    Что-то типа:

    // PVS: VS104 Overwrite: HIGH Ticket 112233 http://mycompany.com/tickets/1122233
    BYTE *dst_bits = FreeImage...
    

    и результат
    image


    1. SvyatoslavMC Автор
      31.08.2017 23:24
      -1

      быстро глянуть и не ходить на один и тот-же дефект, по несколько раз
      Вроде как вся статья о том, как избежать такого)

      Если необходимо передать дефект на дальнейшую обработку, то это и надо делать. Висеть багу в серверных логах — не правильный сценарий. Стоит открыть задачу в багтрекере или прям из этого интерфейса можно оставить TODO-комментарий в коде. По нашему опыту открытия баг-репортов в открытых проектах, их обсуждение может идти до полугода. Если в таком проекте регулярно использовать статический анализ и оперативно не обрабатывать результаты анализа, то это сделает работу с анализатором неудобным и быстро перерастёт в технический долг.


      1. eugenebb
        31.08.2017 23:41
        +2

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