问题
I'd like to write a SIGSEGV handler that writes messages to a file (FILE *). I've heard that fprintf is not reentrant and should not be called inside a signal handler. Is there a reentrant version of it, or any other function that provides formatted file I/O that can be called inside a signal handler?
回答1:
No. According to §7.14.1.1 ¶5 of version N1570 of the C11 standard:
If [the] signal occurs […], the behavior is undefined if […] the signal handler calls any function in the standard library other than the
abort
function, the_Exit
function, thequick_exit
function, or thesignal
function […].
So in short, the only standard library functions you can call are:
abort
_Exit
quick_exit
signal
(additional restrictions apply)
Obviously, none of those are formatted I/O functions, so if you want to stick to standard C, there's nothing you can do.
POSIX
That was the view of standard C. If, however, you're okay with being dependent upon POSIX, you can use any of its async-safe functions. One of the async-safe functions is write
, which, as you might expect, writes to a file. It takes a plain buffer, so if you want to format anything, you'll have to format it yourself, and you might not be able to dynamically allocate memory, either. You also have to be careful about accessing global and static variables: the C standard says you can only access them if the type is volatile sig_atomic_t
.
Jumping through those hoops will allow you to write a message in the signal handler as long as you're on a POSIX platform. It's not as easy as fprintf
, but if you have to do it, that's how it's done.
来源:https://stackoverflow.com/questions/17138158/formatted-i-o-inside-signal-handler