Strace исправляет зависший процесс
У меня есть однопоточный процесс Unix, который общается по протоколу TCP с другими процессами.
Проблема в следующем. Когда я запускаю процесс, он зависает (без занятого цикла), пока я не убью его.
Самое смешное, что, как только я присоединяюсь к нему с помощью strace, он продолжает работать с ожидаемым поведением, как будто не было никаких проблем вообще. (всегда воспроизводимый)
Что может быть причиной такого поведения? Какое влияние оказывает влияние на состояние процесса?
Обновление: причина, по которой strace изменил поведение, была в том, что мы использовали openonload с ошибкой. Как только мы подключили strace, стек был перенесен обратно в ядро, и проблема исчезла.
3 ответа
Много лет спустя, так что, вероятно, с совершенно другой основной причиной, этот пост в блоге объясняет, почему подключение трассировщика может исправить зависшие системные вызовы: https://ayende.com/blog/198849-C/production-postmortem-the-heisenbug-server?Key=1eeda567-02a8-4bbb-b90f-557523973233.
Цитирование справочной страницы ptrace :
Некоторые системные вызовы возвращают значение EINTR, если сигнал был отправлен
tracee, но доставка была подавлена трассировщиком. (Это очень типичная операция: обычно ее делают отладчики при каждом подключении, чтобы не вводить фиктивный SIGSTOP). Начиная с Linux3.2.9, затронуты следующие системные вызовы (этот список, вероятно, неполный): epoll_wait(2) и read(2) из файлового дескриптора inotify(7). Обычный симптом этой ошибки заключается в том, что когда вы присоединяетесь к неактивному процессу с помощью команды
strace -p <process-ID>
то вместо обычного и ожидаемого однострочного вывода, такого как
restart_syscall(<... resuming interrupted call ...>_
или
select(6, [5], NULL, [5], NULL_
("_" обозначает позицию курсора), вы наблюдаете более одной строки. Например:
clock_gettime(CLOCK_MONOTONIC, {15370, 690928118}) = 0 epoll_wait(4,_
Что здесь не видно, так это то, что процесс был заблокирован в epoll_wait(2) до того, как к нему подключилась strace(1). Присоединение вызвало возврат epoll_wait(2) в пространство пользователя с ошибкой EINTR. В этом конкретном случае программа реагировала на EINTR, проверяя текущее время, а затем снова выполняя epoll_wait(2). (Программы, которые не ожидают таких «случайных» ошибок EINTR, могут вести себя непреднамеренно при подключении strace(1).)
Скорее всего, этот вывод просто замедляет процесс, делая гораздо менее вероятными взаимные блокировки. Я видел это раньше, когда strace ИЛИ может происходить при добавлении других отладочных вызовов печати или отладки.
Тупики чаще всего встречаются при многопоточном взаимодействии. Но в вашем случае у вас есть несколько процессов. Если strace освобождает процессы каждый раз, то я предполагаю, что именно то, что вы открываете сокеты или рукопожатие на сокете, является тем, что висит. Я думаю, что буферизация и блокировка сокета могут привести вас в состояние блокировки.
Аналогичный вопрос, но с многопоточным процессом, взаимоблокировкой между потоками, а не между отдельными процессами: использование strace исправляет проблему с зависшей памятью
Трудно обобщить примеры, особенно если вы не знаете, что делают ваши разные процессы или они каким-то образом делятся ресурсами? Я попробую.,,
Пример с одним объектом / ресурсом, который должен быть защищен:
Один процесс начинает вносить изменения в объект (например, добавлять элементы в таблицу list/ db)
Другой процесс начинает перебирать список / таблицу.
Опасность того, что один из этих процессов повторяется в цикле, никогда не выходя из ИЛИ не делая что-то хуже, например, запись в недействительную память.Пример, в котором объект / ресурс защищен мьютексами
Классический простой тупик с проблемой двух ресурсов. ~ проще столовых философов
Один поток / процесс захватывает мьютекс объекта A, выполняет некоторую работу.
Другой поток / процесс захватывает мьютекс объекта B, выполняет некоторую работу.
Тот же поток / процесс должен обновить объект A, ожидает мьютекс для A.
Исходный поток / процесс должен получить доступ к объекту B, ожидает мьютекс на B.
,,,,,,,,,,,, @ .,,,,,,,,,,
Тишина, за исключением шума ветра и дутья, дующего по ландшафту.
В тупике.
Если бы эта проблема была только однажды, и она была связана с обработкой сигналов, это один из источников состояния гонки в однопоточном коде.