25
Применение статического анализа для оптимизации динамического поиска гонок Яков Роскошный Университет ИТМО Дмитрий Цителов, Виталий Трифанов, Роман Елизаров OOO "Эксперт-Система"

TMPA-2015: The Application of Static Analysis to Optimize the Dynamic Detection of Race Conditions

Embed Size (px)

Citation preview

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

поиска гонок

Яков РоскошныйУниверситет ИТМО

Дмитрий Цителов, Виталий Трифанов, Роман ЕлизаровOOO "Эксперт-Система"

Гонки

• При отсутствии синхронизации между двумя потоками может возникнуть гонка

• Результат работы программы будет недетерминирован.

Ожидаемое выполнение

Гонка

Методы автоматического поиска гонок

• Анализ кода программы без её запуска.

• NP-трудная задача.Статический

• Анализирует текущий путь выполнения.

• Большие накладные расходы.Динамический

Динамический детектор jDRD

• Основан на отслеживании отношения happens-before с помощью векторных часов.

• Основная проблема – накладные расходы.

• В частности, необходимость контролировать все обращения к разделяемым переменным, по которым возможна гонка.

• Можно применить статический анализ для сужения области анализа jDRD.

Шаблоны обеспечения синхронизации

Неизменяемые объекты

Безопасная публикация объекта

без последующих изменений

Безопасная публикация объекта

Объект, принадлежащий

потоку

Внутренне синхронизированное

поле

Thread confinement

• Объект не покидает контекст одного потока.

• При обращении к таким объектам невозможна гонка.

String a() {

StringBuilder sb = new StringBuilder();

return sb.toString();

}

Безопасная публикация объекта

• Поля класса, экземпляры которого передаются потоку, и затем не покидают его пределов.

Runnable task = new Runnable() {

}

new Thread(task).start();

Безопасная публикация объекта без последующих изменений

• Поля класса инициализируются на начальном этапе конфигурации, а затем только читаются.

• Типичный представитель – конфигурация приложения, доступная через статический контекст.

• Гонки по таким полям могут возникнуть только при отсутствии синхронизации между начальной инициализацией объектов данного класса и их дальнейшим использованием.

Локальные свойства

• Шаблоны– Объект, принадлежащий потоку

– Безопасная публикация объекта

– Безопасная публикация объекта без последующих изменений

• Доказательство теории об отсутствии гонок по полю относится к некоторой ограниченной области кода или зависит от точки порождения объекта.

• Отсутствие гонок может быть гарантировано только для некоторых объектов класса.

Неизменяемые объекты

• Все их поля final и ссылка на объект не «утекает» при конструировании.

• Не изменяют своего состояния после конструирования.

• String, Number.

• jDRD исключает такие объекты из анализа.

Внутренне синхронизированное поле

class A {final Object lock = new Object() ;private int x; //Internally Synchronizedvoid incX() {

synchronized(lock) {x++;

}}void setX(int val) {

synchronized(lock) {x = val;

}}

}

Глобальные свойства

• Шаблоны

– Неизменяемые объекты

– Внутренне синхронизированное поле

• Не зависит от экземпляра объекта и контекста использования.

• Можно исключить из динамического анализа все обращения к этому полю.

Поиск внутренне синхронизированных полей

Получение control flow graph

Выделение множества возможных блокировок

Обход СFG

Промежуточное представление Shimple

• Стек полностью заменен на локальные переменные.

• SSA(Static single assignment) представление. Каждая переменная имеет единственное место присваивания.

• Операции сгруппированы.

• http://sable.github.io/soot/

Пример CFG

void a() {

int x = 3;

int y = 5;

while (y < 5) {

y += x – 1;

}

System.out.println(y);

}

Получение множества возможных блокировок

• Данная часть алгоритма необходима для предотвращения ложных срабатываний.

• Если переменная была инициализирована как φ-функция, или как не final поле, то она не может являться блокировкой.

Обход CFG

• При обходе поддерживаем множество взятых в текущий момент блокировок – curLocks .

Обход CFG

• Для каждого поля f сохраним множество блокировок, с которыми к нему обращались -f.locks.

Обход CFG

• Для каждой вершины CFG будем хранить множество блокировок, с которыми мы посещали данную вершину – v.locks .

Блокировки для методов

• Вызовы методов, аналогично обращению к полям, также могут быть защищены блокировкой.

• Аналогичным анализом можно выделить блокировки для методов

• Затем использовать их при анализе полей.

Результаты

Приложение Общее число полей Защищенных полей Процент

dxFeed 5212 982 19

MARS 2311 477 21

Tomcat 6793 1546 23

jtt 1165 176 15

Приложение Общее число полей Защищенных полей Процент

dxFeed 1555 89 6

MARS 545 20 4

Tomcat 2924 132 5

jtt 405 28 7

Результаты без учета final полей.

Полученные результаты.

Перспективы

• Поиск локальных свойств.

• Результаты анализа могут быть использованы для поиска некоторых ошибок синхронизации.