Короткий огляд статичних аналізаторів коду C
Короткий огляд статичних аналізаторів коду C/C++
При написанні коду на C і C++ люди припускаються помилок. Багато з цих помилок є завдяки -Wall , асертам, тестам, скрупульозному code review, попередженням з боку >
CppCheck є безкоштовним кросплатформовим статичним аналізатором із відкритим вихідним кодом (GPLv3). Він доступний у пакетах багатьох *nix систем із коробки. Також CppCheck вміє інтегруватися з багатьма IDE. На момент написання цих рядків CppCheck є живим проектом, що розвивається.
[some.c:57]: (error) Common realloc mistake: 'numarr' nulled but not freed upon failure
[some.c:154]: (error) Довге використання 'n' (strncpy doesn't always null-terminate it)
CppCheck гарний тим, що він досить швидко працює. Немає приводу не додати його прогін у систему безперервної інтеграції, щоб виправляти прямо все-все-все попередження, що їм виводяться. Навіть незважаючи на те, що багато з них на практиці виявляються хибно-позитивними спрацьовуваннями.
Clang Static Analyzer
Ще один безкоштовний кросплатформовий статичний аналізатор з відкритим вихідним кодом. Є частиною з так званого LLVM-стека. На відміну від CppCheck працює суттєво повільніше, але й помилки знаходить значно серйозніші.
Приклад побудови звіту для PostgreSQL:
Приклад побудови звіту для ядра FreeBSD:
Ідея, як нескладно здогадатися, полягає в тому, щоб зробити clean, а потім запустити складання під scan-build.
На виході виходить дуже симпатичний HTML-звіт з докладними поясненнями, можливістю фільтрувати помилки за їхнім типом, тощо. Обов'язково подивіться на офсайті як це виглядає приблизно.
У цьому контексті не можу невідзначити, що у світі Clang/LLVM є ще й засоби динамічного аналізу, так звані санітайзери. Їх багато, вони знаходять дуже круті помилки і працюють швидше, ніж Valgrind (щоправда, лише під Linux). На жаль, обговорення санітайзерів виходить за рамки цієї нотатки, тому ознайомтеся з ними самостійно.
Закритий статичний аналізатор, який розповсюджується за гроші. PVS-Studio працює тільки під Windows і лише з Visual Studio. Існують численні відомості про існування Linux-версії, але на офіційному сайті вона не доступна. Наскільки я зрозумів, вартість ліцензії обговорюється індивідуально з кожним клієнтом. Доступний тріал.
Я протестував PVS-Studio 6.02 на Windows 7 SP1, що працює під KVM із встановленою Visual Studio 2013 Express Edition. Під час встановлення PVS-Studio також додатково завантажено .NET Framework 4.6. Виглядає це приблизно так. Ви відкриваєте проект (я тестував на PostgreSQL) у Visual Studio, у PVS-Studio тиснете «зараз я почну збирати проект», потім у Visual Studio натискаєте Build, після закінчення складання в PVS-Studio тиснені «я закінчив» і дивіться звіт.
PVS-Studio дійсно знаходить дуже круті помилки, які Clang Static Analyzer не бачить (наприклад). Також дуже сподобався інтерфейс, що дозволяє сортувати та фільтрувати помилки за їх типом, серйозністю, файлом, в якому вони були знайдені, і так далі.
Спробував бета-версію PVS-Studio для Linux. Користуватися нею виявилося дуже просто. Створюємо pvs.conf приблизно такого змісту:
40 Мб) файл strace_out pvs-studio-analyzer analyze --cfg . / pvs.conf plog-converter -t tasklist -o result.task pvs-output.log
Додаток: PVS-Studio для Linux вийшов із бети і тепер доступний усім бажаючим.
Coverity Scan
Coverityвважається одним із найбільш накручених (а отже і дорогих) статичних аналізаторів. На жаль, на офіційному сайті неможливо завантажити навіть його тріал-версію. Можна заповнити форму, і якщо ви будь-який IBM, з вами може бути зв'яжуться. За дуже сильного бажання Coverity якоїсь доісторичної версії можна знайти через неофіційні канали. Він буває для Windows та Linux, працює приблизно за тим же принципом, що й PVS-Studio. Але без серійника чи ліки звіти Coverity вам не покаже. А щоб знайти серійник або ліки, потрібно мати не просто дуже сильне бажання, а дуже сильне.
На щастя, у Coverity є SaaS версія - Coverity Scan. Мало того, що Coverity Scan доступний для простих смертних, він ще й абсолютно безкоштовний. Прив'язки до конкретної платформи немає. Проте аналізувати за допомогою Coverity Scan дозволяється лише відкриті проекти.
Ось як це працює. Ви реєструєте свій проект через веб-інтерфейс (або приєднуєтеся до існуючого, але це менш цікавий кейс). Щоб переглянути звіти, потрібно пройти модерацію, яка займає 1-2 робочі дні.
Звіти будуються в такий спосіб. Спочатку ви локально збираєте свій проект під спеціальною утилітою Coverity Build Tool. Утиліта ця аналогічна scan-build з Clang Static Analyzer і доступна під усі можливі платформи, включаючи будь-яку екзотику типу FreeBSD або навіть NetBSD.
Установка Coverity Build Tool:
Готуємо тестовий проект (я використовував код із нотатки Продовжуємо вивчення OpenGL: простий висновок тексту):
Потім збираємо проект під cov-build:
Важливо! Не змінюйте назву директорії cov-int.
Архівуємо директорію cov-int:
Заливаємо архів через форму Upload a Project Build. Також на сайті Coverity Scan єінструкції з автоматизації цього кроку за допомогою curl. Чекаємо небагато, і можна дивитися результати аналізу. Зверніть увагу, що щоб пройти модерацію, потрібно відправити на аналіз хоча б один білд.
Помилки Coverity Scan дуже добре шукає. Вже точно краще, ніж Clang Static Analyzer. При цьому помилково-позитивні спрацьовування є, але їх набагато менше. Що зручно, у веб-інтерфейсі є щось на кшталт вбудованого багтрекера, що дозволяє надавати помилкам серйозність, відповідального за їх виправлення та подібні речі. Видно, які нові помилки, а які вже були в попередніх білдах. Хибно-позитивні спрацьовування можна назвати як такі і приховати.
Зауважте, що щоб проаналізувати проект у Coverity Scan, не обов'язково бути його власником. Мені особисто успішно вдалося проаналізувати код PostgreSQL без приєднання до вже існуючого проекту. Думається також, що при сильному бажанні (наприклад, використовуючи сабмодулі Git), можна підсунути на перевірку трохи і не дуже відкритого коду.
Висновок
Ось ще кілька статичних аналізаторів, які не потрапили до огляду:
Кожен із розглянутих аналізаторів знаходять такі помилки, які не знаходять інші. Тому в ідеалі краще використати їх одразу все. Робити це прямо постійно, швидше за все, об'єктивно не вийде. Але робити хоча б один прогін перед кожним релізом буде не зайвим. При цьому Clang Static Analyzer виглядає найбільш універсальним і досить потужним. Якщо вас цікавить один аналізатор, який потрібно обов'язково використовувати у будь-якому проекті, використовуйте його. Але все ж таки я рекомендував би додатково використовувати як мінімум PVS-Studio або Coverity Scan.
А які статичні аналізатори ви пробували та/або регулярно використовували та які вашівраження від них?