Processo que trava, ignora SIGKILL, é executável (não é um zumbi ou fica ininterrupto). Em que estado está?

17

Eu tenho um processo que várias vezes agora parou de responder e parece estar completamente bloqueado. Ele não responde a nenhuma tentativa de rastrear ou espiar com o gdb (o gdb fica travado em um syscall wait4 ()). O processo é executável e não está aguardando um syscall (/ proc / X / syscall:) runningou em suspensão ininterrupta (/ proc / X / status State: R (running):).

Em que estado esse processo está exatamente? Isso é possivelmente um bug do kernel de algum tipo?

O processo é redis, e isso já aconteceu algumas vezes agora. Parece que a única coisa que pode matar o processo é uma reinicialização. O SO é o Cent 7.

Editar: a versão do kernel é 3.10.0-123.13.2.el7.x86_64. Tentando atualizar para 3.10.0-229.11.1.el7 para ver se isso faz alguma diferença.

alienth
fonte
Qual versão do GDB ele está usando? De acordo com stackoverflow.com/questions/8978777/…, uma versão mais recente pode funcionar melhor.
Greg Bray
Atualmente, parece que a investigação é mais do lado do kernel por causa da maneira especial em que ele trava, mas se você não se importa, você poderia adicionar algumas informações específicas do Redis? O que o processo está fazendo enquanto bloqueia e coisas assim. Recebi algumas informações de Nick Craver via Twitter, aparentemente o Redis está carregando um grande conjunto de dados quando isso acontece, é o conjunto de dados carregado apenas reiniciando o processo ou de alguma outra maneira (por exemplo, através do DEBUG RELOAD, ou canalizando grandes quantidades de dados )? Obrigado.
@antirez O conjunto de dados está sendo carregado por uma cópia rdb de outra instância do redis. Os bloqueios ocorrem depois que o redis inicia e lê no rdb gigante. Notavelmente, nem sempre trava durante isso, às vezes.
alienth
1
Eu só tive esse tipo de problema ao ter erros de IO. Você poderia nos falar sobre a dmesgsaída?
• Ho1
3
O que contém /proc/<pid>/stack(e /proc/<pid>/task/*/stack)? Esse processo tem vários threads?
Stéphane Chazelas

Respostas:

2

wait4 é um syscall indicando que o processo está aguardando a rescisão de um de seus filhos. Isso pode indicar algum problema com o tratamento do sinal.

Um pouco brutal, mas você pode tentar matar a hierarquia do app: kill -15 -$YourRedisPID. O - antes do PID significa "o PID e seus filhos". Como parece estar aguardando o término de um filho, ele pode desbloqueá-lo.

Se não estiver funcionando, vamos verificar mais a fundo: encontre o status do processo de sinal com grep ^Sig /proc/$YourRedisPID/status

Você verá coisas como:

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

Conforme definido em "fs / proc / array.c" da fonte do kernel, o "SigQ" é o número de sinais pendentes / o limite de sinais pendentes.

Se o número do sinal for muito alto, isso pode indicar que o seu "SIGKILL" não está sendo tratado. Ainda estou checando o arquivo "kernel / signal.c" para entender o gerenciamento de sinais desses sinais especiais.

Para uma compreensão direta da saída, tente este one-liner: awk 'BEGIN{print "ibase=16;obase=2;"} /^Sig...:/{ print toupper($2)}' /proc/$YourRedisPID/status | BC_LINE_LENGTH=0 bc

Isso me mostra:

0
0
10000000
110000000000000000100000000100011

Vamos começar enviando essa saída. Atualizarei a postagem conforme necessário.

Adrien M.
fonte
O processo não está em wait4 (), o gdb fica pendurado em um wait4 () ao tentar acessar o processo. O processo em si não está em nenhum syscall. Além disso, o processo pendurado não tem filhos. Infelizmente eu tive que reiniciar a caixa. Reunirei os dados solicitados assim que o problema ocorrer novamente.
alienth
Saída aqui: gist.githubusercontent.com/alienth/23685ad2ea46a7eade56/raw/… Mais uma vez, proc está ignorando SIGKILL. Não está em um syscall. Proc também ignora o SIGTERM.
alienth