Я хотел бы написать обработчик SIGSEGV, который записывает сообщения в файл (FILE *). Я слышал, что fprintf не является реентерабельным и не должен вызываться внутри обработчика сигнала. Существует ли его реентерабельная версия или любая другая функция, обеспечивающая форматированный файловый ввод-вывод, который можно вызывать внутри обработчика сигналов?
Форматированный ввод-вывод внутри обработчика сигналов
Ответы (1)
Нет. Согласно 7.14.1.1 5 версии N1570 стандарта С11:
Если возникает [the] сигнал [], поведение не определено, если [] обработчик сигнала вызывает любую функцию из стандартной библиотеки, кроме функции
abort
, функции_Exit
, функцииquick_exit
или функцииsignal
[].
Короче говоря, единственные стандартные библиотечные функции, которые вы можете вызывать, это:
abort
_Exit
quick_exit
signal
(применяются дополнительные ограничения)
Очевидно, что ни одна из этих функций не является форматированным вводом-выводом, поэтому, если вы хотите придерживаться стандартного C, вы ничего не сможете сделать.
POSIX
Таков был взгляд стандартного C. Если, однако, вас устраивает зависимость от POSIX, вы можете использовать любую из его асинхронно-безопасных функций. Одной из асинхронно-безопасных функций является write
, которая, как и следовало ожидать, записывает данные в файл. Требуется обычный буфер, поэтому, если вы хотите что-то отформатировать, вам придется форматировать это самостоятельно, и вы также не сможете динамически выделять память. Вы также должны быть осторожны с доступом к глобальным и статическим переменным: стандарт C говорит, что вы можете получить к ним доступ только в том случае, если тип volatile sig_atomic_t
.
Преодолев эти препятствия, вы сможете написать сообщение в обработчике сигнала, если вы работаете на платформе POSIX. Это не так просто, как fprintf
, но если вам нужно это сделать, вот как это делается.