Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TMPA-2013 Tsytelov Trifanov Devexperts

TMPA-2013 Tsytelov Trifanov Devexperts

Tools & Methods of Program Analysis (TMPA-2013)
Tsytelov, D., Trifanov, V., Devexperts LLC, St. Petersburg State University
Search of Race Conditions in Java Programs Based on Synchronization Contracts

5206c19df417b8876825b5561344c1a0?s=128

Exactpro
PRO

October 12, 2013
Tweet

Transcript

  1. Динамический поиск гонок в Java- программах на основе синхронизационных контрактов

    Дмитрий Цителов, Devexperts LLC Виталий Трифанов, Devexperts LLC, мат-мех СПбГУ
  2. Состояния гонки • 2+ потоков • к одним и тем

    же данным • хотя бы одно из них - запись • Обычно это ошибка
  3. Пример гонки public class Account { private int amount =

    0; public void deposit(int x) {amount += x;} public int getAmount() {return amount;} } public class TestRace { public static void main (String[] args) { final Account a = new Account(); Thread t1 = depositAccountInNewThread(a, 5); Thread t2 = depositAccountInNewThread(a, 6); t1.join(); t2.join(); System.out.println(account.getAmount()); //5? 6? 11?. } }
  4. Свойства гонок • Опасны – Повреждают глобальные данные – Не

    приводят к немедленному отказу программы • Сложно обнаружить вручную • Трудно воспроизводимы
  5. Статический подход • Анализ кода программы без её запуска •

    Расширение языка, система типов • Ограниченная глубина анализа • Есть много утилит для Java – FindBugs, jChord, etc.
  6. Динамический подход • Анализирует только текущий путь выполнения • Поддерживает

    все средства синхронизации • Огромные накладные расходы • Нет готовых детекторов для Java
  7. Java Memory Model • На синхронизационных событиях есть отношение порядка

    «synchronized-with» • Synchronized-with + порядок событий в одном потоке = частичное отношение порядка happens-before • Отслеживаем happens-before с помощью векторных(логических) часов Ламперта • Метод точный, но много накладных расходов
  8. Идея • Приложения используют библиотеки через API • API хорошо

    документировано – Класс XXX потокобезопасен – Класс YYY непотокобезопасен – ZZZ.get() синхронизирован с ZZZ.put() • Опишем поведение API • Исключим библиотеку из анализа
  9. Пример синхронизационного контракта

  10. Типы связей • Явные • Простые • Сигнатура метода: retval

    owner.method(parameters) • Любая комбинация простых связей • Условия на возвращаемое значение
  11. Примитивные простые явные связи Owner Param Return value Owner chm.put(k,

    v) ↓ chm.get(k) ex.sumbit(task) ↓ task.run() Наверное, тоже бывает Param chm.put(k, v) ↓ chm.get(k) Наверное, тоже бывает Return value Наверное, тоже бывает
  12. Пример описания контракта

  13. Пример описания контракта

  14. Язык контрактов • Happens-before контракты – пары методов – всех

    методов класса • Потокобезопасность метода – ну, или всех методов класса (умеем «*») • Тип непотокобезопасного метода – Read – Write (по умолчанию)
  15. Области анализа (RD) (SD)

  16. Алгоритм • В основе – отслеживание happens-before • Операции синхронизации

    в SD: – synchronized, volatile, thread start/join, … – happens-before контракты – не отслеживаем, если в контрактном методе • Обращения к данным в RD (RD ∈ SD): – к полям классов из RD – вызовы непотокобезопасных методов классов, не принадлежащих RD
  17. Реализация Instrumented app classes Application classes

  18. Детали реализации • Не сломать сериализацию • Не давать разрастаться

    часам • Хранение контрактов • Не генерировать garbage
  19. Экспериментальные результаты Приложение JTT QD MARS client MARS Server Режим

    base juc base juc base juc base juc Синхр. оп-ий/мин 115К 28К 15М 7.2М 7.4 М 4.3 М 1650К 800К Кол-во синх. часов 13К 7К 6.1K 0.2K 85K 72K 15К 14К Контрактов/мин 2.3K 0.6K 209К 130К 980К 730К 360К 904К Кол-во контр. часов 8.5K 0.75K 1.4М 1.4М 17К 24К 5.5К 5.5К Найдено гонок 8 10 1 6 1 5 2 2
  20. Ограничения • Трактуем контракты как атомарные – это неизбежно для

    неблокирующих средств синхронизации – volatile, etc. • Только контракты на основе простых связей – Если сложней, то просто не описывать, детектор шагнёт «внутрь» метода – Lock.newCondition().await() – печаль – ConcurrentMap.entrySet().iterator() – печаль • Только контракты без сайд-эффектов – Грубо говоря, только контейнеры – Если Executor вызовет task.foo() вместо run() – печаль.
  21. Заключение • Модифицировали happens-before • Научились легко описывать контракты •

    В экспериментах не потеряли точность • Нашли больше гонок • Стало меньше часов • Стало меньше шума • Хорошо, но всё еще впереди – Open source – Доработка языка и детектора – Эксперименты
  22. Спасибо! • Пишите нам: – drd-support@devexperts.com – vitaly.trifanov@gmail.com – tsitelov@acm.org

    • Можно скачать и попробовать: – http://code.devexperts.com/display/DRD/ – Это еще бета-версия