Por que não consigo interromper um processo SIGSTOP com um SIGTERM e onde o sinal pendente é armazenado?

24

Estou usando o Debian stretch (systemd). Eu estava executando o daemon rsyslog em primeiro plano usando /usr/sbin/rsyslogd -n e fiz um Ctrl+ Zpara pará-lo. O estado do processo foi alterado para Tl(parado, encadeado). I emitiu vários comandos para o processo, e o estado do processo foi o mesmo: . Depois que fiz um , ele morreu. Eu tenho 3 perguntas.kill -15 <pid>Tlfg

  • Por que o SIGSTOPprocesso ed não estava respondendo SIGTERM? Por que o kernel o mantém no mesmo estado?
  • Por que foi morto no momento em que recebeu o SIGCONTsinal?
  • Se foi por causa do SIGTERMsinal anterior , onde foi mantido até o processo reiniciar?
nohup
fonte

Respostas:

41

SIGSTOPe SIGKILLsão dois sinais que não podem ser capturados e manipulados por um processo. SIGTSTPé como, SIGSTOPexceto que ele pode ser capturado e manuseado.

Os sinais SIGSTOPe SIGTSTPparam um processo em suas trilhas, pronto para SIGCONT. Quando você envia esse processo a SIGTERM, o processo não está em execução e, portanto, não pode executar o código para sair.

(Também existem SIGTTINe SIGTTOU, que são sinais gerados pela camada TTY quando um trabalho em segundo plano tenta ler ou gravar no terminal. Eles podem ser capturados, mas, de outra forma, interromperão (suspenderão) o processo, assim como SIGTSTP. Mas agora vou para ignorar esses dois pelo restante desta resposta.)

Você CtrlZenvia o processo a SIGTSTP, que parece não ter sido tratado de maneira alguma por rsyslogdisso, simplesmente suspende o processo pendente SIGCONTou SIGKILL.

A solução aqui também é enviar SIGCONTapós o seu SIGTERMpara que o processo possa receber e manipular o sinal.

Exemplo:

sleep 999 &

# Assume we got PID 456 for this process
kill -TSTP 456    # Suspend the process (nicely)
kill -TERM 456    # Terminate the process (nicely). Nothing happens
kill -CONT 456    # Continue the process so it can exit cleanly

A documentação da GNU C Library explica isso muito bem, eu acho (meu destaque):

Enquanto um processo é interrompido, nenhum outro sinal pode ser enviado até que continue , exceto SIGKILLsinais e (obviamente) SIGCONTsinais. Os sinais são marcados como pendentes, mas não são entregues até que o processo continue. O SIGKILLsinal sempre causa o término do processo e não pode ser bloqueado, manipulado ou ignorado. Você pode ignorar SIGCONT, mas sempre faz com que o processo continue mesmo assim, se estiver parado. Enviar um SIGCONTsinal para um processo faz com que quaisquer sinais de parada pendentes para esse processo sejam descartados. Da mesma forma, quaisquer SIGCONTsinais pendentes para um processo são descartados quando ele recebe um sinal de parada

roaima
fonte
11
@nohup. resposta estendida, mas essencialmente, "sim; tratou do que kill -15você já havia enviado".
roaima 27/07
2
@nohup sim, de acordo com a documentação: « Enquanto um processo está parado, não há mais sinais a serem entregues até que continue ... Os sinais são marcados como pendentes, mas não são entregues até que o processo continue. »
roaima
11
Veja também SIGTTIN e SIGTTOU que também interrompem processos
Stéphane Chazelas
11
@ StéphaneChazelas bom ponto. Eu adicionei menção a eles, mas os ignorei. Sinta-se à vontade para editar como achar melhor.
roaima 27/07
2
@coteyr. Não concordo: SIGKILLimpede que um aplicativo seja limpo; portanto, o uso SIGTERMé preferível em muitos casos (na maioria).
roaima 28/07
9

SIGTERM é como qualquer outro sinal , pois pode ser capturado por um processo. Receber o sinal fará com que o processo salte para uma rotina especial de tratamento de sinais. A SIGTERMação padrão será encerrar o processo, mas, por exemplo, um editor pode querer capturar o sinal para salvar uma cópia de rascunho de qualquer arquivo aberto antes de morrer. Se o processo for parado, ele não poderá executar o manipulador de sinal, mas o sinal permanecerá pendente até o processo continuar. Observe que o número de sinais enviados geralmente não será salvo.

Em teoria, o sistema poderia saber se o processo possui um manipulador de sinais instalado SIGTERMe encerrá-lo imediatamente, se não. Mas (conforme comentário de Gilles), o POSIX exige que o sinal seja interrompido até que o processo continueSIGCONT .

ilkkachu
fonte
4
Desculpas, meu comentário anterior estava errado. Enquanto um processo está parado, nenhum sinal é entregue, exceto SIGKILL e SIGCONT. Mesmo que o sinal tenha sua ação padrão que é matar o processo, isso é adiado até que o processo seja reiniciado por um SIGCONT. O POSIX exige esse comportamento.
Gilles 'SO- stop be evil'