Форматированный ввод-вывод внутри обработчика сигналов

Я хотел бы написать обработчик SIGSEGV, который записывает сообщения в файл (FILE *). Я слышал, что fprintf не является реентерабельным и не должен вызываться внутри обработчика сигнала. Существует ли его реентерабельная версия или любая другая функция, обеспечивающая форматированный файловый ввод-вывод, который можно вызывать внутри обработчика сигналов?


person user2491608    schedule 16.06.2013    source источник
comment
Возможный дубликат Печать int из обработчика сигнала с использованием записи или безопасные асинхронные функции   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 20.09.2017


Ответы (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, но если вам нужно это сделать, вот как это делается.

person icktoofay    schedule 16.06.2013