Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
GBP
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
Инкрементальный анализ в PVS-Studio: те…

Инкрементальный анализ в PVS-Studio: теперь и на сборочном сервере

13 Фев 2017

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

Сценарии использования статического анализатора

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

0475_Improved_Incremental_Analysis_ru/image1.png

Почему же так важно обнаруживать и устранять ошибки как можно раньше? Я не буду здесь говорить о таких банальных вещах как репутационные риски, которые неизбежно возникнут, если ваши пользователи начнут массово обнаруживать дефекты в вашем программном обеспечении. Давайте сосредоточимся именно на экономической составляющей исправления ошибки в коде. У нас нет статистики по средней цене ошибки. Ошибки бывают очень разные, обнаруживаются на разных этапах жизненного цикла программного обеспечения, программное обеспечение может применяться в разных предметных областях, как критичных к ошибкам, так и не очень. Поэтому, хотя средняя по индустрии стоимость исправления дефекта в зависимости от стадии жизненного цикла ПО неизвестна, оценить изменение этой стоимости можно, используя известное правило "1-10-100". Применительно к разработке программного обеспечения, это правило утверждает, что если стоимость устранения дефекта на этапе разработки равна 1 ₽, то после передачи этого кода в тестирование составит уже 10 ₽, и вырастает до 100 ₽ после того, как код с дефектом ушел на продакшен:

0475_Improved_Incremental_Analysis_ru/image2.png

Существует множество причин для такого быстрого роста цены исправления дефекта, например:

  • Изменения в одной части кода могут затронуть множество других частей приложения.
  • Повторное выполнение уже сделанных задач: изменения в дизайне, кодирование, внесение корректировок в документацию и т.д.
  • Доставка исправленной версии пользователям, необходимость убедить пользователей обновиться.

Понимая важность того, что следует устранять ошибки на наиболее ранних этапах жизненного цикла ПО, мы предлагаем нашим клиентам использовать двухуровневую схему проверки кода статическим анализатором. Первый уровень – это проверка кода на компьютере разработчика перед тем, как код будет заложен в систему контроля версий. То есть разработчик пишет какой-то фрагмент кода и сразу инспектирует его статическим анализатором. Для этой задачи у нас есть плагин для Microsoft Visual Studio (поддерживаются все версии с 2010 до 2015 включительно). Плагин позволяет проверить один или несколько файлов исходного кода, один или несколько проектов или все решение целиком.

Второй уровень защиты - это запуск статического анализа во время ночной сборки проекта. Это позволяет убедиться, что новые ошибки не были добавлены в систему контроля версий, или же предпринять необходимые действия, чтобы эти ошибки исправить. Для того, чтобы минимизировать риск проникновения ошибок на более поздние этапы жизненного цикла ПО, мы предлагаем использовать оба уровня выполнения статического анализа: локально на машинах разработчиков и на централизованном сервере непрерывной интеграции.

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

Режим инкрементального анализа, позволяющий проверять только последние измененные файлы, помогает решить эти проблемы. Рассмотрим более подробно, какие преимущества может принести режим инкрементального анализа при использовании на компьютерах разработчиков и на сборочном сервере.

Инкрементальный анализ на компьютере разработчика - барьер на пути багов в систему контроля версий

Если команда разработчиков приняла решение использовать статический анализ кода, и анализ выполняется только на сборочном сервере, во время, например, ночных сборок, рано или поздно разработчики начнут статический анализатор воспринимать как врага. Неудивительно, ведь все члены команды будут видеть, какие ошибки допускают их коллеги. Мы стремимся к тому, чтобы все участники проекта воспринимали статический анализатор как друга и как полезный инструмент, который помогает улучшать качество кода. Для того, чтобы ошибки, которые может обнаруживать статический анализатор, не попадали в систему контроля версий и на всеобщее обозрение, статический анализ должен выполняться также и на компьютерах разработчиков, чтобы выявлять возможные проблемы в коде как можно раньше.

Как я уже упоминал, ручной запуск статического анализа на всей кодовой базе может потребовать достаточно продолжительного времени. Если же разработчик будет вынужден запоминать, над какими файлами с исходным кодом он работал, это также будет очень сильно раздражать.

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

Включить режим послесборочного инкрементального анализа можно в меню PVS-Studio/Incremental Analysis After Build (Modified Files Only), данный пункт активирован в PVS-Studio по умолчанию:

0475_Improved_Incremental_Analysis_ru/image3.png

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

0475_Improved_Incremental_Analysis_ru/image4.png

Подробности, связанные с использованием инкрементального анализа, рассмотрены в статье Режим инкрементального анализа PVS-Studio.

Инкрементальный анализ на сервере непрерывной интеграции - дополнительный барьер на пути багов

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

