Как отладить утверждение futex, показанное в strace?

Я отлаживаю проблему в многопоточном процессе linux, где определенный поток не выполняется в течение нескольких секунд. Глядя на вывод strace, выяснилось, что он ждет futex, например
1673109 14: 36: 28.600329 futex (0x44b8d20, FUTEX_WAIT_PRIVATE,
1673109 14: 36: 33.221850 <... futex возобновлен>) = 0 <4.621514>

Как я могу узнать, на что ссылается этот futex(0x44b8d20) в пространстве пользователя, то есть, как отобразить это на блокирующую конструкцию, которая использует futex внутри.

1 ответ

Я бы использовал простой сценарий systemtap, чтобы помочь вам быстро найти адреса предполагаемых блокировок фьютекса. Когда я говорю адрес, я имею в виду первый аргумент системного вызова futex:

http://man7.org/linux/man-pages/man2/futex.2.html

  1. Здесь вы можете скачать простой системный скрипт, который находит спорные блокировки пользовательского пространства:

https://sourceware.org/systemtap/examples/process/futexes.stp

Поэтому, если в вашей системе установлена ​​системная запись, просто запустите этот системный скрипт: stap futexes.stp

  1. Захватите вывод данных, как вы делали раньше.

  2. Если вы завершите выполнение сценария системного касания простым нажатием клавиши Ctrl-C, вы получите вывод утвержденных фьютексов.

  3. Наконец, в выходных данных strace ищите вызовы futex, в которых вторым аргументом (типом операции) является FUTEX_WAIT. Например:

futex (0x7f58a31999d0, FUTEX_WAIT, 4508, NULL) = 0

Затем вы можете найти первый аргумент в выводе скрипта системного крана. Как я сделал быструю проверку этого, здесь вы найдете соответствующий вывод системного крана:

ome [4489] блокировка 0x7f58a31999d0 оспаривалась 1 раз, 7807 с нами

Если вы посмотрите на этот системный скрипт, он приятно напечатает имя процесса и идентификатор процесса / потока, что позволит легко найти то, что вы ищете. Однако следует заметить, что выполнение сценария systemtap фактически перехватит системный вызов всей системы.

Здесь я хочу поделиться своим опытом с другими, потому что действительно сложно отлаживать многопоточные приложения. Следующим был мой результат.

strace: Process 91073 attached
futex(0x7feb282109d0, FUTEX_WAIT, 91074, NULL

Так как я до сих пор помню, что делал: при комментировании отладочного вывода забывал одну строку. Это заставляет мою программу перестать работать в середине. Процесс по-прежнему потребляет немного ресурсов процессора, но остается в состоянии S.

unique_lock<mutex> ulk(mut);  // Forgot to comment out before the release
// cerr << "I am almost done with the job in this thread\n";
// ulk.unlock();

В этом случае это ошибка опечатки, но реальное состояние гонки также вызовет ту же проблему.

Другие вопросы по тегам