Când sistemul trimite un SIGTERM unui proces?

Programul serverului meu a primit un SIGTERM și s-a oprit (cu codul de ieșire 0). Sunt surprins de acest lucru, deoarece sunt destul de sigur că a existat multă memorie pentru asta. În ce condiții linux (busybox) trimite un SIGTERM unui proces?

Comentarii

  • Pot ' nu vă gândiți la niciun caz când nucleul sau un instrument standard ar trimite SIGTERM la un proces aleatoriu. Ce ne puteți spune despre ceea ce face programul și cum a început '? Cum ați aflat despre starea de ieșire a programului '? Puteți reproduce problema? Aveți jurnale pe care le puteți verifica?
  • Citește și scrie pe o linie serială și răspunde la solicitările UDP și TCP. Am împachetat execuția pe un script bash și, prin urmare, cunosc codul de ieșire.
  • Documentația Posix indică faptul că SIGTERM este strict un eveniment la nivel de utilizator. Este posibil ca altcineva să fi putut ucide programul dvs. de server?
  • Sunteți! Codul de returnare 0 înseamnă o ieșire normală. Dacă ar exista un SIGTERM, $? ar fi setat la 143 (128 + număr de semnal).
  • De asemenea, ^ C este SIGINT, nu SIGTERM și asta ar fi ieșiți cu un cod de 130.

Răspuns

Voi posta acest lucru ca răspuns că există un fel de rezoluție dacă acest lucru se dovedește a fi problema.

O stare de ieșire de 0 înseamnă o ieșire normală dintr-un program de succes. Un program de ieșire poate alege orice număr între 0 și 255 ca stare de ieșire. În mod convențional, programele folosesc valori mici. Valorile 126 și peste sunt utilizate de către shell pentru a raporta condiții speciale, deci este cel mai bine să le evitați.

La nivelul API C, rapoartele de programe o stare de 16 biți¹ care codifică atât starea de ieșire a programului, cât și semnalul care l-a ucis, dacă există.

În shell, un starea de ieșire a comenzii (salvată în $?) combină starea efectivă de ieșire a programului și valoarea semnalului: dacă un program este ucis de un semnal, $? este setat la o valoare mai mare de 128 (cu majoritatea shell-urilor, această valoare este 128 plus numărul de semnal; ATT ksh folosește 256 + numărul de semnal și yash folosește 384 + numărul de semnal, ceea ce evită ambiguitatea, dar celelalte cochilii nu au urmat exemplul).

În special, dacă $? este 0, programul dvs. a ieșit normal.

Rețineți că aceasta include cazul unui proces care primește SIGTERM, dar are un handler de semnal pentru acesta și, în cele din urmă, iese normal (poate ca o consecință indirectă a semnalului SIGTERM, poate nu).


Pentru a răspunde la întrebarea din titlul dvs., SIGTERM nu este trimis niciodată automat de sistem. Există câteva semnale care sunt trimise automat, cum ar fi SIGHUP când un terminal dispare, SIGSEGV / SIGBUS / SIGILL când un proces face lucruri pe care nu ar trebui să le facă, SIGPIPE când scrie într-o țeavă / priză ruptă etc. Și există câteva semnale care sunt trimise datorită apăsării unei taste într-un terminal, în principal SIGINT pentru Ctrl + C , SIGQUIT pentru Ctrl + \ și SIGTSTP pentru Ctrl + Z , dar SIGTERM nu este unul dintre acestea. Dacă un proces primește SIGTERM, un alt proces a trimis acel semnal.

¹ aproximativ vorbind

Comentarii

  • Explicație frumoasă a modului în care se determină starea de ieșire la primirea unui semnal. Cu toate acestea, acest răspuns nu ' se adresează întrebării OP '.
  • @codeforester Am răspuns la întrebare în corp, nu întrebarea din titlu. Ei bine, una dintre întrebările din corp – având în vedere că s-a bazat pe o neînțelegere, este cam dezordonată. I ' Voi adăuga câteva cuvinte despre restul.
  • Asta depinde de coajă. În ksh93, ' s 256 + signum, în yash, este ' s 384 + signum
  • Rețineți că utilizarea unei valori peste 256 a la ksh nu este neapărat mai bună, deoarece aceasta împiedică trecerea la exit. Abordarea yash este un compromis bun, dar vedeți rc pentru altul. A se vedea, de asemenea, Cod de ieșire implicit când procesul este încheiat?

Răspuns

SIGTERM este semnalul care este de obicei utilizat pentru a termina administrativ un proces.

Acesta nu este un semnal pe care nucleul l-ar trimite, ci acela este semnalul pe care un proces l-ar trimite trimiteți pentru a termina (grațios) un alt proces.

Acesta este semnalul trimis în mod implicit de kill, pkill, killall … comenzi.

Acesta este semnalul care este trimis demonilor pentru a-i opri (ca pe un service some-service stop) sau trimis de init înainte de închidere (urmat de SIGKILL pentru acele procese care nu au reușit să se încheie la timp după SIGTERM).

Rețineți că SIGTERM este nu semnalul trimis ^C. Semnalul trimis către ^C este SIGINT.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *