Quando il sistema invia un SIGTERM a un processo?


24

Il mio programma server ha ricevuto un SIGTERM e si è arrestato (con il codice di uscita 0). Sono sorpreso da questo, poiché sono abbastanza sicuro che ci fosse un sacco di memoria per questo. In quali condizioni linux (busybox) invia un SIGTERM a un processo?


Non riesco a pensare ad alcun caso in cui il kernel o uno strumento standard invierebbero SIGTERM a un processo casuale. Cosa puoi dirci su cosa sta facendo il programma e su come è iniziato? Come sei venuto a conoscenza dello stato di uscita del programma? Puoi riprodurre il problema? Hai registri che puoi controllare?
Gilles 'SO-smetti di essere malvagio' il

Sta leggendo e scrivendo su una linea seriale e sta rispondendo alle richieste UDP e TCP. Ho eseguito l'esecuzione su uno script bash e quindi conosco il codice di uscita.
Michelemarcon,

1
La documentazione di Posix indica che SIGTERM è strettamente un evento a livello di utente. È possibile che qualcun altro sia stato in grado di uccidere il tuo programma server?
shellter

3
Sei! Il codice di ritorno 0 indica un'uscita normale. Se fosse presente un SIGTERM, $?sarebbe impostato su 143 (128 + numero del segnale).
Gilles 'SO-smetti di essere malvagio' il

1
Inoltre, ^ C è SIGINT, non SIGTERM, e questo
uscirebbe

Risposte:


13

Pubblicherò questo come una risposta in modo che ci sia una sorta di risoluzione se questo si rivela essere il problema.

Uno stato di uscita pari a 0 indica un'uscita normale da un programma riuscito. Un programma in uscita può scegliere qualsiasi numero intero compreso tra 0 e 255 come stato di uscita. Convenzionalmente, i programmi usano piccoli valori. I valori 126 e superiori sono usati dalla shell per segnalare condizioni speciali, quindi è meglio evitarli.

A livello di API C, i programmi riportano uno stato a 16 bit¹ che codifica sia lo stato di uscita del programma sia il segnale che lo ha ucciso, se presente.

Nella shell, lo stato di uscita di un comando (salvato in $?) unisce lo stato di uscita effettivo del programma e il valore del segnale: se un programma viene ucciso da un segnale, $?viene impostato su un valore maggiore di 128 (con la maggior parte delle shell, questo valore è 128 più il numero del segnale; ATT ksh usa 256 + numero del segnale e yash usa 384 + numero del segnale, il che evita l'ambiguità, ma gli altri gusci non hanno seguito l'esempio).

In particolare, se $?è 0, il tuo programma è uscito normalmente.

Si noti che questo include il caso di un processo che riceve SIGTERM, ma ha un gestore di segnali per esso e alla fine esce normalmente (forse come conseguenza indiretta del segnale SIGTERM, forse no).


Per rispondere alla domanda nel titolo, SIGTERM non viene mai inviato automaticamente dal sistema. Ci sono alcuni segnali che vengono inviati automaticamente come SIGHUP quando un terminale si spegne, SIGSEGV / SIGBUS / SIGILL quando un processo fa cose che non dovrebbe fare, SIGPIPE quando scrive su un tubo / socket rotto, ecc. E ci sono alcuni segnali inviati a causa della pressione di un tasto in un terminale, principalmente SIGINT per Ctrl+ C, SIGQUIT per Ctrl+ \e SIGTSTP per Ctrl+ Z, ma SIGTERM non è uno di quelli. Se un processo riceve SIGTERM, qualche altro processo ha inviato quel segnale.

¹ parlando approssimativamente


Bella spiegazione di come viene determinato lo stato di uscita alla ricezione di un segnale. Tuttavia, questa risposta non risponde alla domanda di OP.
codeforester,

1
@codeforester Ho risposto alla domanda nel corpo, non alla domanda nel titolo. Bene, una delle domande nel corpo - dato che si basava su un malinteso, è un po 'confusa. Aggiungerò alcune parole sul resto.
Gilles 'SO- smetti di essere malvagio'

Dipende dalla shell. In ksh93, è 256 + signum, in yash, è 384 + signum
Stéphane Chazelas,

Si noti che l'utilizzo di un valore superiore a 256 a la ksh non è necessariamente migliore in quanto impedisce che venga passato a exit. L' yashapproccio è un buon compromesso, ma vedi rc per un altro. Vedi anche Codice di uscita predefinito al termine del processo?
Stéphane Chazelas,

10

SIGTERM è il segnale che viene generalmente utilizzato per terminare amministrativamente un processo.

Questo non è un segnale che il kernel invierebbe, ma questo è il segnale che un processo in genere invierebbe per terminare (con garbo) un altro processo.

Questo è il segnale che viene inviato per default dai kill, pkill, killall, fuser -k... i comandi.

Questo è il segnale che viene inviato ai demoni per fermarli (come su a service some-service stop) o inviato initprima dell'arresto (seguito da SIGKILL per quei processi che non sono riusciti a terminare in tempo su SIGTERM).

Si noti che SIGTERM non è il segnale inviato ^C. Il segnale inviato ^Cè SIGINT.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.