SlideShare une entreprise Scribd logo
1  sur  37
Статический анализ: вокруг Java за 60 минут
Максим Стефанов
PVS-Studio, C++/Java разработчик, г. Тула
1
О докладчике
• Максим Стефанов (stefanov@viva64.com)
• C++/Java разработчик в компании PVS-Studio
• Деятельность:
• Участие в разработке ядра C++ анализатора
• Участие в разработке Java анализатора
2
О чем поговорим...
• Теория
• Качество кода (баги, уязвимости)
• Методологии защиты кода от дефектов
• Code Review
• Статический анализ и все с ним связанное
• Инструменты
• Существующие инструменты статического анализа
• SonarQube
• PVS-Studio for Java – что это?
• Несколько обнаруженных примеров кода с дефектами
• Еще про статический анализ
• Итоги
3
Зачем уделять внимание качеству кода
• Не накопить технический долг, если проект молодой
• Не потерять пользователей, если проект с историей
4
Стоимость исправления дефекта
Из книги С. Макконнелла "Совершенный Код"
5
Методы обеспечения качества кода
6
Code Review
7
Плюсы Минусы
Выявление дефекта на раннем этапе разработки Утомительно
Увеличение взаимодействия команды Длительно
Повышение степени совместного владения кодом Дорого
Эффект обучения
Свежий взгляд со стороны
(каким бы крутым программистом Вы не были, вы
обязательно что-нибудь забудете)
Выявление ошибок высокого уровня
8
Code Review
Статический анализ кода
Плюсы Минусы
Выявляет дефекты до начала code review Нельзя выявить
высокоуровневые ошибки
Анализатор не устаёт и готов работать в любое время Ложные срабатывания
Можно найти ошибки, даже не зная о таком паттерне
Можно найти ошибки, которые при обзоре крайне
сложно заметить
9
Технологии, используемые при
статическом анализе
•Сопоставление с шаблоном (pattern-based analysis)
•Вывод типов (type inference)
•Анализ потока данных (data-flow analysis)
•Символьное выполнение (symbolic execution)
•Аннотирование методов (method annotations)
10
Сопоставление с шаблоном
(pattern-based analysis)
@Override
public boolean equals(Object obj) {
....
return index.equals(other.index)
&& type.equals(other.type)
&& version == other.version
&& found == other.found
&& tookInMillis == tookInMillis
&& Objects.equals(terms, other.terms);
}
11
Вывод типов
(type inference)
interface Human { ... }
class Parent implements Human{ ... }
class Child extends Parent { ... }
...
class Animal { ... }
...
boolean someMethod(List<Child> list, Animal animal)
{
if (list.remove(animal))
return false;
...
}
12
Аннотирование методов
(method annotations)
Class("java.lang.Math")
- Function("max", Type::Int32, Type::Int32)
.Pure()
.Set(FunctionClassification::NoDiscard)
.Requires(NotEquals(Arg1, Arg2))
.Returns(Arg1, Arg2, [](const Int &v1, const Int &v2)
{
return v1.Max(v2);
}
)
13
Аннотирование методов
(method annotations)
int test(int a, int b) {
Math.max(a, b); //1
if (a > 5 && b < 2) {
// a = [6..INT_MAX]
// b = [INT_MIN..1]
if (Math.max(a, b) > 0) //2
{...}
}
return Math.max(a, a); //3
}
14
Анализ потока данных
(data-flow analysis)
void func(int x) // x: [-2147483648..2147483647] //1
{
if (x > 3)
{
// x: [4..2147483647] //2
if (x < 10)
{
// x: [4..9] //3
}
}
else
{
// x: [-2147483648..3] //4
}
}
15
Символьное выполнение
(symbolic execution)
int someMethod(int A, int B)
{
if (A == B)
return 10 / (A - B);
return 1;
}
16
Существующие инструменты
17
SonarQube: что и зачем
• Платформа с открытым исходным кодом для
непрерывного анализа и измерения качества кода
• Содержит ряд анализаторов для разных языков
• Позволяет интегрировать сторонние анализаторы
• Наглядно визуализирует качество вашего продукта
18
SonarQube: визуализация данных
19
SonarQube: визуализация данных
20
SonarQube: визуализация данных
21
SonarQube: визуализация данных
22
История создания PVS-Studio для Java
• Java - популярный язык
• Большая сфера применения языка
• Была возможность использовать механизмы из
C++ анализатора (data-flow analysis, method
annotations)
23
Внутреннее устройство анализатора
24
Spoon для получения синтаксического
дерева и семантической модели
Spoon преобразует код в метамодель:
class TestClass
{
void test(int a, int b)
{
int x = (a + b) * 4;
System.out.println(x);
}
}
25
Внутреннее устройство анализатора
Data-flow analysis, method annotations - использование
механизмов из C++ анализатора при помощи SWIG
26
Внутреннее устройство анализатора
Диагностическое правило – является визитором, у которого
перегружаются методы, в которых обходятся интересующие нас
элементы по дереву
27
Внутреннее устройство анализатора
Некоторые примеры ошибок, найденных
при помощи PVS-Studio
28
Целочисленное деление
private static boolean checkSentenceCapitalization(@NotNull String value) {
List<String> words = StringUtil.split(value, " ");
....
int capitalized = 1;
....
return capitalized / words.size() < 0.2; // allow reasonable amount of
// capitalized words
}
V6011 [CWE-682] The '0.2' literal of the 'double' type is compared to a value of the 'int' type.
TitleCapitalizationInspection.java 169
IntelliJ IDEA
29
Всегда false
PVS-Studio: V6007 [CWE-570] Expression '"0".equals(text)' is always false. ConvertIntegerToDecimalPredicate.java 46
IntelliJ IDEA
public boolean satisfiedBy(@NotNull PsiElement element) {
....
@NonNls final String text = expression.getText().replaceAll("_", "");
if (text == null || text.length() < 2) {
return false;
}
if ("0".equals(text) || "0L".equals(text) || "0l".equals(text)) {
return false;
}
return text.charAt(0) == '0';
}
30
Незапланированное количество итераций
public static String getXMLType(@WillNotClose InputStream in) throws
IOException
{
....
String s;
int count = 0;
while (count < 4) {
s = r.readLine();
if (s == null) {
break;
}
Matcher m = tag.matcher(s);
if (m.find()) {
return m.group(1);
}
}
....
}
31
SpotBugs
V6007 [CWE-571] Expression 'count < 4' is always true. Util.java 394
Никуда без Copy-Paste
public class RuleDto {
....
private final RuleDefinitionDto definition;
private final RuleMetadataDto metadata;
....
private void setUpdatedAtFromDefinition(@Nullable Long updatedAt) {
if (updatedAt != null && updatedAt > definition.getUpdatedAt()) {
setUpdatedAt(updatedAt);
}
}
private void setUpdatedAtFromMetadata(@Nullable Long updatedAt) {
if (updatedAt != null && updatedAt > definition.getUpdatedAt()) {
setUpdatedAt(updatedAt);
}
}
....
}
32
SonarQube
V6032 It is odd that the body of method 'setUpdatedAtFromDefinition' is fully equivalent to the body of another method
'setUpdatedAtFromMetadata'. Check lines: 396, 405. RuleDto.java 396
Дубликаты
V6033 [CWE-462] An item with the same key 'JavaPunctuator.PLUSEQU' has already been added. Check lines: 104, 100.
KindMaps.java 104
SonarJava
private final Map<JavaPunctuator, Tree.Kind> assignmentOperators =
Maps.newEnumMap(JavaPunctuator.class);
public KindMaps() {
....
assignmentOperators.put(JavaPunctuator.PLUSEQU, Tree.Kind.PLUS_ASSIGNMENT);
....
assignmentOperators.put(JavaPunctuator.PLUSEQU, Tree.Kind.PLUS_ASSIGNMENT);
....
}
33
Как интегрировать статический анализ в
процесс разработки ПО
• Каждый разработчик имеет на рабочем месте
инструмент статического анализа
• Анализ всей кодовой базы при ночных сборках, и в
случае нахождения подозрительного кода - рассылка
писем виновникам
34
Как начать использовать инструменты
статического анализа на больших проектах и не
пасть духом
1. Проверяем проект
2. Указываем, что все выданные предупреждения нам пока не
интересны, поместив их в специальный файл подавления
3. Закладываем файл с разметкой в систему контроля версий
4. Запускаем анализатор и получаем предупреждения только на
новый или измененный код
5. PROFIT!
35
Вывод
• Статический анализ – дополняющая методология, а не
«серебряная пуля»
• Статический анализ должен использоваться регулярно
• Можно начать использовать анализ сразу, отложив правку старых
ошибок на потом
• Конкуренция – залог прогресса
36
Максим Стефанов
stefanov@viva64.com
7 953 968 49 43
37

