Написал just for lulz такую прожуцу:
#include <stdio.h>
#include <signal.h>
#include <stdint.h>
#include <ucontext.h>
#include <machine/fpu.h>
float lol;
void signal_handler (int signal, siginfo_t *siginfo, void *foo)
{
lol = 1.0f;
ucontext_t *context = foo;
context->uc_mcontext.mc_rip -= 16; // Reload arguments into XMM registers
}
int main()
{
lol = 0.0f;
struct sigaction s;
s.sa_sigaction = signal_handler;
s.sa_flags = SA_SIGINFO;
sigemptyset (&s.sa_mask);
sigaction (SIGFPE, &s, NULL);
unsigned int reg;
asm ("stmxcsr %0" : : "m" (reg));
reg &= ~1<<9;
asm ("ldmxcsr %0" : : "m" (reg));
float f = 9.0/lol;
printf ("%f %f\n", f, lol);
return 0;
}
Это типа супирь-пупирь обработчик деления на ноль. Обрабатываем SIGFPE, ставим lol в 1.0 и выполняем загрузку аргументов в XMM регистры заново (компиляторо и платформо зависимо, у меня mov занимает 7 байт + nop после mov).
Но ясен пень, что это костыльно. Вот что, если у меня есть свой собственный сферический компилятор в вакууме и я пишу рантайм, который должен выполнить некоторое действие при делении на ноль. Как разумнее всего будет обработать эту ситуацию? Вообще, нормальная ли практика, что обработчик совершает какие-либо прыжки по коду, а не возвращается в место возникновения ошибки. Какие-нибудь примеры/литературу можете подкинуть?
ЗЫ. Почему-то «Це» - некорректный тэг