2012-03-03 8 views
5

código en cuestión primero (caso minimizada):Printf no está funcionando en el manejador de la señal C

#include <stdio.h> 
#include <signal.h> 

int counter = 0; 

void react_to_signal(int n) { 
    fprintf(stderr, "Caught!\n"); 
    counter++; 
} 

int main(int argc, char** argv) { 

    signal(SIGINFO, react_to_signal); 

    while (1) { 
     printf("%d\n", counter); 
    } 

    return 0; 
} 

corro el código, se realiza un bucle como se debe, la impresión de 0. Luego, en otra línea de comandos ..

kill -s SIGINFO <pid_of_my_process> 

La señal es entregada, c se incrementa ... pero el fprintf no ocurre.

¿Por qué es esto así? ¿En qué entorno/contexto se ejecuta el código del controlador? ¿Dónde puedo leer sobre esto?

+0

Intente vaciar stderr con 'fflush (stderr)' – Saphrosit

+2

No utilice printf() et.al. manejadores de señal dentro No son señal de seguridad (por ejemplo: puede llamar a malloc(), que no es seguro para señales) – wildplasser

+0

De manera divertida, podría haber jurado que probé una variante con 'fflush' antes de publicar. O nunca volví a compilar y ejecuté, o me pegué un tiro en el pie con el bucle infinito para sacar el mensaje de la pantalla. Tan poco romántico y tonto. – ntl0ve

Respuesta

14

En resumen: no se puede utilizar con seguridad printf dentro manejador de señales

Hay una list of authorized functions en la página hombre manejador de señales, en asíncrono señal segura sección. No hay fprintf en él.

Eso es porque esta función no es reentrante, principalmente porque puede usar malloc y libre. Ver this post para una explicación detallada.

+0

Muy bien, todo está claro ahora. ¡Muchas gracias! – ntl0ve

1

Es posible que tenga que limpiar stderr para que el mensaje se escriba antes de que finalice el programa.

+0

¿'printf' no se vacía automáticamente cuando llega a una nueva línea? –

+1

No. Consulte https://stackoverflow.com/questions/5229096/does-printf-always-flush-the-buffer-on-encountering-a-newline –

Cuestiones relacionadas