Contenu connexe

Tendances

Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кода
Andrey Karpov
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Platonov Sergey
 
20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov
Computer Science Club
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
Alex Tumanoff
 
Async clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAsync clinic by by Sergey Teplyakov
Async clinic by by Sergey Teplyakov
Alex Tumanoff
 

Tendances (20)

Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кода
 
TMPA-2015: Lexical analysis of dynamically formed string expressions
TMPA-2015: Lexical analysis of dynamically formed string expressionsTMPA-2015: Lexical analysis of dynamically formed string expressions
TMPA-2015: Lexical analysis of dynamically formed string expressions
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
 
Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о Boost
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov
 
TMPA-2013 Anureyev: On the Road to Technology of Developing the Means of Dedu...
TMPA-2013 Anureyev: On the Road to Technology of Developing the Means of Dedu...TMPA-2013 Anureyev: On the Road to Technology of Developing the Means of Dedu...
TMPA-2013 Anureyev: On the Road to Technology of Developing the Means of Dedu...
 
TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...
TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...
TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...
 
3. Массивы в C#
3. Массивы в C#3. Массивы в C#
3. Массивы в C#
 
C++ refelection and cats
C++ refelection and catsC++ refelection and cats
C++ refelection and cats
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
 
Язык программирования C#
Язык программирования C#Язык программирования C#
Язык программирования C#
 
