Как отладить утверждение 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
- Здесь вы можете скачать простой системный скрипт, который находит спорные блокировки пользовательского пространства:
https://sourceware.org/systemtap/examples/process/futexes.stp
Поэтому, если в вашей системе установлена системная запись, просто запустите этот системный скрипт: stap futexes.stp
Захватите вывод данных, как вы делали раньше.
Если вы завершите выполнение сценария системного касания простым нажатием клавиши Ctrl-C, вы получите вывод утвержденных фьютексов.
Наконец, в выходных данных 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();
В этом случае это ошибка опечатки, но реальное состояние гонки также вызовет ту же проблему.