Cppcheck


Cppcheck - это инструмент статического анализа исходного кода на языке Си и Си++. Отличительными чертами инструмента являются: открытость, бесплатность, кроссплатформенность, простота использования.

Сайт проекта: http://cppcheck.sourceforge.net/

Cppcheck является открытым, бесплатным инструментом, распространяемым под лицензией GNU General Public License. Организатором проекта является Daniel Marjamäki (его профиль на сайте StackOverflow). Исходный код проекта можно скачать с сайта github.

Возможности Cppcheck

На момент написания этой заметки Cppcheck версии 1.60.1 поддерживал следующие языки: C89, C99, C11, C++03, C++11. Также, на момент написания статьи, существуют следующие плагины для интеграции с различными средами разработки:

Использование Cppcheck

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

Рисунок 1. Cppcheck для Windows. Главное окно. Нажмите на картинку для увеличения.

Рисунок 1. Cppcheck для Windows. Главное окно. Нажмите на картинку для увеличения.

Просто выберите в меню "Check directory" и укажите путь до вашего проекта. Результат работы анализатора может выглядеть как показано на рисунке ниже.

Рисунок 2. Результат проверки проекта. Нажмите на картинку для увеличения.

Рисунок 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. Пример просмотра диагностического сообщения. Нажмите на картинку для увеличения.

Рисунок 3. Пример просмотра диагностического сообщения. Нажмите на картинку для увеличения.

Диагностики

Анализатор Cppcheck выполняет множество различных видов проверок. Перечислим некоторые из них:

  • Неправильное использование функций из Standard Template Library;
  • Утечки памяти (Memory leaks);
  • Утечки ресурсов (Resource leaks);
  • Выход за границы массивов (Bounds checking for array overruns);
  • Использование неинициализированных переменных;
  • Использование устаревших функций;
  • Проверка операций ввода/вывода (Check input/output operations);
  • Разыменование нулевого указателя.

Примеры диагностик

Приведём несколько примеров ошибок в коде, которые умеет выявлять анализатор Cppcheck.

Пример N1. Проект MPlayer

В этом коде ситуация отсутствия данных обрабатывается неправильно. Если выполняется условие "(!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

Пример N2. Проект Doom 3

В коде вместо "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.

Пример N3. Проект Doom 3

Ошибка связана с тем, что память выделяется для массива элементов, а освобождается, как если бы она была выделена для одного элемента. Правильный вариант 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

Пример N4. Проект Quake 3: Arena

Массив состоит из трех элементов. А работаем, как если бы он содержал четыре элемента.

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

Пример N5. Проект Quake 3: Arena

Функция 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

Ссылки


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

Проверено проектов
346
Собрано ошибок
13 188

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

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

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

goto PVS-Studio;