0

Lately have been testing out using signals such as SIGINT and SIGHUP and their role on ongoing processes on Linux. Running the following code returned some interesting results.

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

void routine(int p){
    puts("Not finishing");
    sleep(2);
}

main(){
    int i = 0;
    signal(SIGINT, routine);
    signal(SIGHUP, routine);

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

As you can see, it simply counts from 0 on an infinite loop. Then, by using kill -SIGINT on the process it created, I got the following:

Routine

As you can see, before the line I requested the routine to print, the program repeated the last number (and it does not happen always). I would really like to know why.

  • 5
    You can't safely use stdio functions in signal handlers. See `man signal-safety` for the ones you can use. – Shawn Oct 03 '18 at 05:08
  • Read this [To know why printf should not be used inside signal handler](https://stackoverflow.com/questions/16891019/how-to-avoid-using-printf-in-a-signal-handler) – Achal Oct 03 '18 at 05:21

1 Answers1

1

It is likely that you are narrowly avoiding horrible bugs by accident.

What I think is happening is that the signal sometimes interrupts while printf is in progress formatting the string into the output buffer. Then the puts in the signal handler inserts more string into the output buffer. Then the handler returns, printf inserts the newline and flushes the buffer.

But guess what would happen if this signal occurred just before the flush of a full 8K output buffer. The buffer positions would be at the end. Then the puts call happens, not realizing that printf is already in process of flushing and clearing the buffer. Where exactly would it be putting the puts string? At the beginning? At the end? Would the excess data printf was in the process of writing write over the string that puts had added? All of those things are possible.

Buffered C output is not reentrant and cannot be used in signal handlers.

Zan Lynx
  • 53,022
  • 10
  • 79
  • 131