PVS-Studio - это инструмент для выявления ошибок в исходном коде программ, написанных на языках С, C++ и C#.
PVS-Studio выполняет статический анализ кода и генерирует отчёт, помогающий программисту находить и устранять ошибки. PVS-Studio выполняет широкий спектр проверок кода, но наиболее силён в поисках опечаток и последствий неудачного Copy-Paste. Показательные примеры таких ошибок: V501, V517, V522, V523, V3001.
Анализатор ориентирован на разработчиков, использующих среду Visual Studio, и может в фоновом режиме выполнять анализ измененных файлов после их компиляции. В идеале ошибки будут обнаружены и исправлены ещё до попадания в репозиторий. Однако ничто не мешает использовать анализатор для проверки всего решения целиком или для встраивания в системы непрерывной интеграции. Эти и иные способы использования анализатора описаны в документации.
PVS-Studio выполняет статический анализ кода и генерирует отчёт, помогающий программисту находить и устранять ошибки. PVS-Studio выполняет широкий спектр проверок кода, но наиболее силён в поисках опечаток и последствий неудачного Copy-Paste. Показательные примеры таких ошибок: V501, V517, V522, V523, V3001.
Анализатор ориентирован на разработчиков, использующих среду Visual Studio, и может в фоновом режиме выполнять анализ измененных файлов после их компиляции. В идеале ошибки будут обнаружены и исправлены ещё до попадания в репозиторий. Однако ничто не мешает использовать анализатор для проверки всего решения целиком или для встраивания в системы непрерывной интеграции. Эти и иные способы использования анализатора описаны в документации.
Проверка Firebird 3.0
Запись от el_programmer размещена 12.05.2016 в 10:57
Показов 2193
Комментарии 0
Метки c++, cpp, firebird, open source, programming
|
Автор: Павел Беликов Не так давно вышла новая версия СУБД Firebird. Релиз стал одним из масштабных в истории проекта: была сильно переработана архитектура, добавлена поддержка многопоточности, улучшена производительность. Такое значительное обновление и послужило поводом для повторной проверки Firebird с помощью статического анализатора кода PVS-Studio. Введение Firebird - это кроссплатформенная свободная система управлениями базами данных. Проект написан на C++ и работает на Microsoft Windows, Linux, Mac OS X и многих Unix-like операционных системах. СУБД полностью бесплатна для использования и распространения. Подробнее о Firebird можно узнать на официальном сайте. Ранее Firebird уже проверялся анализатором. С отчётом о предыдущей проверке можно ознакомиться в статье "Побочный результат: проверяем Firebird с помощью PVS-Studio". Для проверки был взят код с GitHub из ветви master. Сборка подробно описана в соответствующей статье на сайте проекта. Анализ исходных файлов производился в PVS-Studio Standalone версии 6.03 с помощью перехвата вызова компиляторов (Compiler Monitoring). Данная технология позволяет проверять проекты без интеграции в сборочную систему. Полученный отчёт можно просмотреть как в Standalone версии, так и в Visual Studio. Опечатки
Анализатор обнаружил, что в логической операции присутствуют два одинаковых подвыражения c != '_'. В последнем условии допущена опечатка и переменная c должна сравниваться с другим символом. В других функциях используется проверка с символом '$', возможно здесь нужно использовать его:
Здесь неверно используется функция BURP_error. Она объявлена следующим образом:
Однако, есть случаи, когда распознать ошибку может только разработчик проекта.
В коде идут подряд два блока с одинаковым условием. Может быть, в одном из них допустили опечатку, может быть, такая ситуация возникла из-за копирования или удаления отдельных участков: в любом случае такой код выглядит странно. В следующем примере рассмотрим ситуацию, связанную с указателями.
В условии переменная p проверяется на nullptr сразу же после разыменовывания. Это может означать, что на месте проверки должно было быть другое условие либо то, что проверка лишняя. Если посмотреть выше по коду, то можно найти аналогичный фрагмент:
Опасное использование memcmp
Функция memcmp возвращает следующие значения:
Точные значения функции при неравенстве строк не гарантируются, поэтому сохранение результата в переменную меньшего размера, чем int, может привести к потере значащих битов и нарушению логики приложения. Лишние проверки
Анализатор нашёл проверку двух противоположных условий. Скорее всего, второе условие здесь стало не нужным в результате изменения первого и его можно удалить, но решение тут стоит принимать автору. Ещё одним примером странного ветвления может послужить следующий фрагмент кода.
Если field не нулевой указатель, то код никогда не достигнет условия в else if. Либо данная проверка лишняя, либо на её месте должно было быть другое сравнение. Неизвестно, противоречит ли данное условие логике приложения. Помимо этого, было найдено несколько лишних проверок в логических выражениях.
Проверку if (!xnet_connect_mutex || (xnet_connect_mutex && ERRNO == ERROR_ALREADY_EXISTS)) можно упростить до if (!xnet_connect_mutex || ERRNO == ERROR_ALREADY_EXISTS). Это можно легко доказать с помощью таблицы истинности. Опасное сравнение беззнаковой переменной
Условие bdb->bdb_page.getPageNum() >= 0 всегда окажется верным, так как функция возвращает значение беззнакового типа. Возможно, программист неверно проверил значение. Принимая во внимания аналогичные сравнения в проекте, можно предположить, что код должен выглядеть следующим образом:
Разыменовывание нулевых указателей
Предупреждение V595 является самым часто встречаемым в проектах, проверенных PVS-Studio, и Firebird не стал исключением. Всего обнаружено более 30 мест с данным предупреждением. В этом примере вызов strlen(lpName) идёт перед проверкой указателя на nullptr. Это приведёт к неопределённому поведению при попытке передать в функцию нулевой указатель. Разыменовывание указателя здесь спрятано в вызове strlen, что затрудняет обнаружение ошибки, если не пользоваться статическим анализатором. Проверка на nullptr после new
Анализатор предупреждает, что оператор new не может вернуть nullptr - для проверки необходимо использовать блок try-catch или new (std::nothrow). Однако, в данном примере всё несколько сложнее. Для выделения памяти используется макрос FB_NEW. Он объявлен в файле alloc.h:
Опасное использование realloc
Выражение вида ptr = realloc(ptr, size) плохо тем, что в случае, когда realloc вернёт nullptr, указатель на память будет потерян. Чтобы этого избежать, следует сохранить результат realloc в временную переменную и после проверки на nullptr присвоить ptr её значение.
Неиспользованные значения enum в switch
В конструкции switch были использованы не все значения enum, и отсутствует блок default. Возможно, что здесь забыли добавить обработку piDirectMatch. Список мест с аналогичным предупреждением:
Переполнение буфера
Размер буфера isc_844.isc_874 равен 125, соответственно, максимальное возможное значение strlen(isc_844.isc_874) - 124. Размер temp - 64, что меньше этого значения. Запись по такому индексу может привести к переполнению буфера. Безопасней будет выделить больший объём памяти для переменной temp. Сдвиг отрицательных чисел
Код содержит сдвиг вправо отрицательного числа. В стандарте C++ указано, что такое действие имеет неуточняемое поведение, значит на разных компиляторах и платформах может выдавать разный результат. Лучше переписать его так:
V610 Unspecified behavior. Check the shift operator '>>'. The left operand is negative ('i64value' = [-2147483648..2147483647]). exprnodes.cpp 6382 Переопределение переменной
В этом примере вместо присвоения переменная exit_code переопределяется. Это скрывает из области видимости предыдущую переменную, и в итоге функция возвращает неверное значение, всегда равное -1. Корректный код:
Заключение Большинство проблем, найденных в предыдущей проверке, было исправлено разработчиками проекта и сейчас в коде их нет - значит анализатор проделал отличную работу. Однако лучшего результата можно добиться при регулярном использовании, что позволит отлавливать ошибки на ранней стадии. Инкрементальный анализ и совместимость с любыми системам сборки позволяют легко интегрировать статический анализатор в свой проект. Использование статического анализатора может сэкономить массу времени и найти ошибки, которые сложно обнаружить с помощью отладки или динамического анализа. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Метки c++, cpp, firebird, open source, programming
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии


