Как перешагнуть через legacy и начать использовать статический анализ кода


    Проблемы 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. Пожалуйста, ознакомьтесь со списком.
    PVS-Studio
    794,46
    Static Code Analysis for C, C++, C# and Java
    Поделиться публикацией

    Комментарии 17

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

        А вот если применить что-нибудь из VS 2017 для Code Style, то без чего-нибудь подобного, о чём речь в статье, на нашем коде тоже невозможно пользоваться.
        0
        Два коротких вопроса:
        1. Swift?
        2. MacOS X?
      • НЛО прилетело и опубликовало эту надпись здесь
          0
          попробую купить

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

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

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

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

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

          Хочу еще раз выделить, что такой подход правильный. Незачем делать что-то самим, если можно использовать специалистов. Нет смысла заставлять программистов мыть полы офисе. Это лучше, быстрее и дешевле, сделает специальный человек (уборщица).
          • НЛО прилетело и опубликовало эту надпись здесь
            0
            Если бы еще добавить возможность подключать custom plugins к вашей системе, вообще бы было клёво.

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

            +1
            Два вопроса: планируется ли интеграция с SharpDevelop и как запустить режим Standalone с этой средой, если это возможно вообще (у меня не взлетело)?
              0
              Для проверки любого нестандартного C/C++ проекта всегда поможет утилита Standalone. Но в случае с C# она может выступать только просмотрщиком/редактором отчётов, полученных в Visual Studio. Интеграция с SharpDevelop сейчас не в приоритете.
                0
                Т.к. SharpDevelop использует MSBuild в качестве сборочной системы (поправьте, если не прав), Вы можете попробовать проверить .sln или .csproj с помощью PVS-Studio_Cmd.exe. А для просмотра отчёта уже использовать, например, Standalone.

                Я попробовал на синтетическом проекте — получилось.
                  +1
                  Отличная идея. Спасибо!
              • НЛО прилетело и опубликовало эту надпись здесь
                  –1
                  быстро глянуть и не ходить на один и тот-же дефект, по несколько раз
                  Вроде как вся статья о том, как избежать такого)

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

                  • НЛО прилетело и опубликовало эту надпись здесь

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое