Статический анализ кода

Перейти к навигацииПерейти к поиску

Стати́ческий ана́лиз ко́да (англ. static code analysis) — анализ исходного кода программного обеспечения, производимый без реального выполнения исследуемых программ (в отличие от динамического анализа). В большинстве случаев анализ производится над исходным кодом, хотя, иногда анализу подвергается объектный код, например P-код или код на MSIL. Термин обычно применяют к анализу, производимому специальным программным обеспечением (ПО), тогда как ручной анализ называют «program understanding», «program comprehension» (пониманием или постижением программы).

В зависимости от используемого инструмента глубина анализа может варьироваться от определения поведения отдельных операторов до анализа всего имеющегося кода. Способы использования полученной в ходе анализа информации также различны — от выявления мест, возможно содержащих ошибки (утилиты типа Lint), до формальных методов, позволяющих математически доказать какие-либо свойства программы (например, соответствие поведения спецификации).

В некоторых источниках программные метрики и обратное проектирование относятся к формам статического анализа. Получение метрик (англ. software quality objectives) и статический анализ часто совмещаются, особенно при создании встраиваемых систем.[1]

Принципы статического анализа

Примером простейшего синтаксического анализа являются генерируемые большинством компиляторов (например, GNU C Compiler) «предупреждения» (англ. warnings) — диагностические сообщения о потенциальной ошибочности синтаксически правильного кода. Например, для следующего кода на C может быть получено сообщение о неинициализированной переменной:

int x;
int y = x + 2;  // Переменная x не инициализирована!

В связи с высокими требованиями к скорости компиляции и качеству машинного кода компиляторы проверяют код лишь на простейшие ошибки. Статические анализаторы предназначены для более детального исследования кода.

Типы ошибок, обнаруживаемых статическими анализаторами

  • Неопределённое поведение — неинициализированные переменные, обращение к NULL-указателям. О простейших случаях сигнализируют и компиляторы.
  • Нарушение алгоритма пользования библиотекой. Например, во многих языках программирования каждому открытию файла должно соответствовать его закрытие, поэтому если файловая переменная теряется раньше, чем файл закрывается, анализатор может сообщить об ошибке.
  • Сценарии, приводящие к недокументированному поведению.
  • Переполнение буфера, чаще всего вызванное использованием небезопасных функций или неопределённым поведением.
  • Типичные сценарии, мешающие кроссплатформенности.
Object *p = getObject();
int pNum = reinterpret_cast<int>(p);    // на x86-32 верно, на x64 часть указателя будет потеряна; следует использовать intptr_t
  • Ошибки в повторяющемся коде. Многие программы исполняют несколько раз схожий код, обычно не создаваемый с нуля, а размножаемый и исправляемый.
dest.x = src.x + dx;
dest.y = src.y + dx;  // Опечатка: вместо dy указан dx
  • Ошибки форматных строк — в функциях форматированного ввода и вывода (например, printf) форматная строка может не соответствовать реальному количеству и типам параметров.
std::wstring s;
printf("s is %s and d is %d", s);
  • Неизменный параметр, передаваемый в функцию, может свидетельствовать об изменившихся требованиях к программе или об ошибке при кодировании. В первом случае программист может избавиться от этого параметра и от связанной с ним логики.
void doSomething(bool flag)   // flag всегда равен true
{
   if (flag)
       // какая-то логика
   else
       // код есть, но не задействован
}
...
doSomething(true);
...
  • Утечки памяти и других ресурсов. В целом статические анализаторы проигрывают в сфере поиска утечек динамическим анализаторам кода[2][].
Traverser *t = new Traverser(Name);
if (!t->Valid())
{
  return FALSE; // return до освобождения памяти.
  delete t;
}
  • Вызов функций, не имеющих побочного эффекта как процедур (без сохранения возвращаемого значения):
std::string s;
...
s.empty();     // код ничего не делает; возможно, опечатка и должно быть s.clear()?
  • Прочие ошибки.

Применение

В последнее время статический анализ всё больше используется в верификации свойств ПО, используемого в компьютерных системах высокой надёжности, особенно критичных для жизни (safety-critical[англ.]). Также применяется для поиска кода, потенциально содержащего уязвимости (иногда это применение называется Static Application Security Testing, SAST).[3]

