Wann sendet das System ein SIGTERM an einen Prozess?

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 '
  • 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 (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 '.

  • @codeforester Ich habe die Frage in der Körper, nicht die Frage im Titel. Nun, eine der Fragen im Körper – da sie auf einem Missverständnis beruhte, ist es ein bisschen chaotisch. I ' füge ein paar Worte zum Rest hinzu.
  • Das hängt von der Shell ab. In ksh93 ist ' 256 + signum, in yash ' 384 + signum
  • Beachten Sie dies Die Verwendung eines Werts über 256 a la ksh ist nicht unbedingt besser, da dadurch verhindert wird, dass er an 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.

    Schreibe einen Kommentar

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.