Лучшие вопросы
Таймлайн
Чат
Перспективы
Статический анализ кода
Из Википедии, свободной энциклопедии
Remove ads
Стати́ческий ана́лиз ко́да (англ. static code analysis) — анализ исходного кода программного обеспечения, производимый без реального выполнения исследуемых программ (в отличие от динамического анализа). В большинстве случаев анализ производится над исходным кодом, хотя иногда анализу подвергается объектный код, например P-код или код на MSIL. Термин обычно применяют к анализу, производимому специальным программным обеспечением (ПО), тогда как ручной анализ называют «program understanding» или «program comprehension» (пониманием программы).
В зависимости от используемого инструмента глубина анализа может варьироваться от определения поведения отдельных операторов до анализа всего имеющегося кода. Способы использования полученной в ходе анализа информации также различны — от выявления мест, возможно содержащих ошибки (утилиты типа Lint), до формальных методов, позволяющих математически доказать какие-либо свойства программы (например, соответствие поведения спецификации).
В некоторых источниках программные метрики и обратное проектирование рассматриваются как формы статического анализа. Получение метрик (англ. software quality objectives) и статический анализ часто совмещаются, особенно при создании встраиваемых систем[1].
Современные средства анализа, такие как Coverity, SonarQube, PVS-Studio, Clang Static Analyzer и Infer от Meta, используют методы анализа потока данных, контроля потока управления, а также абстрактной интерпретации для выявления ошибок, неочевидных при компиляции. Многие инструменты интегрируются в CI/CD-конвейеры и автоматизированные процессы разработки программного обеспечения для раннего выявления уязвимостей и дефектов.
Статический анализ играет важную роль в обеспечении безопасной разработки, соответствующей таким стандартам, как OWASP и MISRA C (в автомобильной индустрии), и широко применяется при разработке критически важных систем.
Remove ads
Принципы статического анализа
Суммиров вкратце
Перспектива
Примером простейшего статического анализа являются генерируемые большинством компиляторов (например, GCC) «предупреждения» (англ. warnings) — диагностические сообщения о потенциальной ошибочности синтаксически правильного кода. Например, для следующего кода на C может быть получено сообщение о неинициализированной переменной:
int x;
int y = x + 2; // Переменная x не инициализирована!
В связи с высокими требованиями к скорости компиляции и качеству машинного кода, компиляторы проверяют код лишь на простейшие ошибки. Статические анализаторы предназначены для более детального исследования кода, включая межпроцедурный анализ, определение утечек памяти, проблем конкурентности и возможных уязвимостей.
Типы ошибок, обнаруживаемых статическими анализаторами
Статические анализаторы выявляют широкий спектр ошибок, которые могут привести к сбоям, уязвимостям и проблемам сопровождения программного обеспечения:
- Неопределённое поведение — например, использование неинициализированных переменных, обращение к нулевым указателям. Простые случаи могут быть обнаружены ещё на этапе компиляции.
- Нарушения контракта использования библиотек. Например, в языках с управлением файлами каждый вызов открытия файла должен сопровождаться вызовом его закрытия. Если файловая переменная теряется до закрытия, это может быть отмечено как ошибка.
- Недокументированное поведение, возникающее при использовании конструкций, выходящих за рамки спецификации языка.
- Переполнение буфера, особенно при использовании небезопасных функций (например,
strcpy
,sprintf
) или при ошибках работы с массивами и указателями. - Ошибки кроссплатформенности. Например, приведение указателей к типу
int
может работать на 32-битных архитектурах, но потерять значимые данные на 64-битных:
Object *p = getObject();
int pNum = reinterpret_cast<int>(p); // часть указателя теряется на x64
- Копипаст-ошибки в повторяющемся коде — например, неправильное копирование строк с небольшими изменениями:
dest.x = src.x + dx;
dest.y = src.y + dx; // ошибка: дублируется dx, а не dy
- Ошибки форматных строк, особенно в языках со статической типизацией. Например:
std::wstring s;
printf("s is %s and d is %d", s);
- Неиспользуемые или неизменные параметры, которые могут указывать на ошибки проектирования или устаревшую логику:
void doSomething(bool flag) // flag всегда равен true
{
if (flag)
// какая-то логика
else
// код не используется
}
doSomething(true);
- Утечки памяти и ресурсов. Несмотря на то, что динамические анализаторы лучше подходят для выявления таких проблем, статические инструменты также могут обнаруживать ошибки:
Traverser *t = new Traverser(Name);
if (!t->Valid())
{
return FALSE; // выход без delete
delete t;
}
- Вызовы функций без побочных эффектов без использования возвращаемого значения:
std::string s;
s.empty(); // вызов ничего не делает; возможно, имелось в виду s.clear()
- Прочие ошибки, зависящие от конкретного контекста и языка программирования.
Инструменты, такие как PVS-Studio, Coverity и Clang Static Analyzer, предоставляют различные уровни проверки, включая межпроцедурный анализ, анализ сложных выражений, контроль утечек памяти и другие формальные методы[2].
Remove ads
Применение
В последнее время статический анализ всё больше используется в верификации свойств ПО, используемого в компьютерных системах высокой надёжности, особенно критичных для жизни (safety-critical[англ.]). Также применяется для поиска кода, потенциально содержащего уязвимости (иногда это применение называется Static Application Security Testing, SAST)[3].
Статический анализ постоянно применяется для критического ПО в следующих областях:
- ПО для медицинских устройств[4];
- ПО для атомных станций и систем защиты реактора (Reactor Protection Systems)[5];
- ПО для авиации (в комбинации с динамическим анализом)[6];
- ПО на автомобильном или железнодорожном транспорте[7].
По данным VDC на 2012 год, примерно 28 % разработчиков встраиваемого ПО применяют средства статического анализа, а 39 % собираются начать их использование в течение 2 лет[8].
Remove ads
Формальные методы
Суммиров вкратце
Перспектива
Формальные методы — это строго определённые математические подходы, применяемые для доказательства корректности программного обеспечения на основе его спецификаций. В рамках статического анализа кода формальные методы позволяют не только находить ошибки, но и доказывать свойства программ, включая отсутствие определённых классов ошибок, таких как переполнение буфера, гонки данных или утечки памяти.
Примеры применения формальных методов:
- Frama-C — платформа для анализа программ на языке C, использующая аннотации и абстрактную интерпретацию для доказательства корректности.
- SPARK — формальный диалект языка Ada, предназначенный для разработки критичных к безопасности систем. Используется, например, в авионике и управлении железнодорожными системами[9].
- Coq — интерактивная среда доказательств, применяемая для формальной верификации алгоритмов и программ. Используется в проектах типа CompCert, Bedrock и Verasco.
- Why3 — платформа для формальной спецификации и верификации программ, интегрирующая различные автоматические доказатели (Z3, Alt-Ergo и др.).
- Dafny — язык программирования с поддержкой формальной верификации. Компилятор может автоматически доказывать корректность кода относительно спецификации.
Формальные методы находят применение при разработке систем, критичных к безопасности, таких как авионика, медицинские устройства, автомобильные контроллеры и банковские системы. Несмотря на высокую стоимость внедрения, они позволяют существенно снизить риски, связанные с программными ошибками[10].
Инструменты статического анализа
Существует множество инструментов статического анализа, охватывающих различные языки программирования. Ниже приведён перечень наиболее известных из них, основанный в том числе на публикации CISO CLUB[11] и других источниках.
C/C++
C#
- CodeCrawler
- Visual Code Grepper
- PVS-Studio
- NDepend
- StyleCop
- ReSharper
Java
JavaScript
.NET
- Roslyn (.NET Compiler Platform)
- FxCop
- NDepend
- StyleCop
- PVS-Studio
PHP
- PHPStan
- Psalm
- RIPS
- YASCA
- Visual Code Grepper
- SonarQube
Python
Ruby
- Brakeman
Rust
- clippy
Другие
Remove ads
См. также
- Формальная верификация
- Тестирование программного обеспечения
- Безопасное программирование
- Список средств статического анализа кода[англ.]
- MISRA C
Примечания
Ссылки
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads