Wanneer stuurt het systeem een SIGTERM naar een proces?

Mijn serverprogramma ontving een SIGTERM en stopte (met exitcode 0). Ik ben hierdoor verrast, want ik ben er vrij zeker van dat er genoeg geheugen voor was. Onder welke omstandigheden stuurt linux (busybox) een SIGTERM naar een proces?

Reacties

  • Ik kan ' denk niet aan elk geval waarin de kernel of een standaardtool SIGTERM naar een willekeurig proces zou sturen. Wat kunt u ons vertellen over wat het programma doet en hoe het ' is gestart? Hoe kwam u op de hoogte van de afsluitstatus van het programma '? Kunt u het probleem reproduceren? Heeft u logboeken die u kunt controleren?
  • Het leest en schrijft naar een seriële lijn, en reageert op UDP- en TCP-verzoeken. Ik heb de uitvoering ingepakt in een bash-script en daarom ken ik de exitcode.
  • Posix-documentatie geeft aan dat SIGTERM strikt een gebeurtenis op gebruikersniveau is. Is het mogelijk dat iemand anders uw serverprogramma heeft kunnen uitschakelen?
  • Dat bent u! De retourcode 0 betekent een normale uitgang. Als er een SIGTERM was, zou $? worden ingesteld op 143 (128 + signaalnummer).
  • Bovendien is ^ C SIGINT, niet SIGTERM, en dat zou sluit af met de code 130.

Answer

Ik zal dit als antwoord posten dat er een soort oplossing is als dit het probleem blijkt te zijn.

Een afsluitstatus van 0 betekent een normale afsluiting van een succesvol programma. Een afsluitend programma kan elk geheel getal tussen 0 en 255 kiezen als de exit-status. Conventioneel gebruiken programmas kleine waarden. Waarden 126 en hoger worden door de shell gebruikt om speciale omstandigheden te rapporteren, dus het is het beste om ze te vermijden.

Op het C API-niveau rapporteren programmas een 16-bits status¹ die zowel de exitstatus van het programma codeert als het signaal dat het heeft gedood, indien aanwezig.

In de shell een commando “s exit-status (opgeslagen in $?) combineert de werkelijke exit-status van het programma en de signaalwaarde: als een programma wordt gedood door een signaal, $? is ingesteld op een waarde groter dan 128 (bij de meeste shells is deze waarde 128 plus het signaalnummer; ATT ksh gebruikt 256 + signaalnummer en yash gebruikt 384 + signaalnummer, waardoor de ambiguïteit, maar de andere shells hebben dit “niet gevolgd).

In het bijzonder, als $? 0 is, wordt uw programma normaal afgesloten.

Merk op dat dit het geval is van een proces dat SIGTERM ontvangt, maar er een signaalhandler voor heeft, en uiteindelijk normaal verlaat (misschien als een indirect gevolg van het SIGTERM-signaal, misschien niet).


Om de vraag in uw titel te beantwoorden: SIGTERM wordt nooit automatisch door het systeem verzonden. Er zijn een paar signalen die automatisch worden verzonden, zoals SIGHUP wanneer een terminal weggaat, SIGSEGV / SIGBUS / SIGILL wanneer een proces dingen doet die het niet zou moeten doen, SIGPIPE wanneer het naar een kapotte buis / socket schrijft, enz. een paar signalen die worden verzonden als gevolg van een toetsaanslag in een terminal, voornamelijk SIGINT voor Ctrl + C , SIGQUIT voor Ctrl + \ en SIGTSTP voor Ctrl + Z , maar SIGTERM is er niet één van. Als een proces SIGTERM ontvangt, stuurt een ander proces dat signaal.

¹ grofweg

Reacties

  • Leuke uitleg over hoe de exit-status wordt bepaald bij ontvangst van een signaal. Dit antwoord heeft echter geen ' adres OP ' s vraag.
  • @codeforester Ik heb de vraag in de body, niet de vraag in de titel. Nou, een van de vragen in de body – aangezien het gebaseerd was op een misverstand, is het een beetje rommelig. I ' Ik zal een paar woorden toevoegen over de rest.
  • Dat hangt af van de shell. In ksh93 is het ' s 256 + signum, in yash is het ' s 384 + signum
  • Merk op dat het gebruik van een waarde hoger dan 256 a la ksh is niet noodzakelijkerwijs beter, want dat voorkomt dat deze wordt doorgegeven aan exit. De yash -aanpak is een goed compromis, maar zie rc voor een andere. Zie ook Standaard afsluitcode wanneer proces wordt beëindigd?

Antwoord

SIGTERM is het signaal dat doorgaans wordt gebruikt om een proces administratief te beëindigen.

Dat is geen signaal dat de kernel zou verzenden, maar dat is het signaal dat een proces normaal gesproken verzenden om (netjes) een ander proces te beëindigen.

Dat is het signaal dat standaard wordt verzonden door de kill, pkill, killall … opdrachten.

Dat is het signaal dat naar daemons wordt gestuurd om ze te stoppen (zoals bij een service some-service stop), of verzonden door init voor afsluiten (gevolgd door SIGKILL voor die processen die er niet in geslaagd zijn om op tijd te eindigen na SIGTERM).

Merk op dat SIGTERM niet het signaal is dat wordt verzonden naar ^C. Het signaal dat wordt verzonden op ^C is SIGINT.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *