Как я уже говорил, большинство сигналов зависит от ОС. Для Linux внимательно прочитайте signal(7). Вы забыли \n
внутри своего printf
(обычно вам будет повезло увидеть что-то в вашем коде, но прочитайте весь мой ответ). И в принципе вы не должны называть printf
(который не является функцией защиты от асинхронного сигнала, вы должны использовать напрямую и только write(2) внутри) от вашего обработчика сигнала.
Что, вероятно, происходит это (не обращая внимания на undefined behavior, создаваемый неправильно используя printf
внутри обработчик сигналу) является то, что:
вашего stdout
буфер никогда не покраснел, так как вы забыли \n
(вы можете добавить fflush(NULL);
...) в printf
внутри my_handler
в коде
вероятно, обработчик SIGFPE снова перезагружает machine code инструкция запуска его. (Более точно, после возвращения из sigreturn(2) ваша машина находится в том же состоянии, как это было раньше SIGFPE
было доставлено, так же условие деления на ноль происходит, и т.д ...)
трудно (но с болью возможно, если вы согласны с кодированием аппаратного и специфического для операционной системы кода) для обработки SIGFPE
; вы бы использовать sigaction(2) с SA_SIGINFO
и обрабатывать третий аргумент обработчика сигнала (который является ucontext_t
указатель косвенно давая состояние машины, в том числе processor registers, которые вы можете изменить внутри обработчика, в частности, вы могли бы изменить ваше возвращение program counter там) , Вы можете также рассмотреть возможность использования sigsetjmp(3) внутри вашего обработчика сигнала (но это теоретически запрещено, поскольку не безопасно для асинхронного сигнала).
(Вы, конечно, нужно понимать детали instruction set архитектуры вашего процессора и вашей операционной системы ABI, и вы, вероятно, потребуется неделя кодирования работы после того, освоив их)
В портативном POSIX пути, SIGFPE
не может действительно быть обработаны, как описано в Blue Moon's answer
Вероятно, время выполнения JVM или SBCL обрабатывает SIGFPE
в машине & операционной системы определенным образом сообщать нулевое деление как исключение по принципу «деление на ноль» .... (для программ Java для JVM, для общих программ Lisp для SBCL). В качестве альтернативы их JIT или компилятор могут генерировать тест перед каждым подразделением.
BTW, флаг, установленный внутри обработчика сигнала, должен быть объявлен volatile sig_atomic_t
.См POSIX спецификации о <signal.h>
Как прагматическом правило, обработчик портативный и надежный сигнал POSIX должен только установить некоторые volatile sig_atomic_t
и/или, возможно, write(2) несколько байт в какой-то pipe(7) (ваш процесс мог бы создать трубу к себе - а recommended by Qt - с другой нитью и/или какой-то цикл обработки событий чтения), но это не работает для асинхронных process -порожденных сигналы, как SIGFPE
, SIGBUS
, SIGILL
и SIGSEGV
, и т.д. ... (который может быть обработан только с помощью болезненного компьютерного кода).
См. Также this answer к очень близкому вопросу.
Наконец, в Linux обработка сигналов считается не очень быстрой. Даже с большим количеством машинного кодирования, эмулируя GNU Hurd external pagers хитростью SIGSEGV
, обработка (которая была бы mmap
lazily ....), как полагают, была довольно медленной.
Большинство сигналов зависит от ОС. Для Linux внимательно прочитайте [signal (7)] (http://man7.org/linux/man-pages/man7/signal.7.html) и обратите внимание, что вам разрешено использовать только безопасные функции асинхронного сигнала (есть очень немногие из них) в обработчиках сигналов. В частности, использование 'printf' (или' std :: cout' и, например, его 'operator <<') в обработчике сигнала запрещено –
Возможная дубликация [Сигнал SIGFPE вопрос] (https://stackoverflow.com/questions/6628947/signal-sigfpe-question) –