28 December 2011

Klocwork — впечатления от двухнедельного тестирования

Designing and refactoring
Не успел я поделиться впечатлениями от PVS-Studio, как сразу же последовали обвинения в рекламе. Что ж, расскажу о своем первом опыте использования систем static code analysis.

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

И вот (уже тоже в далеком 2010 году), увидев на Embedded World стенд того самого Klocwork-a, подошел порасспрашивать их насчет триал-лицензии для «попробовать». Спустя какое-то время получил от них е-мейл с вопросом: «Вы интересовались, все еще хотите?».

А мне тогда как раз досталось «в наследство» приличное количество кода, который, как бы помягче сказать, был… слегка кривовато написан. Да и проект был в стадии «Первый релиз выпущен», как раз было время на поиски возможных проблем.

Поэтому охотно согласился. Получил триал-инсталляцию и инструкции по интеграции. Отмечу лишь, что если интеграция с VS прошла «на ура», в один клик, то интеграция с CodeWarrior от FreeScale заставила попотеть как меня, так и техподдержку (которая, к их чести, всячески старалась мне помочь по е-мейлу, при том, что продукт был триал, без каких-либо гарантий, что он будет куплен!). В результате через две недели попыток интеграция была таки сделана (вручную — уж слишком CodeWarrior оказался вещью в себе). И наконец-то была получена лицензия на две недели, позволяющая делать то, ради чего все затевалось — static code analysis.

В двух словах о самой системе — есть центральный сервер, на котором запускаются т.н. «билды», и есть веб-клиенты, которые в браузере могут просматривать результаты анализа каждого «билда». Лицензию нужно покупать как на сервер, так и на каждого клиента. Причем лицензия ограничена по времени. При покупке 20 клиентских лицензий серверная — бесплатно, такой пакет получался по цене порядка 30 тысяч евро в год.

Результаты меня весьма приятно удивили.

В стадии «первый релиз выпущен» анализатор нашел 73 потенциальных проблем в трех проектах!

Ложно-положительных срабатываний было при этом только 6.

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

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

void function (int len, char * buf)
{
  char data[DATA_SIZE];

  for (int i = 0; i < len; ++i)
  {
    data[i] = buf[i];
  }

}

Для приведенного выше кода анализатор выдает сообщение «Buffer overflow: array of 'data' may be out of bounds. Array 'data' of size 260 may use index values from 260..65534»

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

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

К сожалению, не могу выложить скриншоты, т.к. сделаны они все на реальном проекте и реальном коде, который нельзя показывать в открытом доступе :( Делая же отчет для руководства два года назад, я не позаботился о том, чтобы запастись скриншотами на dummy-коде для возможной открытой публикации.

В вышеприведенном примере реального переполнения буфера не происходило — во всех вызовах функции передавалось правильное значение параметра len. Анализатор нашел в данном случае
лишь потенциально возможную проблему.

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

И еще из «вкусностей» данного анализатора кода:

  • Возможность отслеживания каждой найденной проблемы. Т.е. если проблема была исправлена, в следующем билде анализатор это обнаружит и больше ее показывать не будет. А также отразит это на красивом графике количества появившихся-оставшихся-исправленных проблем от билда к билду.
  • Возможность изменения статуса каждой проблемы. Т.е. если вы обнаружили, что это ложноположительное срабатывание, то можете отметить ее как «no problem», и анализатор ее не будет больше вам показывать.
  • Возможность назначения ответственного по каждой проблеме.
  • Возможность построения метрик кода (и отображения по ним графиков-тенденций от билда к билду).
  • Возможность экспорта результатов в эксель. При этом пропадает очень удобная интерактивность, но вся необходимая информация для того, чтобы найти и исправить проблемы, остается. Удобно, если нет «лишней» лицензии.
  • Настраиваемые отчеты — можно выбрать, что именно показывать в отчетах.

Анализатор поддерживает C/C++, C#, Java, хотя я тестировал только С/С++ часть.

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

Цена… Да, цена, безусловно, высока. Но для крупной компании, одновременно ведущей 20 и более проектов, цена при покупке наиболее выгодного пакета, в пересчете на проект окажется не столь и высокой. Да и наверняка первоначально названная цена — далеко не окончательная и может быть снижена путем переговоров, если речь зайдет о реальной покупке. Если же еще учесть, что одна подобная потенциальная проблема, в один прекрасный момент ставшая реальной, легко может «съесть» две-три недели работы ведущего программиста (а то и не одного), а в еще худшем случае (если она «вылезет» после релиза) может привести к весьма и весьма ощутимым убыткам, значительно превосходящим стоимость анализатора…

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

И да, как этот пост, так и пост про PVS-Studio написаны исключительно из интереса к теме. Ни в этом, ни в том случае я не получил никакой материальной компенсации от авторов за написание обзора, если вдруг кто-то таки засомневается в моей непредвзятости.
Tags:static code analysisklocworkc++
Hubs: Designing and refactoring
+32
4.7k 24
Comments 12
Popular right now
SEO-специалист
December 7, 202064,900 ₽Нетология
iOS-разработчик с нуля
December 7, 202070,740 ₽Нетология
Python для работы с данными
December 7, 202031,500 ₽Нетология
UX-дизайнер
December 7, 202047,940 ₽Нетология