¿Qué causa que se envíen varias señales?

28

A veces me confundo un poco con todas las señales que puede recibir un proceso. Según tengo entendido, un proceso tiene un controlador predeterminado ( disposición de señal ) para cada una de estas señales, pero puede proporcionar su propio controlador llamando sigaction().

Así que aquí está mi pregunta: ¿qué hace que se envíen cada una de las señales? Me doy cuenta de que puede enviar señales manualmente a los procesos en ejecución a través del -sparámetro kill, pero ¿cuáles son las circunstancias naturales en las que se envían estas señales? Por ejemplo, ¿cuándo SIGINTse envía?

Además, ¿hay restricciones sobre qué señales se pueden manejar? ¿Se SIGSEGVpueden procesar incluso las señales y devolver el control a la aplicación?

Nathan Osman
fuente
Una respuesta adecuada a esto será épica, y básicamente replicará la información en el artículo de Wikipedia sobre el asunto, así que solo señalaré allí.
Shawn J. Goff el
@Shawn: El artículo de Wikipedia tiene una lista de señales, pero no una presentación clara de quién envía qué señales.
Gilles 'SO- deja de ser malvado'

Respuestas:

41

Además de las llamadas a procesos kill(2), el núcleo envía algunas señales (o, a veces, el propio proceso) en varias circunstancias:

  • Los controladores de terminal envían señales correspondientes a varios eventos:
    • Notificaciones de pulsación de teclas: SIGINT(vuelva al bucle principal) en Ctrl+ C, SIGQUIT(salga inmediatamente) en Ctrl+ \, SIGTSTP(suspenda) en Ctrl+ Z. Las claves se pueden cambiar con el sttycomando.
    • SIGTTINy SIGTTOUse envían cuando un proceso en segundo plano intenta leer o escribir en su terminal de control.
    • SIGWINCH se envía para indicar que el tamaño de la ventana del terminal ha cambiado.
    • SIGHUPse envía a la señal de que el terminal ha desaparecido (históricamente debido a su módem tuvo h ung arriba , hoy en día por lo general porque se ha cerrado la ventana de emulación de terminal).
  • Algunas trampas de procesador pueden generar una señal. Los detalles dependen de la arquitectura y el sistema; Aquí hay ejemplos típicos:
    • SIGBUS para una memoria de acceso no alineada;
    • SIGSEGV para acceder a una página no asignada;
    • SIGILL para una instrucción ilegal (código de operación incorrecto);
    • SIGFPEpara una instrucción de punto flotante con malos argumentos (por ejemplo sqrt(-1)).
  • Una serie de señales notifican al proceso de destino que se ha producido algún evento del sistema:
    • SIGALRMnotifica que un temporizador establecido por el proceso ha expirado. Temporizadores pueden ajustarse con alarm, setitimerentre otros.
    • SIGCHLD notifica a un proceso que uno de sus hijos ha muerto.
    • SIGPIPEse genera cuando un proceso intenta escribir en una tubería cuando se ha cerrado el final de la lectura (la idea es que si se ejecuta foo | bary barsale, a) lo foomata SIGPIPE.
    • SIGPOLL(también llamado SIGIO) notifica al proceso que se ha producido un evento pollable. POSIX especifica eventos sondeables registrados a través de I_SETSIG ioctl. Muchos sistemas permiten eventos sondeables en cualquier descriptor de archivo, establecido a través de la O_ASYNC fcntlbandera. Una señal relacionada es SIGURG, que notifica los datos urgentes en un dispositivo (registrado a través de I_SETSIG ioctl) o el zócalo .
    • En algunos sistemas, SIGPWRse envía a todos los procesos cuando el UPS señala que una falla de energía es inminente.

Estas listas no son exhaustivas. Las señales estándar se definen en signal.h.

La aplicación puede capturar y manejar la mayoría de las señales (o ignorarlas). Las únicas dos señales portátiles que no pueden captarse son SIGKILL(simplemente morir) y STOP(detener la ejecución).

SIGSEGV( error de segmentación ) y su primo SIGBUS( error del bus ) pueden detectarse, pero es una mala idea a menos que realmente sepa lo que está haciendo. Una aplicación común para atraparlos es imprimir un seguimiento de pila u otra información de depuración. Una aplicación más avanzada es implementar algún tipo de gestión de memoria en proceso o atrapar instrucciones incorrectas en motores de máquinas virtuales.

