Статический анализ кода | это... Что такое Статический анализ кода? (original) (raw)
Стати́ческий ана́лиз ко́да (англ. static code analysis) — анализ программного обеспечения, производимый без реального выполнения исследуемых программ (анализ, производимый с выполнением программ, называется динамический анализ кода). В большинстве случаев анализ производится над какой-либо версией исходного кода, хотя иногда анализу подвергается какой-нибудь вид объектного кода, например P-код или код на MSIL. Термин обычно применяют к анализу, производимому специальным ПО, тогда как ручной анализ называют пониманием или постижением программы.
В зависимости от используемого инструмента глубина анализа может варьироваться от определения поведения отдельных операторов до анализа, включающего весь имеющийся исходный код. Способы использования полученной в ходе анализа информации также различны — от выявления мест, возможно содержащих ошибки, до формальных методов, позволяющих математически доказать какие-либо свойства программы (например, соответствие поведения спецификации).
Некоторые люди считают программные метрики и обратное проектирование формами статического анализа.
В последнее время статический анализ всё больше используется в верификации свойств ПО, используемого в компьютерных системах высокой надёжности.
Содержание
- 1 Принципы статического анализа
- 2 Формальные методы
- 3 Инструменты статического анализа
- 4 См. также
- 5 Примечания
- 6 Ссылки
Принципы статического анализа
Большинство компиляторов (например, GNU C Compiler) выводят на экран «предупреждения» (англ. warnings) — сообщения о том, что код, будучи синтаксически правильным, скорее всего, содержит ошибку. Например:
int x; int y = x+2; // Переменная x не инициализирована!
Это простейший статический анализ. У компилятора есть много других немаловажных характеристик — в первую очередь скорость работы и качество машинного кода, поэтому компиляторы проверяют код лишь на очевидные ошибки. Статические анализаторы предназначены для более детального исследования кода.
Типы ошибок, обнаруживаемых статическими анализаторами
- Неопределённое поведение — неинициализированные переменные, обращение к NULL-указателям. О простейших случаях сигнализируют и компиляторы.
- Нарушение блок-схемы пользования библиотекой. Например, для каждого
fopen
нуженfclose
. И если файловая переменная теряется раньше, чем файл закрывается, анализатор может сообщить об ошибке. - Типичные сценарии, приводящие к недокументированному поведению. Стандартная библиотека языка Си известна большим количеством неудачных технических решений. Некоторые функции, например,
[gets](605029)
, в принципе небезопасны.[sprintf](749087)
и[strcpy](114913)
безопасны лишь при определённых условиях. - Переполнение буфера — когда компьютерная программа записывает данные за пределами выделенного в памяти буфера.
void doSomething(const char* x) { char s[40]; sprintf(s, "[%s]", x); // sprintf в локальный буфер, возможно переполнение .... }
- Типичные сценарии, мешающие кроссплатформенности.
Object *p = getObject(); int pNum = reinterpret_cast(p); // на x86-32 верно, на x64 часть указателя будет потеряна; нужен size_t
- Ошибки в повторяющемся коде. Многие программы исполняют несколько раз одно и то же с разными аргументами. Обычно повторяющиеся фрагменты не пишут с нуля, а размножают и исправляют.
dest.x = src.x + dx; dest.y = src.y + dx; // Ошибка, надо dy!
- Ошибки форматных строк — в функциях наподобие
[printf](192635)
могут быть ошибки с несоответствием форматной строки реальному типу параметров.[1]
std::wstring s; printf ("s is %s", s);
- Неизменный параметр, передаваемый в функцию — признак изменившихся требований к программе. Когда-то параметр был задействован, но сейчас он уже не нужен. В таком случае программист может вообще избавиться от этого параметра — и от связанной с ним логики.
void doSomething(int n, bool flag) // flag всегда равен true { if (flag) { // какая-то логика } else { // код есть, но не задействован } }
doSomething(n, true); ... doSomething(10, true); ... doSomething(x.size(), true);
- Прочие ошибки — многие функции из стандартных библиотек не имеют побочного эффекта, и вызов их как процедур не имеет смысла.[1]
std::string s; ... s.empty(); // код ничего не делает; вероятно, вы хотели s.clear()?
Формальные методы
Инструменты статического анализа
- BLAST
- Coverity
- FindBugs [2]
- lint и lock_lint, входящие в состав Sun Studio
- MSR Tools
- Parasoft C++Test, JTest
- ReSharper
- Sonar
- SourceAnalyzer
- T-SQL Analyzer — инструмент, который может просматривать программные модули в базах данных под управлением Microsoft SQL Server 2005 или 2008 и обнаруживать потенциальные проблемы, связанные с низким качеством кода.
- АК-ВС
См. также
- Формальная семантика ЯП
- Формальная верификация
- Анализ программного обеспечения
- Тестирование программного обеспечения
- Постепенная деградация
- SPARK — ЯП