8

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?

4
  • Try to flush stderr using fflush(stderr) Commented Mar 3, 2012 at 17:04
  • 3
    Don't use printf() et.al. inside signal handlers. They are not signal safe (eg: can call malloc(), which is not signal-safe) Commented Mar 3, 2012 at 17:05
  • Amusingly, I could've sworn I'd tried a variant with fflush before I posted. Either never recompiled and ran, or shot myself in the foot with the infinite loop moving the message off screen. So unromantic and dumb. Commented Mar 3, 2012 at 18:43
  • How does printf use malloc/free? (What for?) Commented Mar 3, 2012 at 18:44

3 Answers 3

21

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.

Sign up to request clarification or add additional context in comments.

1 Comment

In addition to potentially calling malloc/free (for buffer management), its internal buffer management is not reentrant, so if a signal occurs in the middle of a printf call, the fprintf call may end up corrupting the buffer in odd ways, leading to garbage or missed output.
2

You may need to fflush stderr to get the message to write before the program exits.

2 Comments

Doesn't printf automatically flush when it reaches a newline?
1

In addition to the reentrancy problems, since counter is not volatile, its read might get hoisted out of the while(1) loop, leading to the printf in the loop always printing 0 even when the signal handler increments the global variable.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.