По мотивам "трёх интервью о статических анализаторах", или четвертое интервью




Примерно неделю назад была опубликована статья "Три интервью о статических анализаторах кода", в которой на читательский суд были представлены точки зрения опытных программистов из Acronis, AlternativaPlatform и НПО "Эшелон" о методике разработки ПО, а также некоторые их размышления относительно использования статических анализаторов кода.

Поскольку спонсором статьи выступила компания ООО "СиПроВер" - разработчик статического анализатора PVS-Studio, - я решил попросить Андрея Карпова (технический директор) также ответить на некоторые вопросы. А именно - прокомментировать интересные моменты всех трёх интервью. Плюс сделать обращение к коллегам и читателям. Получился вот такой интересный результат.

Picture 3

Комментарий относительно примечательных моментов в интервью Акрониса

Пару раз на конференции при неформальном общении в холле или за обеденным столом меня спрашивали: "Неужели кто-то ещё программирует на Си++?". И искренне удивлялись, когда я отвечал: "да, и это один из самых используемых языков". Просто он как-то сегодня не на слуху. Кругом php, ruby, go. Кажется, что Си++ - это "было давно и не правда". И мне приятно, что люди лишний раз увидят в статье, что, например, Acronis Backup написан на Си++ и над этим постоянно трудится 70 программистов. Сам я о будущем Си и Си++ не переживаю. Мне просто удивительно, как так выходит, что многие считают Си++ мёртвым языком.

Приятно было также услышать, что в Acronis широко применяется практика Code Review. Часто этот метод повышения качества программ недооценивается, или считается, что он отнимает слишком много времени. Скупой платит дважды.

Кстати, я знаю по крайней мере один пример, когда иногда умножать sizeof на sizeof всё-таки имеет практический смысл. Например, такое умножение получается, когда один sizeof() используется для взятия количества элементов в массиве. Имеется в виду вот это:

template <typename T, size_t N>
char (&ArraySizeHelper(T (&array)[N]))[N];
#define arraysize(array) (sizeof(ArraySizeHelper(array)))

Такой 'arraysize' защищает от случайной передачи в качестве аргумента не массива, а обыкновенного указателя. Подробности здесь.

В результате, вполне может получиться конструкция вида: "sizeof(float) * (sizeof(ArraySizeHelper(array)))". Но анализатор PVS-Studio знает про такие случаи и не выдаёт предупреждений.

Комментарий относительно примечательных моментов в интервью Альтернативы

С Java я не знаком, поэтому не могу прокомментировать, насколько хорошо язык защищает от ошибок. Конечно, уже одно отсутствие ручного управления памятью сильно упрощает жизнь. Однако, я думаю, часть ошибок не зависит от языка. Например, если это результаты Copy-Paste. Думаю, использование статического анализатора для поиска опечаток было бы весьма уместно и для Java. Но я опять-таки не знаю, что предлагают для Java существующие анализаторы кода.

Комментарий относительно примечательных моментов в интервью НПО Эшелон

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

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

Возьмём, например, проект UltimateTCPIP и найдем в нём с помощью PVS-Studio вот такую ошибку:

char *CUT_CramMd5::GetClientResponse(LPCSTR ServerChallenge)
{
  ...
  if (m_szPassword != NULL)
  {
    ...
    if (m_szPassword != '\0')
    {
  ...
}

V528 It is odd that pointer to 'char' type is compared with the '\0' value. Probably meant: *m_szPassword != '\0'. UTMail ut_crammd5.cpp 333

Мы говорим о такой ошибке просто, как об опечатке. Забыли разменивать указатель. В результате не выполняется проверка, что строка пустая. Код должен был быть таким:

if (*m_szPassword != '\0')

Но ведь, с другой стороны, это самая настоящая уязвимость. Оставим в стороне вопрос, можно ли этой уязвимостью воспользоваться и насколько она опасна. Главное то, что проверка на опечатку может выявить самую настоящую дыру в безопасности. Мало ли что пойдёт не так, если программа начнёт работать с пустым паролем.

Или ещё пример из PostgreSQL:

char *
px_crypt_md5(const char *pw, const char *salt,
             char *passwd, unsigned dstlen)
{
  ....
  unsigned char final[MD5_SIZE];
  ....
  /* Don't leave anything around in vm they could use. */
  memset(final, 0, sizeof final);
  ....
}

V597 The compiler could delete the 'memset' function call, which is used to flush 'final' buffer. The RtlSecureZeroMemory() function should be used to erase the private data. pgcrypto crypt-md5.c 157

Здесь PVS-Studio обнаруживает, что массив 'final' не обнуляется перед выходом из функции. Почему так, можно узнать из описания диагностики V597.

Вот мне и непонятно, почему диагностики PVS-Studio являются "недостаточно выявляющими уязвимости".

Ваше видение относительно будущего статических анализаторов кода

В целом со статическим анализом всё хорошо. Инструментарий в этом направлении быстро развивается и набирает большую популярность.

Хотелось бы, чтобы в России это тоже происходило побыстрее. У нас практически нет рынка для инструментов статического анализа. Об этом можно судить хотя бы по количеству посещений нашего сайта, скачиванию демонстрационных версий и статистике продаж. Половину всей активности создают посетители из России. Но количество российских клиентов составляет не 50%, а только чуть-чуть. Печально.

Обращение к читателям и коллегам по цеху

Текст в духе "используйте в работе статический анализ" прозвучит банально. Поэтому подниму нестандартную тему.

Желаю удачного общения между начальниками и подчинёнными. Часто указания начальства выглядят по меньшей мере странными. Но следует учитывать, что начальник часто обладает большим объёмом знаний по проекту в целом. И то, что кажется странным подчинённому, на высоком уровне может быть очень полезным или просто вынужденным. К сожалению, начальники программистов часто сами являются выходцами из программистов и потому тяготеют к интроверсии. Другими словами, ставя задачу, они не считают нужным объяснить, зачем всё это надо. Их надо понять и простить. А потом, задавая вопросы, понять, чем вызвано такое странное распоряжение. Скорее всего, начальник не против будет объяснить. Он просто забыл про это или "оптимизировал" время общения, сведя комплексную задачу к "сделай так". Соответственно, желаю и руководству не забывать объяснять свои шаги и решения.

И спасибо организатору интервью.

Заключение

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



Найдите ошибки в своем C, C++, C# и Java коде

Предлагаем попробовать проверить код вашего проекта с помощью анализатора кода PVS-Studio. Одна найденная в нём ошибка скажет вам о пользе методологии статического анализа кода больше, чем десяток статей.

goto PVS-Studio;


Найденные ошибки

Проверено проектов
361
Собрано ошибок
13 417

А ты совершаешь ошибки в коде?

Проверь с помощью
PVS-Studio

Статический анализ
кода для C, C++, C#
и Java

goto PVS-Studio;