Как отлаживать тупиковые проблемы в ядре - PullRequest
5 голосов
/ 05 февраля 2012

У меня неисправный модуль ядра, который я пытаюсь исправить.Обычно, когда этот модуль работает, другие задачи будут зависать более 120 секунд.Поскольку почти все зависшие задачи ожидают либо mm-> mmap_sem, либо каких-либо блокировок файловой системы (i_node-> i_mutex), я подозреваю, что это как-то связано с этим модулем, который не захватывает блокировку mmap_sem и некоторый уровень файловой системы.блокировка (например, inote-> i_mutex) по порядку, что могло вызвать проблемы с тупиком.Поскольку мой модуль не пытается захватить эти блокировки напрямую, я предполагаю, что это была вызванная мной функция, которая захватывает эти блокировки.И теперь я пытаюсь выяснить, какие вызовы функций в моем модуле вызывают проблему.

Однако мне трудно отладить его по следующим причинам:

  1. Я не знаю точно, какую блокировку пытается получить зависшая задача.Я получил трассировку вызова зависшей задачи и знаю, в какой момент она зависает.Ядро также дает мне некоторую информацию, такую ​​как: «1 блокировка, удерживаемая automount / 3115: 0: (& type-> i_mutex_dir_key # 2) {- ..}, в: [] real_lookup + 0x24 / 0xc5».Однако я хочу точно знать, какую блокировку удерживает задача, и какую именно блокировку она пытается получить, чтобы выяснить проблему.Поскольку ядро ​​не предоставляет аргументы вызовов функций вместе с трассировкой вызовов, мне трудно получить эту информацию.

  2. Я использую gdb и vmware для отладки этого, что позволяет мне устанавливать точки останова, входить в функцию и тому подобное.Однако, поскольку какая задача и в какой момент эта задача будет зависать, является своего рода недетерминированной, я действительно не знаю, где устанавливать точки останова и проверять.Было бы здорово, если бы я мог как-то «присоединиться» к задаче, ядро ​​которой, как сообщалось, было заблокировано более 120 секунд, и получить некоторую информацию об этом.

Итак, мои вопросы следующие:

  1. Где я могу получить, наряду с трассировкой вызова, аргументы функций в вызоветрассировка, чтобы выяснить, какую именно блокировку пытается получить задача.

  2. Могу ли я использовать gdb для того, чтобы каким-то образом "прикрепить" к зависшей задаче в ядре?Если нет, есть ли какой-нибудь способ для меня, по крайней мере, изучить структуру данных, которая представляет эту задачу?Так как мне тяжело исследовать всю глобальную структуру данных в ядре.GDB всегда жалуется, что «не может получить доступ к памяти 0x3200» или что-то подобное.

  3. Было бы также очень полезно, если бы я мог распечатать для каждой задачи в ядре, какие блокировки они в данный момент удерживают.Есть ли способ сделать это?

Большое спасибо!

Ответы [ 3 ]

3 голосов
/ 05 февраля 2012

Не отвечая на ваш вопрос напрямую, но, надеюсь, это более полезно - ядро ​​Linux имеет встроенный сверхпрочный валидатор блокировки, называемый lockdep. Включите его и дайте ему поработать. Если у вас возникла проблема с порядком блокировки, она, вероятно, перехватит ее и предоставит подробный отчет.

См .: http://www.mjmwired.net/kernel/Documentation/lockdep-design.txt

2 голосов
/ 14 марта 2014

Функция ядра lockdep может помочь вам в этом.Прочтите мой пост о том, как использовать его в вашем ядре: Как использовать функцию lockdep в ядре Linux для обнаружения тупиков

1 голос
/ 13 февраля 2012

Дай мне попробовать. 1) Попробуйте KGDB

2) Вы имеете в виду зависший процесс? http://www.ibm.com/developerworks/aix/library/au-unix-strace.html

3) Попробуйте пакет lsof.

...