Процесс, который блокируется, игнорирует SIGKILL, работает (не в зомби и не в непрерывном сне). В каком это состоянии?

17

У меня есть процесс, который несколько раз перестал отвечать и, кажется, полностью блокируется. Он не реагирует ни на одну из попыток выполнить strace или просмотр с помощью gdb (gdb просто висит на системном вызове wait4 ()). Процесс работает и не ожидает системного вызова (/ proc / X / syscall:) runningили непрерывного сна (/ proc / X / status :) State: R (running).

В каком состоянии находится этот процесс? Возможно, это ошибка ядра какого-то типа?

Процесс повторяется, и это уже происходило несколько раз. Кажется, единственная вещь, которая может убить процесс - это перезагрузка. ОС Cent 7.

Изменить: Ядро версии 3.10.0-123.13.2.el7.x86_64. Попытка обновления до 3.10.0-229.11.1.el7, чтобы увидеть, если это имеет какое-либо значение.

alienth
источник
Какую версию GDB он использует? Согласно stackoverflow.com/questions/8978777/… более новая версия может работать лучше.
Грег Брей,
В настоящее время похоже, что расследование связано с ядром, потому что оно зависает, но если вы не возражаете, не могли бы вы добавить немного информации, относящейся к Redis? Что делает процесс, в то время как он блокирует и тому подобное. Я получил немного информации от Ника Крейвера через Twitter, по-видимому, Redis загружает большой набор данных, когда это происходит, загружается ли набор данных, просто перезапуская процесс или каким-либо другим способом (например, через DEBUG RELOAD, или конвейеризуя большие объемы данных )? Благодарю.
@antirez Набор данных загружается копией rdb из другого экземпляра redis. Блокировки происходят после того, как redis запускается и читает в гигантском rdb. Примечательно, что это не всегда зависает во время этого, просто иногда.
alienth
1
Подобные проблемы возникали только при ошибках ввода-вывода. Не могли бы вы рассказать нам о dmesgвыходе?
Ho1
3
Что /proc/<pid>/stack/proc/<pid>/task/*/stack) содержится? У этого процесса есть несколько потоков?
Стефан Шазелас

Ответы:

2

wait4 - системный вызов, указывающий, что процесс ожидает завершения одного из его дочерних процессов. Это может указывать на некоторые проблемы с обработкой сигнала.

Немного жестоко, но вы можете попытаться убить иерархию из приложения: kill -15 -$YourRedisPID. - до PID означает «PID и его детей». Так как кажется, что он ждет завершения ребенка, он может разблокировать его.

Если это не работает, давайте проверим глубже: найдите свой статус обработки сигналов с помощью grep ^Sig /proc/$YourRedisPID/status

Вы увидите такие вещи, как:

SigQ:   8/62777
SigPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000080
SigCgt: 0000000180004023

Как определено в «fs / proc / array.c» источника ядра, «SigQ» - это количество ожидающих сигналов / предел ожидающих сигналов.

Если количество сигнала слишком велико, это может означать, что ваш «SIGKILL» вообще не обрабатывается. Я все еще проверяю файл «kernel / signal.c», чтобы понять управление сигналами этих специальных сигналов.

Для непосредственного понимания вывода, попробуйте этот однострочный: awk 'BEGIN{print "ibase=16;obase=2;"} /^Sig...:/{ print toupper($2)}' /proc/$YourRedisPID/status | BC_LINE_LENGTH=0 bc

Это выводит меня:

0
0
10000000
110000000000000000100000000100011

Давайте начнем с отправки нам этого вывода. Я буду обновлять пост по мере необходимости.

Адриен М.
источник
Процесс не находится в wait4 (), gdb зависает в wait4 () при попытке доступа к процессу. Сам процесс не находится ни в каком системном вызове. Кроме того, зависший процесс не имеет детей. К сожалению, мне пришлось перезагрузить коробку. Я соберу данные, которые вы запросили, как только проблема повторяется.
alienth
Вывод здесь: gist.githubusercontent.com/alienth/23685ad2ea46a7eade56/raw/… Еще раз, proc игнорирует SIGKILL. Это не в системном вызове. Proc также игнорирует SIGTERM.
alienth