2

We know that printf is not async signal safe function. And below is my basic understanding:

Let's say we have called printf in main method, so the content is written to stdio buffer, just before the buffer get flushed to the file, a signal arrives and the signal handler also calls printf, and the second printf append it's content to the buffer, now the buffer has content from first call and second call, which is inconsistent, this is not correct, therefore we cannot use non asyc safe functions in signal handlers. Is my understanding correct?

If my understanding is correct, then how can async safe function solve this problem? Because the safe function still need to deal with buffer, which still might contain precious call's buff data?

5
  • Modern printf() implementations are thread safe. If you do something before (e.g. setvbuf()), that causes the I/O buffer to be allocated early, you can safely use printf() from signal handlers.
    – schily
    Sep 13, 2020 at 21:33
  • @schily No, printf is by definition non-reentrant, so it absolutely cannot be used from signal handlers. thread-safe != async-signal-safe. printf is thread-safe but not async-signal-safe.
    – user313992
    Sep 15, 2020 at 7:01
  • here is a list of functions which are async-signal-safe according to the standard. (the table is after the shall be async-signal-safe.).
    – user313992
    Sep 15, 2020 at 7:09
  • Multiply posted on stackoverflow.com/q/63868653/340790 by a prolific multi-poster.
    – JdeBP
    Sep 15, 2020 at 7:43
  • @ktzap You should have a look at printf implementations. It operates on local memory on the stack so it is reentrant. The only problem in printf is the use of stdio.
    – schily
    Sep 15, 2020 at 8:47

2 Answers 2

4

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.

The recommended async-signal-safe approach is for the signal handler to set a flag somewhere, and have the main program flow deal with the flag. This avoids issues with re-entrance, serialises output, and helps keep signal handlers speedy.

4

Is my understanding correct?

Mostly. There's also the problem with the nested printf calls stepping on each other toes when adjusting the offset and size of the buffer(s), which can result not only in inconsistent data, but also in crashes.

how can async safe function solve this problem?

There are two kinds of async-signal-safe functions:

  • reentrant functions like strlen(3), which are not modifying any memory beyond that used to hold their local variables, arguments and return value.

  • functions which are simple system call wrappers, like kill(2), waitpid(2), etc: their userland part is completely reentrant as above, and for the kernel part, the kernel takes care of everything.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .