RaceHound 1.0 - ещё раз о «гонках» в ядре
Недавно вышла версия 1.0 системы RaceHound для поиска «состояний гонки» при обращениях к данным в ядре Linux.
Если говорить простым языком, такие «состояния гонки» — это когда к данной области памяти разные потоки выполнения в программе (или, скажем, в ядре) могут обращаться одновременно, причём хотя бы один из потоков выполнения меняет содержимое этой области памяти. Такие ситуации могут приводить к очень неприятным последствиям, но выявить их бывает очень непросто.
В этом, например, может помочь инструмент KernelStrider. Он находит много потенциальных «гонок», но у него могут быть и ложные срабатывания, то есть бывает, что он сообщает о «гонке», которой нет.
RaceHound же, наоборот, может многое «не заметить», но если он выявил «гонку» — та, действительно, происходит. Кстати, эти инструменты хорошо работают в паре: KernelStrider выявляет потенциальные «гонки», а RaceHound проверяет, действительно ли эти «гонки» происходят.
В частности, таким образом удалось недавно выявить интересную «гонку» в драйвере «uvcvideo» (работа с web-камерой) из ядра 4.1-rc5. Правда, разработчики этого драйвера уверяют, что ничего страшного из-за этой гонки произойти не может, но всё же.
Принцип работы RaceHound очень прост.
- Ставим программную точку прерывания, ПТП, (наподобие того, как это делают отладчики) на те инструкции в коде, которые могут участвовать в «гонке».
- Когда какая-то из ПТП срабатывает, выясняем, к каким данным в памяти соотв. инструкция собирается обратиться, то есть находим их адрес и размер.
- Ставим аппаратные точки прерывания на эту область памяти.
- Делаем небольшую задержку. Если в это время кто-то обратится к этой области памяти, аппаратные точки прерывания сработают — «гонка» выявлена.
- Убираем аппаратные точки прерывания, затем даём возможность той инструкции, для которой выше сработала ПТП, выполняться дальше.
Разумеется, «дьявол — в деталях» и реализовать такой алгоритм на практике оказалось очень и очень непросто. Не зря работа над RaceHound ведётся с лета 2012 года.
По сравнению с предыдущими версиями (0.x), в версии 1.0 наши специалисты существенно переработали основные компоненты RaceHound. Раньше можно было использовать его только для одного выбранного модуля ядра. Теперь же — для произвольного кода как в самом ядре, так и в модулях, для любого участка кода, куда можно поставить программную точку прерывания.
Кстати, при подготовке этой версии была найдена и исправлена ошибка в механизме работы с точками прерывания (точнее, с т. н. Kprobes) в самом ядре. Исправление должно войти в версию ядра 4.1.
[ Хронологический вид ]Комментарии
Войдите, чтобы комментировать.