Warum kann ich einen SIGSTOP-Prozess nicht mit einem SIGTERM beenden und wo wird das anstehende Signal gespeichert?

24

Ich benutze Debian Stretch (systemd). Ich habe den rsyslog-Daemon im Vordergrund mit ausgeführt /usr/sbin/rsyslogd -n und ein Ctrl+ ausgeführt Z, um ihn zu stoppen. Der Status des Prozesses wurde in Tl(gestoppt, Threaded) geändert . Ich ausgegeben mehrere Befehle an den Prozess, und der Zustand des Prozesses war die gleiche: . Sobald ich eine gemacht habe , ist sie gestorben. Ich habe 3 Fragen.kill -15 <pid>Tlfg

  • Warum SIGSTOPreagierte der -ed-Prozess nicht SIGTERM? Warum behält der Kernel den gleichen Zustand bei?
  • Warum wurde es getötet, sobald es das SIGCONTSignal erhielt?
  • Wenn es wegen des vorherigen SIGTERMSignals war, wo wurde es aufbewahrt, bis der Prozess wieder aufgenommen wurde?
Nohup
quelle

Antworten:

41

SIGSTOPund SIGKILLsind zwei Signale, die von einem Prozess nicht erfasst und verarbeitet werden können. SIGTSTPist wie die SIGSTOPAusnahme , dass es kann abgefangen und behandelt werden.

Die Signale SIGSTOPund SIGTSTPstoppen einen Prozess in seinen Spuren, bereit für SIGCONT. Wenn Sie diesen Prozess a senden, wird SIGTERMder Prozess nicht ausgeführt, und der Code zum Beenden kann nicht ausgeführt werden.

(Es gibt auch SIGTTINund SIGTTOU- Signale, die von der TTY-Ebene generiert werden, wenn ein Hintergrundjob versucht, Daten auf dem Terminal zu lesen oder zu schreiben. Sie können abgefangen werden, halten den Prozess aber ansonsten an (unterbrechen), genau wie SIGTSTP. Aber ich gehe jetzt um diese beiden für den Rest dieser Antwort zu ignorieren.)

Ihr CtrlZsendet den Prozess a SIGTSTP, der anscheinend in keiner Weise speziell von behandelt wird rsyslogd, so dass er einfach den Prozess pendent SIGCONToder aussetzt SIGKILL.

Die Lösung besteht hier auch darin, SIGCONTnach Ihrem zu senden, SIGTERMdamit der Prozess das Signal empfangen und verarbeiten kann.

Beispiel:

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

Die Dokumentation für die GNU C Library erklärt dies ziemlich gut, denke ich (meine Hervorhebung):

Während ein Prozess gestoppt ist, können keine Signale mehr an ihn gesendet werden, bis er fortgesetzt wird , mit Ausnahme von SIGKILLSignalen und (offensichtlich) SIGCONTSignalen. Die Signale werden als anstehend markiert, aber erst dann zugestellt, wenn der Vorgang fortgesetzt wird. Das SIGKILLSignal führt immer zum Abbruch des Prozesses und kann nicht blockiert, verarbeitet oder ignoriert werden. Sie können ignorieren SIGCONT, aber es führt immer dazu, dass der Prozess trotzdem fortgesetzt wird, wenn er gestoppt wird. Wenn Sie ein SIGCONTSignal an einen Prozess senden, werden alle anstehenden Stoppsignale für diesen Prozess verworfen. Ebenso werden alle anstehenden SIGCONTSignale für einen Prozess verworfen, wenn er ein Stoppsignal empfängt

Roaima
quelle
1
@nohup. Antwort erweitert, aber im Wesentlichen: "Ja, es hat die kill -15bereits gesendeten Daten verarbeitet".
Roaima
2
@nohup ja, laut Dokumentation: « Während ein Prozess gestoppt ist, können keine Signale mehr an ihn gesendet werden, bis er fortgesetzt wird ... Die Signale werden als anstehend markiert, aber nicht gesendet, bis der Prozess fortgesetzt wird. »
Roaima
1
Siehe auch SIGTTIN und SIGTTOU, die ebenfalls Prozesse stoppen
Stéphane Chazelas
1
@ StéphaneChazelas guter Punkt. Ich habe diese erwähnt, aber ansonsten ignoriert. Bitte zögern Sie nicht zu bearbeiten, wie Sie es für richtig halten.
Roaima
2
@coteyr. Ich stimme nicht zu: SIGKILLVerhindert, dass eine App bereinigt wird. Daher SIGTERMist die Verwendung in vielen (den meisten) Fällen vorzuziehen.
Roaima
9

SIGTERMist wie jedes andere Signal darin, dass es von einem Prozess abgefangen werden kann. Durch den Empfang des Signals springt der Prozess zu einer speziellen Signalbehandlungsroutine. Für SIGTERMdie Standard - Aktion den Prozess beenden wird, sondern zB könnte ein Editor wie das Signal zu fangen , so dass es einen Entwurf Kopie aller geöffneten Dateien , bevor sie sterben zu speichern. Wenn der Prozess gestoppt wird, kann der Signalhandler nicht ausgeführt werden, das Signal bleibt jedoch anstehend, bis der Prozess fortgesetzt wird. Beachten Sie, dass die Anzahl der gesendeten Signale normalerweise nicht gespeichert wird.

Theoretisch könnte das System wissen, ob für den Prozess ein Signal-Handler installiert ist SIGTERM, und ihn, falls nicht, sofort beenden. Nach Gilles 'Kommentar verlangt POSIX jedoch, dass das Signal anhält, bis der Prozess über fortgesetzt wird SIGCONT.

ilkkachu
quelle
4
Entschuldigung, mein vorheriger Kommentar war falsch. Während ein Prozess gestoppt ist, werden außer SIGKILL und SIGCONT keine Signale an ihn gesendet. Selbst wenn das Signal seine Standardaktion hat, die darin besteht, den Prozess abzubrechen, wird dies verzögert, bis der Prozess von einem SIGCONT fortgesetzt wird. POSIX schreibt dieses Verhalten vor.
Gilles 'SO- hör auf böse zu sein'