Одним из важных требований к задачам, выполняемым на сервере непрерывной интеграции, является то, что сборка проекта и выполнение всех дополнительных действий должны проходить быстро, чтобы команда могла оперативно отреагировать на обнаруженные проблемы. Выполнение статического анализа на большой кодовой базе после каждого коммита в систему контроля версий противоречит этому требованию, поскольку это может требовать весьма продолжительного времени. Мы были не согласны мириться с таким ограничением, поэтому посмотрели на наш плагин для Visual Studio, в котором уже давно существует режим инкрементального анализа, и спросили себя: а почему бы нам не реализовать такой же режим в модуле для командной строки PVS-Studio_Cmd.exe?

Сказано - сделано, и в нашем модуле для командной строки, который предназначен для интеграции статического анализатора в различные сборочные системы, появился режим инкрементального анализа. Этот режим работает так же, как инкрементальный анализ в плагине.

Таким образом, с добавлением поддержки инкрементального анализа в PVS-Studio_Cmd.exe стало возможно использовать наш статический анализатор в системе непрерывной интеграции во время многочисленных дневных сборок. За счет того, что будут проверены только измененные файлы с момента последнего обновления кода из системы контроля версий, статический анализ будет выполнен очень быстро, и продолжительность сборки проекта практически не увеличится.

Чтобы активировать режим инкрементального анализа в модуле для командной строки PVS-Studio_Cmd.exe, укажите ключ --incremental и задайте один из следующих режимов работы:

  • Scan – проанализировать все зависимости для определения того, на каких файлах должен быть выполнен инкрементальный анализ. Непосредственно анализ выполнен не будет.
  • Analyze – выполнить инкрементальный анализ. Этот шаг должен выполняться после выполнения шага Scan, и может выполняться как до, так и после сборки решения или проекта. Статический анализ будет выполнен только для измененных файлов с момента последней сборки.
  • ScanAndAnalyze - проанализировать все зависимости для определения того, на каких файлах должен быть выполнен инкрементальный анализ, и сразу же выполнить инкрементальный анализ измененных файлов с исходным кодом.

Для получения более подробной информации о режиме инкрементального анализа в модуле для командной строки PVS-Studio_Cmd.exe, обратитесь к статьям Режим инкрементального анализа PVS-Studio и Проверка Visual C++ (.vcxproj) и Visual C# (.csproj) проектов из командной строки с помощью PVS-Studio.

Хочу также отметить, что с функциональностью инкрементального анализа отлично сочетается использование утилиты BlameNotifier, поставляемой в дистрибутиве PVS-Studio. Эта утилита взаимодействует с популярными системами контроля версий (на данный момент поддерживаются Git, Svn и Mercurial), чтобы получить информацию о том, кто из разработчиков закоммитил код, содержащий ошибки, и разослать уведомления этим разработчикам.

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

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

Особенности реализации режима инкрементального анализа в PVS-Studio

Как я уже отметил, режим инкрементального анализа в плагине PVS-Studio для Visual Studio существует уже давно. В плагине определение измененных файлов, для которых должен выполняться инкрементальный анализ, было реализовано с помощью COM-оберток Visual Studio. Такой подход абсолютно неприменим для реализации режима инкрементального анализа в версии нашего анализатора для командной строки, поскольку он полностью независим от внутренней инфраструктуры Visual Studio. Поддержка разных реализаций, выполняющих одну и ту же функцию в разных компонентах, - не самая хорошая идея, поэтому мы сразу решили, что плагин для Visual Studio и утилита для командной строки PVS-Studio_Cmd.exe будут использовать общую кодовую базу.

Теоретически, задача по обнаружению модифицированных файлов с момента последней сборки проекта не представляет особой трудности. Для ее решения нам нужно получить время модификации целевого бинарного файла и время модификации всех файлов, участвовавших в построении целевого бинарного файла. Те файлы с исходным кодом, которые были изменены позднее, чем целевой файл, должны быть добавлены в список файлов для инкрементального анализа. Реальный мир, однако, гораздо сложнее. В частности, для проектов, реализованных на C или C++, весьма сложно определить все файлы, участвовавшие в построении целевого файла, например, те заголовочные файлы, которые были подключены напрямую в коде, и отсутствуют в проектном файле. Здесь я хочу отметить, что под Windows и наш плагин для Visual Studio (что очевидно), и версия для командной строки PVS-Studio_Cmd.exe поддерживают только анализ проектов MSBuild. Этот факт существенно упростил нашу задачу. Стоит также упомянуть, что в Linux версии PVS-Studio тоже возможно использование инкрементального анализа - там это работает "из коробки": при использовании мониторинга компиляции будут анализироваться только собираемые файлы. Соответственно, при инкрементальной сборке запустится инкрементальный анализ; при прямой интеграции в сборочную систему (например, в make файлы) ситуация будет аналогичной.

В MSBuild реализован механизм отслеживания обращений к файловой системе (File Tracking). Для инкрементальной сборки проектов, реализованных на C и C++, соответствия между исходными файлами (например, cpp-файлами, заголовочными файлами) и целевыми файлами записываются в *.tlog-файлы. Например, для задачи CL пути ко всем исходным файлам, прочитанным компилятором, будут записаны в файл CL.read.{ID}.tlog, а пути к целевым файлам будут сохранены в файле CL.write.{ID}.tlog.