4. Многомерные массивы и массивы массивов в C#
4. Многомерные массивы и массивы массивов в C#4. Многомерные массивы и массивы массивов в C#
4. Многомерные массивы и массивы массивов в C#
 
Async clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAsync clinic by by Sergey Teplyakov
Async clinic by by Sergey Teplyakov
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
 
Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
 

Similaire à Статический анализ: вокруг Java за 60 минут

статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
Andrey Karpov
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Google
yaevents
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templates
Platonov Sergey
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templates
Platonov Sergey
 

Similaire à Статический анализ: вокруг Java за 60 минут (20)

статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
 
AlgoCollections (RUS)
AlgoCollections (RUS)AlgoCollections (RUS)
AlgoCollections (RUS)
 
Улучшение качества открытого программного обеспечения с помощью инструментов ...
Улучшение качества открытого программного обеспечения с помощью инструментов ...Улучшение качества открытого программного обеспечения с помощью инструментов ...
Улучшение качества открытого программного обеспечения с помощью инструментов ...
 
Пояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteПояснения к статье про Copy-Paste
Пояснения к статье про Copy-Paste
 
Scala for android
Scala for androidScala for android
Scala for android
 
Поиск ошибок в программах на языке C#
Поиск ошибок в программах на языке C#Поиск ошибок в программах на языке C#
Поиск ошибок в программах на языке C#
 
На что способны современные статические анализаторы для C#
На что способны современные статические анализаторы для C#На что способны современные статические анализаторы для C#
На что способны современные статические анализаторы для C#
 
Технологии анализа бинарного кода приложений: требования, проблемы, инструменты
Технологии анализа бинарного кода приложений: требования, проблемы, инструментыТехнологии анализа бинарного кода приложений: требования, проблемы, инструменты
Технологии анализа бинарного кода приложений: требования, проблемы, инструменты
 
Парсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricksПарсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricks
 
Парсим CSS
Парсим CSSПарсим CSS
Парсим CSS
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Google
 
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
 
Выявление ошибок и потенциальных уязвимостей в C и C++ коде с помощью анализа...
Выявление ошибок и потенциальных уязвимостей в C и C++ коде с помощью анализа...Выявление ошибок и потенциальных уязвимостей в C и C++ коде с помощью анализа...
Выявление ошибок и потенциальных уязвимостей в C и C++ коде с помощью анализа...
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templates
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templates
 
Erlang
ErlangErlang
Erlang
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
 
Java 8 puzzlers
Java 8 puzzlersJava 8 puzzlers
Java 8 puzzlers
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMerge
 

Plus de Andrey Karpov

Plus de Andrey Karpov (20)

60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста
 
60 terrible tips for a C++ developer
60 terrible tips for a C++ developer60 terrible tips for a C++ developer
60 terrible tips for a C++ developer
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
PVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewPVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature Overview
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибок
 
PVS-Studio в 2021
PVS-Studio в 2021PVS-Studio в 2021
PVS-Studio в 2021
 
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' Mistakes
 
