Статический анализ защищает ваш код от бомб замедленного действия

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

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


Чтобы показать преимущество регулярного использования статического анализатора PVS-Studio, мы настроили у себя регулярную проверку проекта Blender. Подробнее про эту идею мой коллега писал здесь.


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


void UI_but_drag_set_asset(uiBut *but,
                           const AssetHandle *asset,
                           const char *path,
                           int import_type,
                           int icon,
                           struct ImBuf *imb,
                           float scale)
{
  ....
  asset_drag->asset_handle = MEM_mallocN(sizeof(asset_drag->asset_handle),
                                         "wmDragAsset asset handle");
  *asset_drag->asset_handle = *asset;
  ....
}

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


Ошибка здесь:


sizeof(asset_drag->asset_handle)

Правильный вариант:


sizeof(*asset_drag->asset_handle)

Анализатор выявил эту ошибку, выдав предупреждение: V568: It's odd that 'sizeof()' operator evaluates the size of a pointer to a class, but not the size of the 'asset_drag->asset_handle' class object. interface.c 6192


Всё просто. Классический паттерн ошибки, с которым мы встречались в различных проектах. Интересно другое! Этот код сейчас работает правильно! Автору кода повезло. Посмотрим, что собой представляет структура AssetHandle:


typedef struct AssetHandle {
  const struct FileDirEntry *file_data;
} AssetHandle;

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


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


В этот момент приложение сломается. Причём будет непонятно, что и где именно сломалось. Под структуру будет выделяться памяти меньше, чем требуется. Хорошо если программисту повезёт и при выходе за границу буфера возникнет Access Violation. Но, скорее всего, просто будет портиться какая-то память, и разработчика могут ждать часы мучительной отладки кода.


Используйте статический анализ кода, чтобы существенно улучшить качество и надёжность кода. Это полезно как в краткосрочной, так и в долгосрочной перспективе.


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


Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Andrey Karpov. Static analysis protects your code from time bombs.

Источник: https://habr.com/ru/company/pvs-studio/blog/571178/


Интересные статьи

Интересные статьи

Какие способы моделирования, диаграммы и визуализации используют чаще всего при проектировании информационных систем? Какие нотации использовать, чтобы сделать информацию...
После моей недавней статьи (части 1, 2, 3) о криминале и полицейской стрельбе в США и их связи с расовой принадлежностью я решил продолжить эту тему и в таком же ключе проанализироват...
Анализ тональности успешно применяется для социальных сетей, отзывов, новостей и даже учебников. На основе ключевых исследований для русского языка, описанных в предыдущей статье,...
Биоинформатика — чрезвычайно любопытная область научного знания, так как в ней соединяются задачи, формулируемые в биологических терминах, и методы, привычные для специалистов по алгоритмам, обра...
Новая игрушка Мы продолжаем знакомится с новым материалом от Apple, представленным на WWDC. На этот раз рассмотрим MetricKit, это абсолютно новый фреймворк, который служит инструментом для м...