Итак, в файлах CL.*.tlog у нас уже есть вся информация об исходных файлах, которые были скомпилированы, и о целевых файлах. Задача постепенно упрощается. Однако, все равно остается задача обойти все исходные и целевые файлы и сравнить даты их модификации. Можно ли упростить еще? Конечно! В пространстве имен Microsoft.Build.Utilities находим классы CanonicalTrackedInputFiles и CanonicalTrackedOutputFiles, которые отвечают за работу с файлами CL.read.*.tlog и CL.write.*.tlog соответственно. Создав экземпляры этих классов и используя метод CanonicalTrackedInputFiles.ComputeSourcesNeedingCompilation, получаем список исходных файлов, требующих компиляции, на основании анализа целевых файлов и графа зависимостей исходных файлов.

Приведем пример кода, позволяющий получить список файлов, на которых должен быть выполнен инкрементальный анализ, с помощью выбранного нами подхода. В этом примере sourceFiles – это коллекция полных нормализованных путей ко всем исходным файлам проекта, tlogDirectoryPath – путь к директории, в которой находятся *.tlog-файлы:

var sourceFileTaskItems =
    new ITaskItem[sourceFiles.Count];

for (var index = 0; index < sourceFiles.Count; index++)
    sourceFileTaskItems[index] =
        new TaskItem(sourceFiles[index]);

var tLogWriteFiles =
    GetTaskItemsFromPath("CL.write.*", tlogDirectoryPath);
var tLogReadFiles =
    GetTaskItemsFromPath("CL.read.*", tlogDirectoryPath);

var trackedOutputFiles =
    new CanonicalTrackedOutputFiles(tLogWriteFiles);
var trackedInputFiles =
    new CanonicalTrackedInputFiles(tLogReadFiles,
        sourceFileTaskItems, trackedOutputFiles, false, false);

ITaskItem[] sourcesForIncrementalBuild =
    trackedInputFiles.ComputeSourcesNeedingCompilation(true);

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

Заключение

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

Популярные статьи по теме
PVS-Studio ROI

Дата: 30 Янв 2019

Автор: Андрей Карпов

Время от времени нам задают вопрос, какую пользу в денежном эквиваленте получит компания от использования анализатора PVS-Studio. Мы решили оформить ответ в виде статьи и привести таблицы, которые по…
Как и почему статические анализаторы борются с ложными срабатываниями

Дата: 20 Мар 2017

Автор: Андрей Карпов

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

Дата: 14 Апр 2016

Автор: Андрей Карпов

Вы угадали, ответ - "42". Здесь приводится 42 рекомендации по программированию, которые помогут избежать множества ошибок, сэкономить время и нервы. Автором рекомендаций выступает Андрей Карпов - тех…
Технологии, используемые в анализаторе кода PVS-Studio для поиска ошибок и потенциальных уязвимостей

Дата: 21 Ноя 2018

Автор: Андрей Карпов

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

Дата: 22 Дек 2018

Автор: Андрей Карпов

В канун празднования нового 2019 года команда PVS-Studio решила сделать приятный подарок всем контрибьюторам open-source проектов, хостящихся на GitHub, GitLab или Bitbucket. Им предоставляется возмо…
Зло живёт в функциях сравнения

Дата: 19 Май 2017

Автор: Андрей Карпов

Возможно, читатели помнят мою статью под названием "Эффект последней строки". В ней идёт речь о замеченной мной закономерности: ошибка чаще всего допускается в последней строке однотипных блоков текс…
PVS-Studio для Java

Дата: 17 Янв 2019

Автор: Андрей Карпов

В седьмой версии статического анализатора PVS-Studio мы добавили поддержку языка Java. Пришло время немного рассказать, как мы начинали делать поддержку языка Java, что у нас получилось и какие дальн…
Любите статический анализ кода!

Дата: 16 Окт 2017

Автор: Андрей Карпов

Я в шоке от возможностей статического анализа кода, хотя сам участвую в разработке инструмента PVS-Studio. На днях я был искренне удивлён тому, что анализатор оказался умнее и внимательнее меня.
Эффект последней строки

Дата: 31 Май 2014

Автор: Андрей Карпов

Я изучил множество ошибок, возникающих в результате копирования кода. И утверждаю, что чаще всего ошибки допускают в последнем фрагменте однотипного кода. Ранее я не встречал в книгах описания этого …
Статический анализ как часть процесса разработки Unreal Engine

Дата: 27 Июн 2017

Автор: Андрей Карпов

Проект Unreal Engine развивается - добавляется новый код и изменятся уже написанный. Неизбежное следствие развития проекта - появление в коде новых ошибок, которые желательно выявлять как можно раньш…

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

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