Вебинар: Использование статических анализаторов кода при разработке безопасного ПО - 19.12
Cppcheck - это инструмент статического анализа исходного кода на языке Си и Си++. Отличительными чертами инструмента являются: открытость, бесплатность, кроссплатформенность, простота использования.
Сайт проекта: http://cppcheck.sourceforge.net/
Cppcheck является открытым, бесплатным инструментом, распространяемым под лицензией GNU General Public License. Организатором проекта является Daniel Marjamäki (его профиль на сайте Stack Overflow). Исходный код проекта можно скачать с сайта github.
На момент написания этой заметки Cppcheck версии 1.60.1 поддерживал следующие языки: C89, C99, C11, C++03, C++11. Также, на момент написания статьи, существуют следующие плагины для интеграции с различными средами разработки:
Одним из основных преимуществ анализатора Cppcheck является простота использования. Можно рекомендовать этот инструмент для обучения и первого знакомства с методологией статического анализа. Например, установив Cppcheck для Windows, вы получаете GUI интерфейс, позволяющий сразу приступить к проверке ваших проектов.
Рисунок 1. Cppcheck для Windows. Главное окно. Нажмите на картинку для увеличения.
Просто выберите в меню "Check directory" и укажите путь до вашего проекта. Результат работы анализатора может выглядеть как показано на рисунке ниже.
Рисунок 2. Результат проверки проекта. Нажмите на картинку для увеличения.
Конечно, я немного лукавлю, говоря, что Cppcheck не требует никакой настройки. Если вы серьезно начнете использовать Cppcheck, вам понадобится произвести ряд настроек. Например, потребуется указать пути до сторонних библиотек, интегрировать Cppcheck с вашей средой разработки или настроить ночные запуски. Однако, сам факт, что вы можете просто выбрать каталог и получить результат - очень здорово! Особенно если вы только начинаете изучать, что такое статический анализ кода. Эта возможность просто бесценна.
После проверки можно просмотреть диагностические сообщения. Все сообщения разделены на следующие группы: Errors, Warnings, Style Warnings, Portability Warnings, Performance Warnings, Information Messages. Группы легко включать/выключать используя кнопки на тулбаре.
На рисунке N3 показан режим работы для просмотра Style Warnings. Группа предупреждений "Style Warnings" включена, а остальные выключены (см. цифру 1). Файл "cpuid_x86.c" содержит несколько таких предупреждений. Выбрано первое предупреждение, которое относится к 214 строке (см. цифру 2). В нижнем окне сразу показывается описание этой диагностики (см. цифру 3).
Рисунок 3. Пример просмотра диагностического сообщения. Нажмите на картинку для увеличения.
Анализатор Cppcheck выполняет множество различных видов проверок. Перечислим некоторые из них:
Приведём несколько примеров ошибок в коде, которые умеет выявлять анализатор Cppcheck.
В этом коде ситуация отсутствия данных обрабатывается неправильно. Если выполняется условие "(!sh->wf || sh->wf->cbSize < 80)", то происходит утечка памяти.
....
context_t *ctx = calloc(1, sizeof(context_t));
const SpeexMode *spx_mode;
const SpeexStereoState st_st = SPEEX_STEREO_STATE_INIT;
if (!sh->wf || sh->wf->cbSize < 80) {
mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Missing extradata!\n");
return 0;
}
....
Диагностическое сообщение:
libmpcodecs/ad_speex.c:44: Memory leak: ctx
В коде вместо "sizeof(ctx)" должно быть написано "sizeof(*ctx)". Из-за ошибки обнуляется не весь объект 'ctx' а только несколько первых байт.
void MD5_Final( MD5_CTX *ctx, unsigned char digest[16] ) {
....
memset( ctx, 0, sizeof( ctx ) );
Диагностическое сообщение:
..\Doom3\id-Software-DOOM-3-a9c49da\neo\idlib\hashing\MD5.cpp(252):
Using size of pointer ctx instead of size of its data.
Ошибка связана с тем, что память выделяется для массива элементов, а освобождается, как если бы она была выделена для одного элемента. Правильный вариант delete [] sortIndex.
void idImageManager::PrintMemInfo( MemInfo_t *mi ) {
int *sortIndex;
....
sortIndex = new int[images.Num()];
....
delete sortIndex;
Диагностическое сообщение:
..\Doom3\id-Software-DOOM-3-a9c49da\neo\renderer\Image_init.cpp(2214)
Mismatching allocation and deallocation: sortIndex
Массив состоит из трех элементов. А работаем, как если бы он содержал четыре элемента.
void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors )
{
...
unsigned char invModulate[3];
...
invModulate[0] = 255 - backEnd.currentEntity->e.shaderRGBA[0];
invModulate[1] = 255 - backEnd.currentEntity->e.shaderRGBA[1];
invModulate[2] = 255 - backEnd.currentEntity->e.shaderRGBA[2];
invModulate[3] = 255 - backEnd.currentEntity->e.shaderRGBA[3];
// this trashes alpha, but the AGEN block fixes it
Диагностическое сообщение:
..\Quake3\id-Software-Quake-III-Arena-dbe4ddb\code\renderer\tr_shade_calc.c 628
Array 'invModulate[3]' index 3 out of bounds
Функция printf() печатает два числа, а параметров передаётся три. Или один параметр лишний, или неправильная строка форматирования.
static void do_uid(int x) {
printf("<a href='#%d'>%d</a>", x, x, x);
}
Диагностическое сообщение:
..\Quake3\id-Software-Quake-III-Arena-dbe4ddb\lcc\src\2html.c 131
printf format string has 2 parameters but 3 are given
0