Perché non posso uccidere un processo SIGSTOP con un SIGTERM e dove è memorizzato il segnale in sospeso?


24

Sto usando Debian stretch (systemd). Stavo eseguendo il demone rsyslog in primo piano usando /usr/sbin/rsyslogd -n e ho fatto un Ctrl+ Zper fermarlo. Lo stato del processo è cambiato in Tl(interrotto, threaded). Ho emesso diversi comandi per il processo, e lo stato del processo era lo stesso: . Una volta che l'ho fatto , è morto. Ho 3 domande.kill -15 <pid>Tlfg

  • Perché il SIGSTOPprocesso -ed non rispondeva SIGTERM? Perché il kernel lo mantiene nello stesso stato?
  • Perché è stato ucciso nel momento in cui ha ricevuto il SIGCONTsegnale?
  • Se era a causa del SIGTERMsegnale precedente , dove veniva conservato fino al riavvio del processo?

Risposte:


41

SIGSTOPe SIGKILLsono due segnali che non possono essere catturati e gestiti da un processo. SIGTSTPè come SIGSTOPtranne che può essere catturato e gestito.

I segnali SIGSTOPe SIGTSTPfermano un processo nelle sue tracce, pronto per SIGCONT. Quando si invia quel processo a SIGTERM, il processo non è in esecuzione e quindi non può eseguire il codice per uscire.

(Ci sono anche SIGTTINe SIGTTOU, che sono segnali generati dal livello TTY quando un lavoro in background tenta di leggere o scrivere sul terminale. Possono essere catturati ma altrimenti fermeranno (sospenderanno) il processo, proprio come SIGTSTP. Ma ora sto andando ignorare quei due per il resto di questa risposta.)

Il tuo CtrlZinvia il processo a SIGTSTP, che sembra non essere gestito in alcun modo in modo particolare da rsyslogd, quindi semplicemente sospende il processo in sospeso SIGCONTo SIGKILL.

La soluzione qui è anche quella di inviare il SIGCONTtuo in SIGTERMmodo che il processo possa ricevere e gestire il segnale.

Esempio:

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

La documentazione per la GNU C Library lo spiega abbastanza bene, penso (il mio momento saliente):

Mentre un processo viene interrotto, non è possibile inviare più segnali fino a quando non viene continuato , tranne SIGKILLsegnali e (ovviamente) SIGCONTsegnali. I segnali sono contrassegnati come in sospeso, ma non trasmessi fino al proseguimento del processo. Il SIGKILLsegnale provoca sempre l'interruzione del processo e non può essere bloccato, gestito o ignorato. È possibile ignorare SIGCONT, ma provoca sempre comunque il proseguimento del processo se viene interrotto. L'invio di un SIGCONTsegnale a un processo comporta l'eliminazione di tutti i segnali di arresto in sospeso per tale processo. Allo stesso modo, tutti i SIGCONTsegnali in sospeso per un processo vengono eliminati quando riceve un segnale di arresto


1
@nohup. risposta estesa, ma essenzialmente "sì; ha gestito il messaggio che kill -15hai già inviato".
roaima,

2
@nohup sì, come da documentazione: « Mentre un processo viene arrestato, non è possibile inviargli più segnali fino a quando non viene continuato ... I segnali vengono contrassegnati come in sospeso, ma non consegnati fino a quando il processo non viene continuato. »
roaima,

1
Vedi anche SIGTTIN e SIGTTOU che fermano anche i processi
Stéphane Chazelas,

1
@ StéphaneChazelas buon punto. Ho aggiunto menzione di questi, ma altrimenti li ho ignorati. Sentiti libero di modificare come ritieni opportuno.
roaima,

2
@coteyr. Non sono d'accordo: SIGKILLimpedisce a un'app di ripulire, quindi l'utilizzo SIGTERMè preferibile nella maggior parte dei casi.
roaima,

9

SIGTERMè proprio come qualsiasi altro segnale in quanto può essere catturato da un processo. La ricezione del segnale farà semplicemente saltare il processo a una speciale routine di gestione del segnale. Per SIGTERMl'azione predefinita sarà terminare il processo, ma ad esempio un editor potrebbe voler catturare il segnale in modo che possa salvare una bozza di copia di tutti i file aperti prima di morire. Se il processo viene interrotto, non è possibile eseguire il gestore del segnale, ma il segnale rimarrà in sospeso fino a quando il processo continua. Si noti che il numero di segnali inviati di solito non verrà salvato.

In teoria, il sistema potrebbe sapere se per il processo è installato un gestore di segnale SIGTERMe, in caso contrario, terminarlo immediatamente. Ma (secondo il commento di Gilles) POSIX richiede che il segnale si interrompa fino a quando il processo non viene continuato SIGCONT.


4
Mi scuso, il mio commento precedente era sbagliato. Mentre un processo viene interrotto, nessun segnale viene inviato ad esso tranne SIGKILL e SIGCONT. Anche se il segnale ha la sua azione predefinita che consiste nell'uccidere il processo, questo viene ritardato fino a quando il processo non viene ripreso da un SIGCONT. POSIX impone questo comportamento.
Gilles 'SO- smetti di essere malvagio' il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.