Целью этого доклада является представление взгляда на использование машинного обучения в статическом анализе кода со стороны классического подхода. Нужен ли этот "инновационный подход" в этой сфере вообще и какие проблемы связаны с его использованием?
Рассмотрим популярные решения присутствующие на рынке и получим общее представление для каких задач в них используется машинное обучение. Проблемы обучения статического анализатора "вручную". Проблемы обучения на большом количестве открытого исходного кода. О том, решение каких задач в сфере статического анализа с использованием машинного обучения кажется особенно перспективным.
1. Нужно ли статическому анализу
машинное обучение?
Антидоклад
Виктория Ханиева
PVS-Studio
2. Докладчик
2
Ханиева Виктория
• Разработчик С++ в PVS-Studio
• Участие в поддержке стандарта MISRA
• Написание статей про проверку
open-source проектов
khanieva@viva64.com
www.viva64.com
3. Знакомство со статическим анализом
Какие решения уже есть на рынке и какие подходы они реализуют
Проблемы и подводные камни при создании анализатора
При обучении «вручную»
При обучении на большом количестве реального кода
Многообещающие подходы
О чем пойдет речь
3
6. Ручной анализ (code review)
Динамический анализ
Какой анализ кода бывает
6
7. Ручной анализ (code review)
Динамический анализ
Статический анализ
Какой анализ кода бывает
7
8. Процесс выявления ошибок и недочетов в
исходном коде программ.
Выявление ошибок в программах
Рекомендации по оформлению кода
Подсчет метрик
….
Статический анализ
8
19. Java, JS, TS, Python, C, C++
Review кода и аудит
Можно попробовать на open-source проекте или
посмотреть демки
Подборка публикаций
DeepCode
19
Link
21. Java, C, C++, Objective-C
By Facebook
Опубликован исходный код
Можно попробовать на своих проектах
Основан на логике Хоара, separation logic
и bi-abduction, а также на теории
абстрактной интерпретации (abstract
interpretation)
Infer
21
Link
22. Работает с результатами Infer
Предлагает возможные варианты исправлений
SapFix
22
23. Платформа для анализа
качества проекта
Система предложения правок
Поиск взаимосвязей между
функциями и методами с
помощью NLP
Embold
23
24. Открытый исходный код
Подборка публикаций
Репозиторий с датасетом для обучения
Выявление code-style
Платформа для сбора метрик и статистики
Source{d}
24
Link
25. Правка код-стайла в Source{d}
25
Основано на статье
“STYLE-ANALYZER: fixing
code style inconsistencies
with interpretable
unsupervised algorithms”
Link
26. By Mozilla+Ubisoft
Ищет подозрительные коммиты
Основано на публикации “CLEVER: Combining Code
Metrics with Clone Detection for Just-In-Time Fault
Prevention and Resolution in Large Industrial Projects”
Clever-Commit
26
Link
27. Java
By Amazon
Рекомендации по лучшим практикам из
документации и кодовой базы
CodeGuru
27
29. Анализ кода для поиска ошибок
Анализ кода для поиска отклонений от best practices
Анализ код-артефактов
Сбор метрик и данных по коду
Код-стайл
Основные направления
29
30. Подобранная база из open-source репозиториев
Собранный вручную датасет
Собственная база проектов
Способы обучения
30
31. Проблемы и подводные камни
31
*с точки зрения разработчика классического стат анализатора
32. Как может выглядеть:
• if (X && A == A)
• if (A + 1 == A + 1)
• if (A[i] == A[i])
• if ((A) == (A))
• …
Подборка датасета «вручную»
32
Нужно найти:
if (A == A)
35. Нужно найти:
int y = x / 0;
Как это часто выглядит на практике
35
Как может выглядеть:
template <class T> class numeric_limits {
....
}
namespace boost {
....
}
namespace boost {
namespace hash_detail {
template <class T> void dsizet(size_t x) {
size_t length = x / (limits<int>::digits - 31);
}
}
}
36. @Override
public String getText(Mode mode) {
StringBuilder sb = new StringBuilder();
....
if (filter.getMessage()
.toLowerCase(Locale.ENGLISH)
.startsWith("Each ")) {
sb.append(" has base power and toughness ");
} else {
sb.append(" have base power and toughness ");
}
....
return sb.toString();
}
Анализ потока данных
36
37. Анализ потока данных
37
uint32_t* BnNew() {
uint32_t* result = new uint32_t[kBigIntSize];
memset(result, 0, kBigIntSize * sizeof(uint32_t));
return result;
}
std::string AndroidRSAPublicKey(crypto::RSAPrivateKey* key) {
....
uint32_t* n = BnNew();
....
RSAPublicKey pkey;
....
if (pkey.n0inv == 0)
return kDummyRSAPublicKey; // <=
....
}
38. «На GitHub полно проектов, обучим анализатор на
репозиториях и коммитах в них» превращается в сбор и
разметку коммитов.
Если база для обучения, собранная вручную, оказывается
ненадежной, то что уж ожидать от автоматически-
собранной.
Обучение на большом количестве кода
38
39. Смотрим коммит со словом fix, а там:
Обучение на большом количестве кода
39
40. Анализатор должен быть up to date относительно
проверяемого языка
Большинство проектов используют старые
стандарты
Большинство проектов не используют новые
конструкции
Устаревание кода
40
45. Пример кода:
ObjectOutputStream out = new ObjectOutputStream(....);
SerializedObject obj = new SerializedObject();
obj.state = 100;
out.writeObject(obj);
obj.state = 200;
out.writeObject(obj);
out.close();
Почему документация нужна
45
46. Предложение анализатора по правке:
ObjectOutputStream out = new ObjectOutputStream(....);
SerializedObject obj = new SerializedObject();
obj.state = 100;
out.writeObject(obj);
obj = new SerializedObject(); // Добавилась эта строка
obj.state = 200;
out.writeObject(obj);
out.close();
Почему документация нужна
46
47. Что происходит без правки:
ObjectOutputStream out = new ObjectOutputStream(....);
SerializedObject obj = new SerializedObject();
obj.state = 100;
out.writeObject(obj); // сохраняет объект с состоянием = 100
obj.state = 200;
out.writeObject(obj); // сохраняет объект с состоянием = 100
out.close();
Почему документация нужна
47
52. Может быть неизвестна причина срабатывания или НЕ
срабатывания на конкретный участок кода
Как исправить?
Дообучение (а поможет?)
Механизмом скрытия предупреждений (не универсально)
Ложные срабатывания
52