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

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

Comentarios

  • Puedo ' t piense en algún caso en el que el kernel o una herramienta estándar enviaría 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? ¿Tiene registros que pueda verificar?
  • Está leyendo y escribiendo en una línea serial y está respondiendo a solicitudes UDP y TCP. He envuelto la ejecución en un script bash y, por lo tanto, conozco el código de salida.
  • 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?
  • ¡Usted lo 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).
  • Además, ^ C es SIGINT, no SIGTERM, y eso salir con un código de 130.

Respuesta

Publicaré esto como respuesta que hay algún tipo de resolución si este resulta ser el problema.

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

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

En el shell, un estado de salida del comando (guardado en $?) combina el estado de salida real del programa y el valor de la señal: si un programa es cancelado 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 shells no han seguido su ejemplo).

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

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


Para responder a la pregunta en su título, el sistema nunca envía SIGTERM automáticamente. 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 una tubería / enchufe roto, etc. Y hay algunas señales que se envían debido a la pulsación de una 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.

¹ grosso modo

Comentarios

  • Buena explicación de cómo se determina el estado de salida al recibir una señal. Sin embargo, esta respuesta no ' t responde a la pregunta de OP '.
  • @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 complicado. I ' Agregaré algunas palabras sobre el resto.
  • Eso depende del shell. En ksh93, ' s 256 + signum, en yash, es ' s 384 + signum
  • Tenga en cuenta que usar un valor superior a 256 a la ksh no es necesariamente mejor, ya que evita que se pase a exit. El enfoque yash es un buen compromiso, pero consulte rc para ver otro. Consulte también ¿Código de salida predeterminado cuando finaliza el proceso?

Respuesta

SIGTERM es la señal que se usa típicamente para terminar administrativamente un proceso.

Esa no es una señal que enviaría el kernel, pero esa es la señal que normalmente enviaría un proceso enviar para terminar (con gracia) otro proceso.

Esa es la señal que envía de forma predeterminada el kill, pkill, killall … comandos.

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

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

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *