När skickar systemet ett SIGTERM till en process?

Mitt serverprogram fick ett SIGTERM och stoppade (med utgångskod 0). Jag är förvånad över detta, eftersom jag är ganska säker på att det fanns gott om minne för det. Under vilka förhållanden skickar Linux (upptagen låda) ett SIGTERM till en process?

Kommentarer

  • Jag kan ' t tänk på något fall när kärnan eller ett standardverktyg skulle skicka SIGTERM till en slumpmässig process. Vad kan du berätta om vad programmet gör och hur det ' startade? Hur fick du reda på programmets ' utgångsstatus? Kan du återge problemet? Har du loggar som du kan kontrollera?
  • Den läser och skriver till en seriell rad och svarar på UDP- och TCP-förfrågningar. Jag har lindat körningen i ett bash-skript och därför vet jag utgångskoden.
  • Posix-dokumentation indikerar att SIGTERM är strikt en användarnivåhändelse. Är det möjligt att någon annan kunde döda ditt serverprogram?
  • Du är! Returkoden 0 betyder en normal utgång. Om det fanns en SIGTERM skulle $? ställas in på 143 (128 + signalnummer).
  • Dessutom är ^ C SIGINT, inte SIGTERM, och det skulle avsluta med koden 130.

Svar

Jag lägger upp detta som ett svar så att det finns någon form av upplösning om detta visar sig vara problemet.

En utgångsstatus på 0 betyder en normal utgång från ett framgångsrikt program. Ett avslutande program kan välja vilket heltal som helst mellan 0 och 255 som utgångsstatus. Konventionellt använder program små värden. Värden 126 och högre används av skalet för att rapportera speciella förhållanden, så det är bäst att undvika dem.

På C API-nivå rapporterar programmen en 16-bitars status¹ som kodar både programmets utgångsstatus och signalen som dödade den, om någon.

I skalet, en kommando ”s utgångsstatus (sparad i $?) sammanfogar programmets faktiska utgångsstatus och signalvärdet: om ett program dödas av en signal, $? är inställt på ett värde större än 128 (för de flesta skalen är detta värde 128 plus signalnumret; ATT ksh använder 256 + signalnummer och yash använder 384 + signalnummer, vilket undviker tvetydigheten, men de andra skalen har inte följt).

I synnerhet, om $? är 0, avslutades ditt program normalt.

Observera att detta inkluderar fallet med en process som tar emot SIGTERM men har en signalhanterare för den och slutligen slutar normalt (kanske som en indirekt konsekvens av SIGTERM-signalen, kanske inte).


För att svara på frågan i din titel skickas SIGTERM aldrig automatiskt av systemet. Det finns några signaler som skickas automatiskt som SIGHUP när en terminal går bort, SIGSEGV / SIGBUS / SIGILL när en process gör saker den inte borde göra, SIGPIPE när den skriver till ett trasigt rör / uttag, etc. Och det finns några signaler som skickas på grund av en tangenttryckning i en terminal, främst SIGINT för Ctrl + C , SIGQUIT för Ctrl + \ och SIGTSTP för Ctrl + Z , men SIGTERM är inte en av dessa. Om en process tar emot SIGTERM skickade någon annan process den signalen.

¹ grovt sagt

Kommentarer

  • Trevlig förklaring av hur utgångsstatus bestäms vid mottagning av en signal. Men detta svar ' t adress OP ' s fråga.
  • @codeforester Jag svarade på frågan i kropp, inte frågan i titeln. Tja, en av frågorna i kroppen – med tanke på att den var baserad på ett missförstånd är det lite rörigt. Jag ' Lägg till några ord om resten.
  • Det beror på skalet. I ksh93 är det ' s 256 + signum, i yash, det ' s 384 + signum
  • Observera att att använda ett värde över 256 a la ksh är inte nödvändigtvis bättre eftersom det förhindrar att det skickas till exit. yash -metoden är en bra kompromiss, men se rc för en annan. Se även Standardutgångskod när processen avslutas?

Svar

SIGTERM är signalen som vanligtvis används för att administrativt avsluta en process.

Det är inte en signal som kärnan skulle skicka, men det är signalen som en process vanligtvis skulle skicka för att avsluta (graciöst) en annan process.

Det är signalen som sänds som standard av kill, pkill, killall … kommandon.

Det är signalen som skickas till demoner för att stoppa dem (som på en service some-service stop), eller skickas av init före avstängning (följt av SIGKILL för de processer som inte har lyckats avslutas i tid vid SIGTERM).

Observera att SIGTERM är inte signalen som skickas vid ^C. Signalen som skickas till ^C är SIGINT.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *