سؤال

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?

هل كانت مفيدة؟

المحلول

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, the quick_exit function, or the signal 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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top