Does static analysis need machine learning?
Does static analysis need machine learning?Does static analysis need machine learning?
Does static analysis need machine learning?
 
Typical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaTypical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and Java
 
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
 
Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
 
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareThe Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
 
Static Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineStatic Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal Engine
 
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsSafety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
 
The Great and Mighty C++
The Great and Mighty C++The Great and Mighty C++
The Great and Mighty C++
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
Zero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youZero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for you
 

Статический анализ: вокруг Java за 60 минут

  • 1. Статический анализ: вокруг Java за 60 минут Максим Стефанов PVS-Studio, C++/Java разработчик, г. Тула 1
  • 2. О докладчике • Максим Стефанов (stefanov@viva64.com) • C++/Java разработчик в компании PVS-Studio • Деятельность: • Участие в разработке ядра C++ анализатора • Участие в разработке Java анализатора 2
  • 3. О чем поговорим... • Теория • Качество кода (баги, уязвимости) • Методологии защиты кода от дефектов • Code Review • Статический анализ и все с ним связанное • Инструменты • Существующие инструменты статического анализа • SonarQube • PVS-Studio for Java – что это? • Несколько обнаруженных примеров кода с дефектами • Еще про статический анализ • Итоги 3
  • 4. Зачем уделять внимание качеству кода • Не накопить технический долг, если проект молодой • Не потерять пользователей, если проект с историей 4
  • 5. Стоимость исправления дефекта Из книги С. Макконнелла "Совершенный Код" 5
  • 8. Плюсы Минусы Выявление дефекта на раннем этапе разработки Утомительно Увеличение взаимодействия команды Длительно Повышение степени совместного владения кодом Дорого Эффект обучения Свежий взгляд со стороны (каким бы крутым программистом Вы не были, вы обязательно что-нибудь забудете) Выявление ошибок высокого уровня 8 Code Review
  • 9. Статический анализ кода Плюсы Минусы Выявляет дефекты до начала code review Нельзя выявить высокоуровневые ошибки Анализатор не устаёт и готов работать в любое время Ложные срабатывания Можно найти ошибки, даже не зная о таком паттерне Можно найти ошибки, которые при обзоре крайне сложно заметить 9
  • 10. Технологии, используемые при статическом анализе •Сопоставление с шаблоном (pattern-based analysis) •Вывод типов (type inference) •Анализ потока данных (data-flow analysis) •Символьное выполнение (symbolic execution) •Аннотирование методов (method annotations) 10
  • 11. Сопоставление с шаблоном (pattern-based analysis) @Override public boolean equals(Object obj) { .... return index.equals(other.index) && type.equals(other.type) && version == other.version && found == other.found && tookInMillis == tookInMillis && Objects.equals(terms, other.terms); } 11
  • 12. Вывод типов (type inference) interface Human { ... } class Parent implements Human{ ... } class Child extends Parent { ... } ... class Animal { ... } ... boolean someMethod(List<Child> list, Animal animal) { if (list.remove(animal)) return false; ... } 12
  • 13. Аннотирование методов (method annotations) Class("java.lang.Math") - Function("max", Type::Int32, Type::Int32) .Pure() .Set(FunctionClassification::NoDiscard) .Requires(NotEquals(Arg1, Arg2)) .Returns(Arg1, Arg2, [](const Int &v1, const Int &v2) { return v1.Max(v2); } ) 13
  • 14. Аннотирование методов (method annotations) int test(int a, int b) { Math.max(a, b); //1 if (a > 5 && b < 2) { // a = [6..INT_MAX] // b = [INT_MIN..1] if (Math.max(a, b) > 0) //2 {...} } return Math.max(a, a); //3 } 14
  • 15. Анализ потока данных (data-flow analysis) void func(int x) // x: [-2147483648..2147483647] //1 { if (x > 3) { // x: [4..2147483647] //2 if (x < 10) { // x: [4..9] //3 } } else { // x: [-2147483648..3] //4 } } 15
  • 16. Символьное выполнение (symbolic execution) int someMethod(int A, int B) { if (A == B) return 10 / (A - B); return 1; } 16
  • 18. SonarQube: что и зачем • Платформа с открытым исходным кодом для непрерывного анализа и измерения качества кода • Содержит ряд анализаторов для разных языков • Позволяет интегрировать сторонние анализаторы • Наглядно визуализирует качество вашего продукта 18
  • 23. История создания PVS-Studio для Java • Java - популярный язык • Большая сфера применения языка • Была возможность использовать механизмы из C++ анализатора (data-flow analysis, method annotations) 23
  • 25. Spoon для получения синтаксического дерева и семантической модели Spoon преобразует код в метамодель: class TestClass { void test(int a, int b) { int x = (a + b) * 4; System.out.println(x); } } 25 Внутреннее устройство анализатора
  • 26. Data-flow analysis, method annotations - использование механизмов из C++ анализатора при помощи SWIG 26 Внутреннее устройство анализатора
  • 27. Диагностическое правило – является визитором, у которого перегружаются методы, в которых обходятся интересующие нас элементы по дереву 27 Внутреннее устройство анализатора
  • 28. Некоторые примеры ошибок, найденных при помощи PVS-Studio 28
  • 29. Целочисленное деление private static boolean checkSentenceCapitalization(@NotNull String value) { List<String> words = StringUtil.split(value, " "); .... int capitalized = 1; .... return capitalized / words.size() < 0.2; // allow reasonable amount of // capitalized words } V6011 [CWE-682] The '0.2' literal of the 'double' type is compared to a value of the 'int' type. TitleCapitalizationInspection.java 169 IntelliJ IDEA 29
  • 30. Всегда false PVS-Studio: V6007 [CWE-570] Expression '"0".equals(text)' is always false. ConvertIntegerToDecimalPredicate.java 46 IntelliJ IDEA public boolean satisfiedBy(@NotNull PsiElement element) { .... @NonNls final String text = expression.getText().replaceAll("_", ""); if (text == null || text.length() < 2) { return false; } if ("0".equals(text) || "0L".equals(text) || "0l".equals(text)) { return false; } return text.charAt(0) == '0'; } 30
  • 31. Незапланированное количество итераций public static String getXMLType(@WillNotClose InputStream in) throws IOException { .... String s; int count = 0; while (count < 4) { s = r.readLine(); if (s == null) { break; } Matcher m = tag.matcher(s); if (m.find()) { return m.group(1); } } .... } 31 SpotBugs V6007 [CWE-571] Expression 'count < 4' is always true. Util.java 394
  • 32. Никуда без Copy-Paste public class RuleDto { .... private final RuleDefinitionDto definition; private final RuleMetadataDto metadata; .... private void setUpdatedAtFromDefinition(@Nullable Long updatedAt) { if (updatedAt != null && updatedAt > definition.getUpdatedAt()) { setUpdatedAt(updatedAt); } } private void setUpdatedAtFromMetadata(@Nullable Long updatedAt) { if (updatedAt != null && updatedAt > definition.getUpdatedAt()) { setUpdatedAt(updatedAt); } } .... } 32 SonarQube V6032 It is odd that the body of method 'setUpdatedAtFromDefinition' is fully equivalent to the body of another method 'setUpdatedAtFromMetadata'. Check lines: 396, 405. RuleDto.java 396
  • 33. Дубликаты V6033 [CWE-462] An item with the same key 'JavaPunctuator.PLUSEQU' has already been added. Check lines: 104, 100. KindMaps.java 104 SonarJava private final Map<JavaPunctuator, Tree.Kind> assignmentOperators = Maps.newEnumMap(JavaPunctuator.class); public KindMaps() { .... assignmentOperators.put(JavaPunctuator.PLUSEQU, Tree.Kind.PLUS_ASSIGNMENT); .... assignmentOperators.put(JavaPunctuator.PLUSEQU, Tree.Kind.PLUS_ASSIGNMENT); .... } 33
  • 34. Как интегрировать статический анализ в процесс разработки ПО • Каждый разработчик имеет на рабочем месте инструмент статического анализа • Анализ всей кодовой базы при ночных сборках, и в случае нахождения подозрительного кода - рассылка писем виновникам 34
  • 35. Как начать использовать инструменты статического анализа на больших проектах и не пасть духом 1. Проверяем проект 2. Указываем, что все выданные предупреждения нам пока не интересны, поместив их в специальный файл подавления 3. Закладываем файл с разметкой в систему контроля версий 4. Запускаем анализатор и получаем предупреждения только на новый или измененный код 5. PROFIT! 35
  • 36. Вывод • Статический анализ – дополняющая методология, а не «серебряная пуля» • Статический анализ должен использоваться регулярно • Можно начать использовать анализ сразу, отложив правку старых ошибок на потом • Конкуренция – залог прогресса 36