Вебинар: Использование статических анализаторов кода при разработке безопасного ПО - 19.12
Мы добавили возможность экспериментировать со статическим анализатором кода PVS-Studio на сайте godbolt.org (Compiler Explorer). Поддерживается анализ C и C++ кода. Уверены, что это интересный и очень простой способ попробовать, как поведёт себя анализатор на тех или иных примерах кода. Однако у нас есть опасение, что теперь программисты начнут пытаться оценивать возможности анализатора на синтетических примерах, а не запуская на реальных проектах. Давайте попробуем разобраться, чем плох подход оценки, базирующийся на синтетических примерах.
Compiler Explorer это интерактивный инструмент, который позволяет печатать код в одном окне и видеть результаты его компиляции в другом.
PVS-Studio – это инструмент для выявления ошибок и потенциальных уязвимостей в исходном коде программ, написанных на языках С, C++, C# и Java.
Мы подружили эти два инструмента, и теперь можно быстро попробовать, обнаружится ли та или иная ошибка в коде с помощью PVS-Studio. Для этого достаточно:
Теперь вы можете проверять ваш код, просто вписав его в окне на сайте. На данный момент поддерживаются все версии компиляторов GCC и Clang для платформ x86 и x64.
Эта новая возможность открывает интересные перспективы с точки зрения утоления любопытства, написания статей и так далее. Однако в этом есть опасность: синтетические примеры могут быть использованы не только для экспериментов/изучения, но и для попытки оценивать и сравнивать анализаторы кода. А это очень плохой подход. Он будет слишком неточен и зависеть от того, как написан пример кода.
Наша команда уже давно столкнулась с этой проблематикой. Ещё в 2017 году я написал статью "Почему я не люблю синтетические тесты". Рекомендую почитать её, она небольшая. Сейчас я приведу ещё примеры.
Первое, что может захотеть проверить программист, - может ли анализатор PVS-Studio найти утечку памяти. По опыту знаю, что все очень почему-то любят проводить именно этот тест :). С большей вероятностью, программист напишет следующий код:
int main()
{
int *p = new int;
*p = 1;
return 1;
}
Да, PVS-Studio умеет выявлять утечки памяти. Вот только здесь он промолчит.
Для экспериментатора причина может быть неочевидна, и он сделает неправильные выводы. Дело в том, что именно в функции main очень часто программисты не освобождают память. Настолько часто, что мы сделали специально исключение на этот случай. Ведь на самом деле, беды нет. После завершения работы функции main память всё равно будет возвращена системе.
Да, формально это всё равно ошибка. Но на практике такой код так широко распространён, что нет смысла отвлекать людей подобными срабатываниями. И помнится, кто-то из пользователей тоже просил нас убрать предупреждения про утечки для main.
Стоит поменять название функции и предупреждение вернётся.
int foo()
{
int *p = new int;
*p = 1;
return 1;
}
Теперь анализатор выдаст ожидаемое предупреждение: <source>:5:1: error: V773 The function was exited without releasing the 'p' pointer. A memory leak is possible.
Другой пример с функцией main. Давайте сделаем в ней вечный цикл:
int main()
{
unsigned i = 0;
while (1)
{
i++;
}
return 1;
}
Анализатор молчит. Неужели он не видит подозрительный вечный цикл? Видит. И это тоже распространённый паттерн корректного кода. Так очень часто пишут разработчики программ для микроконтроллеров. Почти всегда в таких программах есть вечный цикл, в котором что-то делается. Выход из функции main не имеет смысла и никогда не осуществляется. Там, собственно, и выходить-то некуда :).
И вновь, стоит поменять название функции, и анализатор выдаст предупреждение.
int foo()
{
unsigned i = 0;
while (1)
{
i++;
}
return 1;
}
Анализатор сообщает: <source>:4:1: note: V776 Potentially infinite loop.
Работа любого статического анализатора – это хрупкий баланс между бесконечным количеством малополезных сообщений и опасностью не сообщить про настоящую ошибку. Теперь становится понятно, почему анализаторы кода столь чувствительны к тому, как составлены примеры. И надо быть очень аккуратным при написании синтетических примеров. И вдвойне надо быть аккуратным, если с помощью таких маленьких тестов вы захотите сравнивать инструменты анализа. Лучше так не делать.
Если кто-то хочет лучше понять нашу философию реализации диагностик и отсечения ложных срабатываний, предлагаю взглянуть на две следующие статьи:
Самый лучший способ попробовать анализатор кода и оценить его возможности – это запустить его на своем настоящем проекте. Это легко сделать. Просто скачайте анализатор PVS-Studio запустите. Кстати, а для открытых проектов есть ещё и бесплатная лицензия.
Теперь вы предупреждены. Пробуйте, экспериментируйте. Но будьте аккуратны в выводах.
Чтобы вам было проще, и вы не искали, куда же нажать, чтобы проанализировать код, мы подготовили две ссылки. Вы можете просто менять код и наблюдать результат:
Спасибо за внимание.
0