linux - [Solved-5 Solutions] How to avoid using printf in a signal handler ? - ubuntu - red hat - debian - linux server - linux pc



Linux - Problem :

How to avoid using printf in a signal handler ?

Linux - Solution 1:

  • You can use some flag variable, set that flag inside signal handler, and based on that flag call printf() function in main() or other part of program during normal operation.
  • It is not safe to call all functions, such as printf, from within a signal handler.
  • A useful technique is to use a signal handler to set a flag and then check that flag from the main program and print a message if required.
  • Notice in example below, signal handler ding() set a flag alarm_fired to 1 as SIGALRM caught and in main function alarm_fired value is examined to conditionally call printf correctly.
static int alarm_fired = 0;
void ding(int sig) // can be called asynchronously
{
  alarm_fired = 1; // set flag
}
int main()
{
    pid_t pid;
    printf("alarm application starting\n");
    pid = fork();
    switch(pid) {
        case -1:
            /* Failure */
            perror("fork failed");
            exit(1);
        case 0:
            /* child */
            sleep(5);
            kill(getppid(), SIGALRM);
            exit(0);
    }
    /* if we get here we are the parent process */
    printf("waiting for alarm to go off\n");
    (void) signal(SIGALRM, ding);
    pause();
    if (alarm_fired)  // check flag to call printf
      printf("Ding!\n");
    printf("done\n");
    exit(0);
}
click below button to copy the code. By - Linux tutorial - team

Linux - Solution 2:

  • Don't use printf() in signal handlers.
  • At least on POSIX conforming systems, you can use write(STDOUT_FILENO, ...) instead of printf(). Formatting may not be easy however: Print int from signal handler using write or async-safe functions

Linux - Solution 3:

  • For debugging purposes, I wrote a tool which verifies that you are in fact only calling functions on the async-signal-safe list, and prints a warning message for each unsafe function called within a signal context. While it doesn't solve the problem of wanting to call non async-safe functions from a signal context, it at least helps you find cases where you have done so accidentally.
  • By overloading signal/sigaction, then temporarily hijacking the PLT entries of unsafe functions; this causes calls to unsafe functions to be redirected to a wrapper.

Linux - Solution 4:

It is especially useful in programs which have a select loop is to write a single byte down a pipe on receipt of a signal and then handle the signal in the select loop.

static int sigPipe[2];

static void gotSig ( int num ) { write(sigPipe[1], "!", 1); }

int main ( void ) {
    pipe(sigPipe);
    /* use sigaction to point signal(s) at gotSig() */

    FD_SET(sigPipe[0], &readFDs);

    for (;;) {
        n = select(nFDs, &readFDs, ...);
        if (FD_ISSET(sigPipe[0], &readFDs)) {
            read(sigPipe[0], ch, 1);
            /* do something about the signal here */
        }
        /* ... the rest of your select loop */
    }
}
click below button to copy the code. By - Linux tutorial - team

Linux - Solution 5:

  • You can use printf in signal handlers if you are using the pthread library.
  • Note that in order to get a clearer picture of printf output, you should run your application in a console (on linux use ctl+alt+f1 to start console 1), rather than a pseudo-tty created by the GUI.

Related Searches to - linux - linux tutorial - How to avoid using printf in a signal handler ?