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?

Coren
  • 5,517
  • 1
  • 21
  • 34
ntl0ve
  • 1,896
  • 3
  • 19
  • 25
  • Try to flush stderr using `fflush(stderr)` – Manlio Mar 03 '12 at 17:04
  • 2
    Don't use printf() et.al. inside signal handlers. They are not signal safe (eg: can call malloc(), which is not signal-safe) – wildplasser Mar 03 '12 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. – ntl0ve Mar 03 '12 at 18:43
  • How does `printf` use `malloc`/`free`? (What for?) – ntl0ve Mar 03 '12 at 18:44

2 Answers2

19

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.

Coren
  • 5,517
  • 1
  • 21
  • 34
2

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

James McLeod
  • 2,381
  • 1
  • 17
  • 19