Mein Serverprogramm hat ein SIGTERM empfangen und gestoppt (mit Exit-Code 0). Ich bin überrascht, da ich mir ziemlich sicher bin, dass es genügend Speicher dafür gab. Unter welchen Bedingungen sendet Linux (Busybox) ein SIGTERM an einen Prozess?
Kommentare
- Ich kann ' Denken Sie nicht an einen Fall, in dem der Kernel oder ein Standardwerkzeug SIGTERM an einen zufälligen Prozess senden würde. Was können Sie uns darüber sagen, was das Programm tut und wie es ' gestartet wurde? Wie haben Sie vom Exit-Status des Programms ' erfahren? Können Sie das Problem reproduzieren? Haben Sie Protokolle, die Sie überprüfen können?
- Es liest und schreibt in eine serielle Leitung und reagiert auf UDP- und TCP-Anforderungen. Ich habe die Ausführung in ein Bash-Skript eingeschlossen und kenne daher den Exit-Code.
- Die Posix-Dokumentation zeigt an, dass SIGTERM ausschließlich ein Ereignis auf Benutzerebene ist. Ist es möglich, dass jemand anderes Ihr Serverprogramm beenden konnte?
- Sie sind es! Der Rückkehrcode 0 bedeutet einen normalen Ausgang. Wenn es ein SIGTERM gäbe, würde
$?
auf 143 (128 + Signalnummer) gesetzt. - Außerdem ist ^ C SIGINT, nicht SIGTERM, und das würde Beenden Sie mit einem Code von 130.
Antwort
Ich werde dies als Antwort posten dass es eine Art Lösung gibt, wenn sich herausstellt, dass dies das Problem ist.
Ein Exit-Status von 0 bedeutet einen normalen Exit eines erfolgreichen Programms. Ein beendetes Programm kann eine beliebige Ganzzahl zwischen 0 und 255 als Beendigungsstatus auswählen. Herkömmlicherweise verwenden Programme kleine Werte. Die Werte 126 und höher werden von der Shell verwendet, um spezielle Bedingungen zu melden. Vermeiden Sie sie daher am besten.
Auf der C-API-Ebene melden Programme ein 16-Bit-Status¹ , der sowohl den Exit-Status des Programms als auch das Signal codiert, das es beendet hat, falls vorhanden.
In der Shell ein Der Exit-Status des Befehls div (gespeichert in $?
) verbindet den tatsächlichen Exit-Status des Programms mit dem Signalwert: Wenn ein Programm durch ein Signal beendet wird, $?
ist auf einen Wert größer als 128 eingestellt (bei den meisten Shells beträgt dieser Wert 128 plus Signalnummer; ATT ksh verwendet 256 + Signalnummer und yash 384 + Signalnummer, wodurch dies vermieden wird die Mehrdeutigkeit, aber die anderen Shells sind nicht gefolgt).
Insbesondere wenn $?
0 ist, wird Ihr Programm normal beendet.
Beachten Sie, dass dies den Fall eines Prozesses einschließt, der SIGTERM empfängt, aber einen Signalhandler dafür hat und schließlich normal beendet wird (möglicherweise als eine indirekte Folge des SIGTERM-Signals, möglicherweise nicht).
Um die Frage in Ihrem Titel zu beantworten, wird SIGTERM vom System niemals automatisch gesendet. Es gibt einige Signale, die automatisch gesendet werden, wie SIGHUP, wenn ein Terminal ausfällt, SIGSEGV / SIGBUS / SIGILL, wenn ein Prozess Dinge tut, die er nicht tun sollte, SIGPIPE, wenn er in ein defektes Rohr / einen defekten Sockel schreibt usw. Und es gibt Einige Signale, die aufgrund eines Tastendrucks in einem Terminal gesendet werden, hauptsächlich SIGINT für Ctrl + C , SIGQUIT für Ctrl + \ und SIGTSTP für Strg + Z , aber SIGTERM gehört nicht dazu. Wenn ein Prozess SIGTERM empfängt, hat ein anderer Prozess dieses Signal gesendet.
¹ grob gesagt
Kommentare
- Schöne Erklärung, wie der Ausgangsstatus beim Empfang eines Signals bestimmt wird. Diese Antwort <
adressiert jedoch nicht die Frage von OP '.
exit
übergeben wird. Der Ansatz yash
ist ein guter Kompromiss, aber siehe rc für einen anderen. Siehe auch Standard-Exit-Code, wenn der Prozess beendet wird? Antwort
SIGTERM ist das Signal, das normalerweise zum administrativen Beenden eines Prozesses verwendet wird.
Dies ist kein Signal, das der Kernel senden würde, sondern das Signal, das ein Prozess normalerweise senden würde Senden, um einen anderen Prozess (ordnungsgemäß) zu beenden.
Dies ist das Signal, das standardmäßig von kill
, pkill
, killall
… Befehle.
Dies ist das Signal, das an Dämonen gesendet wird, um sie zu stoppen (wie bei einem service some-service stop
) oder gesendet von init
vor dem Herunterfahren (gefolgt von SIGKILL für Prozesse, die bei SIGTERM nicht rechtzeitig beendet werden konnten).
Beachten Sie, dass SIGTERM nicht das Signal ist, das bei ^C
. Das auf ^C
gesendete Signal ist SIGINT.