Code in question first (minimized case):
#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;
}
I run the code, it loops as it should, printing out 0. Then in another shell..
kill -s SIGINFO <pid_of_my_process>
Signal is delivered, c
is incremented .. but the fprintf
doesn't happen.
Why is this so? In what environment/context does handler code run? Where can I read up on this?
You can use printf in signal handlers if you are using the pthread library.
printf is non-async-signal-safe because, as you describe, it ends up manipulating global state without synchronisation. For added fun, it's not necessarily re-entrant. In your example, the signal might be handled while the first printf is running, and the second printf could mess up the state of the first call.
A signal can be generated by calling raise() or kill() system calls. raise() sends a signal to the current process, kill() sends a signal to a specific process. A signal handler is a function which is called by the target environment when the corresponding signal occurs.
The signal() system call just installs the handler: "signal() sets the disposition of the signal signum to handler, which is either SIG_IGN, SIG_DFL, or the address of a programmer-defined function (a "signal handler")." There you go.
In short: you cannot safely use printf
within a signal handler.
There's a list of authorized functions in signal handler's man page. There is not fprintf
in it.
That's because this function is not reentrant, mainly because it can use malloc
and free
.
See this post for a detailed explanation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With