¿Cuándo envía el sistema una SIGTERM a un proceso?

24

Mi programa de servidor recibió un SIGTERM y se detuvo (con el código de salida 0). Estoy sorprendido por esto, ya que estoy bastante seguro de que había mucha memoria para ello. ¿En qué condiciones linux (busybox) envía una SIGTERM a un proceso?

michelemarcon
fuente
No se me ocurre ningún caso en el que el núcleo o una herramienta estándar enviarían SIGTERM a un proceso aleatorio. ¿Qué puede decirnos sobre lo que está haciendo el programa y cómo se inició? ¿Cómo se enteró del estado de salida del programa? ¿Puedes reproducir el problema? ¿Tienes registros que puedes revisar?
Gilles 'SO- deja de ser malvado'
Está leyendo y escribiendo en una línea en serie, y está respondiendo a las solicitudes UDP y TCP. He envuelto la ejecución en un script bash y, por lo tanto, sé el código de salida.
michelemarcon
1
La documentación de Posix indica que SIGTERM es estrictamente un evento de nivel de usuario. ¿Es posible que alguien más haya podido matar su programa de servidor?
Shellter
3
¡Usted está! El código de retorno 0 significa una salida normal. Si hubiera un SIGTERM, $?se establecería en 143 (128 + número de señal).
Gilles 'SO- deja de ser malvado'
1
Además, ^ C es SIGINT, no SIGTERM, y eso saldría con un código de 130.
flarn2006

Respuestas:

13

Publicaré esto como respuesta para que haya algún tipo de resolución si este es el problema.

Un estado de salida de 0 significa una salida normal de un programa exitoso. Un programa existente puede elegir cualquier número entero entre 0 y 255 como su estado de salida. Convencionalmente, los programas usan valores pequeños. El shell utiliza los valores 126 y superiores para informar condiciones especiales, por lo que es mejor evitarlos.

En el nivel C API, los programas informan un estado de 16 bits bit que codifica tanto el estado de salida del programa como la señal que lo mató, si corresponde.

En el shell, el estado de salida de un comando (guardado en $?) combina el estado de salida real del programa y el valor de la señal: si un programa es eliminado por una señal, $?se establece en un valor mayor que 128 (con la mayoría de los shells, este valor es 128 más el número de señal; ATT ksh usa 256 + número de señal y yash usa 384 + número de señal, lo que evita la ambigüedad, pero los otros proyectiles no han seguido el ejemplo).

En particular, si $?es 0, su programa salió normalmente.

Tenga en cuenta que esto incluye el caso de un proceso que recibe SIGTERM, pero tiene un controlador de señal y finalmente sale normalmente (quizás como consecuencia indirecta de la señal SIGTERM, quizás no).


Para responder la pregunta en su título, SIGTERM nunca es enviado automáticamente por el sistema. Hay algunas señales que se envían automáticamente como SIGHUP cuando un terminal desaparece, SIGSEGV / SIGBUS / SIGILL cuando un proceso hace cosas que no debería estar haciendo, SIGPIPE cuando escribe en un tubo / zócalo roto, etc. Y hay algunas señales que se envían debido a una pulsación de tecla en un terminal, principalmente SIGINT para Ctrl+ C, SIGQUIT para Ctrl+ \y SIGTSTP para Ctrl+ Z, pero SIGTERM no es uno de esos. Si un proceso recibe SIGTERM, algún otro proceso envió esa señal.

¹ más o menos hablando

Gilles 'SO- deja de ser malvado'
fuente
Buena explicación de cómo se determina el estado de salida al recibir una señal. Sin embargo, esta respuesta no responde a la pregunta de OP.
codeforester
1
@codeforester Respondí la pregunta en el cuerpo, no la pregunta en el título. Bueno, una de las preguntas en el cuerpo, dado que se basó en un malentendido, es un poco desordenado. Agregaré algunas palabras sobre el resto.
Gilles 'SO- deja de ser malvado'
Eso depende de la cáscara. En ksh93, es 256 + signum, en yash, es 384 + signum
Stéphane Chazelas
Tenga en cuenta que el uso de un valor superior a 256 a la ksh no es necesariamente mejor, ya que eso evita que se lo pase exit. El yashenfoque es un buen compromiso, pero vea rc para otro. Ver también ¿ Código de salida predeterminado cuando finaliza el proceso?
Stéphane Chazelas
10

SIGTERM es la señal que generalmente se usa para terminar administrativamente un proceso.

Esa no es una señal que el núcleo enviaría, pero esa es la señal que un proceso enviaría típicamente para terminar (con gracia) otro proceso.

Esa es la señal que se envía por el impago de los kill, pkill, killall, fuser -k... comandos.

Esa es la señal que se envía a los demonios para detenerlos (como en a service some-service stop), o se envía initantes del apagado (seguido de SIGKILL para aquellos procesos que no han logrado terminar a tiempo en SIGTERM).

Tenga en cuenta que SIGTERM no es la señal que se envía ^C. La señal enviada ^Ces SIGINT.

Stéphane Chazelas
fuente