Статический анализ постоянно применяется для критического ПО в следующих областях:

  1. ПО для медицинских устройств.[4]
  2. ПО для атомных станций и систем защиты реактора (Reactor Protection Systems)[5]
  3. ПО для авиации (в комбинации с динамическим анализом)[6]
  4. ПО на автомобильном или железнодорожном транспорте[7]

По данным VDC на 2012 год, примерно 28 % разработчиков встраиваемого ПО применяют средства статического анализа, а 39 % собираются начать их использование в течение 2 лет.[8]

Формальные методы

Инструменты статического анализа

Инструменты по анализируемым языкам, некоторый из которых выделяет CISO CLUB[9]:

C/C++:

C#:

Java:

JavaScript:

.NET:

  • .NET Compiler Platform (Roslyn) — фреймворк компилятора для C# и VB.NET, предоставляющий интерфейс для анализатора.
  • FxCop
  • Microsoft FxCop
  • NDepend
  • PVS-Studio
  • ReSharper
  • StyleCop
  • YASCA

PHP:

Python:[11][12]

  • Flake8
  • Graudit
  • Pychecker[англ.]
  • Pylint
  • McCabe
  • Pyflakes
  • Pycodestyle
  • Solar appScreener
  • YASCA

Ruby:

Другие:[]

  • T-SQL Analyzer — инструмент, который может просматривать программные модули в базах данных под управлением Microsoft SQL Server 2005 или 2008 и обнаруживать потенциальные проблемы, связанные с низким качеством кода.
  • SonarQube — платформа анализа и управления качеством кода с поддержкой различных языков программирования через систему плагинов.

См. также

Примечания

  1. Software Quality Objectives for Source Code. Proceedings Embedded Real Time Software and Systems 2010 Conference, ERTS2, Toulouse, France: Patrick Briand, Martin Brochet, Thierry Cambois, Emmanuel Coutenceau, Olivier Guetta, Daniel Mainberte, Frederic Mondot, Patrick Munier, Loic Noury, Philippe Spozio, Frederic Retailleau http://www.erts2010.org/Site/0ANDGY78/Fichier/PAPIERS%20ERTS%202010/ERTS2010_0035_final.pdf Архивная копия от 12 марта 2012 на Wayback Machine
  2. Да, PVS-Studio умеет выявлять утечки памяти Архивная копия от 15 мая 2018 на Wayback Machine / Блог компании PVS Studio
  3. Improving Software Security with Precise Static and Runtime Analysis, Benjamin Livshits, section 7.3 "Static Techniques for Security, " Stanford doctoral thesis, 2006. http://research.microsoft.com/en-us/um/people/livshits/papers/pdf/thesis.pdf Архивная копия от 5 июня 2011 на Wayback Machine
  4. FDA Infusion Pump Software Safety Research at FDA. Food and Drug Administration (8 сентября 2010). Дата обращения: 9 сентября 2010. Архивировано 1 сентября 2010 года.
  5. Computer based safety systems — technical guidance for assessing software aspects of digital computer based protection systems, http://www.hse.gov.uk/nuclear/operational/tech_asst_guides/tast046.pdf Архивная копия от 9 октября 2012 на Wayback Machine
  6. Position Paper CAST-9. Considerations for Evaluating Safety Engineering Approaches to Software Assurance Архивная копия от 6 октября 2013 на Wayback Machine // FAA, Certification Authorities Software Team (CAST), January, 2002: «Verification. A combination of both static and dynamic analyses should be specified by the applicant/developer and applied to the software.»
  7. Bill Graham. Static Analysis, Safety-Critical Railway Software, and EN 50128. Дата обращения: 2 сентября 2016. Архивировано 25 августа 2016 года.
  8. VDC Research Automated Defect Prevention for Embedded Software Quality. VDC Research (1 февраля 2012). Дата обращения: 10 апреля 2012. Архивировано 7 апреля 2012 года.
  9. ТОП бесплатных инструментов для статического анализа кода. cisoclub.ru (11 февраля 2021). Дата обращения: 19 ноября 2021. Архивировано 19 сентября 2021 года.
  10. Clang Static Analyzer. clang-analyzer.llvm.org. Дата обращения: 14 мая 2016. Архивировано 8 октября 2011 года.
  11. Anand Balachandran Pillai. Software Architecture with Python. — Packt Publishing Ltd, 2017. — С. 63—64.
  12. Adam Goucher, Tim Riley. Beautiful Testing: Leading Professionals Reveal How They Improve Software. — O'Reilly Media, Inc., 2009. — P. 126.

Ссылки