Finalmente, permítanme mencionar algo que no es una señal. Cuando presiona Ctrl+ Dal comienzo de una línea en un programa que lee la entrada del terminal, esto le dice al programa que se alcanza el final del archivo de entrada. Esto no es una señal: se transmite a través de la API de entrada / salida. Al igual que Ctrl+ Cy amigos, la clave se puede configurar con stty.

Gilles 'SO- deja de ser malvado'
fuente
Y SIGHUP, tu módem ha colgado. :-)
Keith
1
Otra cosa a tener en cuenta:, de forma SIGFPEpoco intuitiva, también se señala en la división entera por cero y, a veces, en el desbordamiento de entero con signo.
Ephemient
18

Para responder a su segunda pregunta primero: SIGSTOPy SIGKILLno puede ser captado por la aplicación, pero cualquier otra señal puede, incluso SIGSEGV. Esta propiedad es útil para la depuración; por ejemplo, con el soporte correcto de la biblioteca, puede escuchar SIGSEGVy generar una traza inversa de la pila para mostrar dónde sucedió esa falla predeterminada.

La palabra oficial (para Linux, de todos modos) sobre lo que hace cada señal está disponible escribiendo man 7 signaldesde una línea de comando de Linux. http://linux.die.net/man/7/signal tiene la misma información, pero las tablas son más difíciles de leer.

Sin embargo, sin algo de experiencia con las señales, es difícil saber de las descripciones breves lo que hacen en la práctica, así que aquí está mi interpretación:

Disparado desde el teclado

  • SIGINTsucede cuando golpeas CTRL+C.
  • SIGQUITse activa por CTRL+\, y vuelca el núcleo.
  • SIGTSTPsuspende tu programa cuando golpeas CTRL+Z. A diferencia SIGSTOP, es capturable, lo que brinda a los programas la viposibilidad de restablecer el terminal a un estado seguro antes de suspenderse.

Interacciones terminales

  • SIGHUP ("colgar") es lo que sucede cuando cierra su xterm (o desconecta el terminal) mientras su programa se está ejecutando.
  • SIGTTINy SIGTTOUpause su programa si intenta leer o escribir en el terminal mientras se ejecuta en segundo plano. Para SIGTTOUque suceda, creo que el programa debe estar escribiendo /dev/tty, no solo stdout predeterminado.

Activado por una excepción de CPU

Esto significa que su programa intentó hacer algo mal.

  • SIGILLsignifica una instrucción de procesador ilegal o desconocida. Esto podría suceder si intentara acceder a los puertos de E / S del procesador directamente, por ejemplo.
  • SIGFPEsignifica que hubo un error matemático de hardware; Lo más probable es que el programa haya intentado dividir por cero.
  • SIGSEGV significa que su programa intentó acceder a una región de memoria no asignada.
  • SIGBUSsignifica que el programa accedió a la memoria incorrectamente de alguna otra manera; No entraré en detalles para este resumen.

Interacción del proceso

  • SIGPIPEsucede si intenta escribir en una tubería después de que el lector de la tubería cerró su extremo. Ver man 7 pipe.
  • SIGCHLDsucede cuando un proceso secundario que creó se cierra o se suspende (por SIGSTOPo similar).

Útil para auto-señalización

  • SIGABRTgeneralmente es causado por el programa que llama a la abort()función y causa un volcado de núcleo por defecto. Una especie de "botón de pánico".
  • SIGALRMes causado por la alarm()llamada del sistema, lo que hará que el núcleo entregue un mensaje SIGALRMal programa después de un número específico de segundos. Ver man 2 alarmy man 2 sleep.
  • SIGUSR1y SIGUSR2se usan sin embargo, el programa le gusta. Podrían ser útiles para la señalización entre procesos.

Enviado por el administrador

Estas señales generalmente se envían desde el símbolo del sistema, a través del killcomando fgo bgen el caso de SIGCONT.

  • SIGKILLy SIGSTOPson las señales que no se pueden bloquear. El primero siempre termina el proceso de inmediato; el segundo suspende el proceso.
  • SIGCONT reanuda un proceso suspendido.
  • SIGTERMes una versión atrapable de SIGKILL.
Jander
fuente
¿Qué señal se envía cuando shutdownse usa el comando?
Nathan Osman el
Eso depende de los scripts de apagado. Por lo general, SIGTERMse envía primero, seguido de un retraso, seguido de SIGKILL. En principio, para un apagado rápido e inmediato, el núcleo no necesita enviar ninguna señal; simplemente podría dejar de ejecutar el proceso.
Jander