LINUX.ORG.RU

Про сигналы и исключения

 , , ,


0

1

Написал 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).

Но ясен пень, что это костыльно. Вот что, если у меня есть свой собственный сферический компилятор в вакууме и я пишу рантайм, который должен выполнить некоторое действие при делении на ноль. Как разумнее всего будет обработать эту ситуацию? Вообще, нормальная ли практика, что обработчик совершает какие-либо прыжки по коду, а не возвращается в место возникновения ошибки. Какие-нибудь примеры/литературу можете подкинуть?

ЗЫ. Почему-то «Це» - некорректный тэг


если уж прибиваешь гвоздями то хотя бы прибивай правильно https://github.com/gccxml/gccxml/blob/master/GCC_XML/Support/GCC/4.3/xmmintrin.h https://github.com/gccxml/gccxml/blob/master/GCC_XML/Support/GCC/4.3/emmintrin.h https://github.com/gccxml/gccxml/blob/master/GCC_XML/Support/GCC/4.3/mmintrin.h

exception13 ★★★★★
()
Последнее исправление: exception13 (всего исправлений: 1)
Ответ на: комментарий от exception13

Если бы ты прочел вопрос, то понял бы, что спрашиваю о том, как не прибивать гвоздями

onanij
() автор топика
Ответ на: комментарий от x0r

Эх, раз такое пошло, давайте искать у него ещё ошибки. Например " вместо "". И шо такое вообще print ?

onanij
() автор топика

Я думаю тебе нужно уточнить вопрос. Что значит «какие-либо прыжки по коду» и «возвращается в место возникновения ошибки», например?

vasily_pupkin ★★★★★
()
Ответ на: комментарий от vasily_pupkin

Ну считается ли хорошим тоном, что обработчик изменяет instruction pointer, как у меня. Или, может быть, он должен откуда-то получить информацию, в каких регистрах сидят операнды и загрузить их сам. Ну и хорошо бы примерчики таких обработчиков.

Я просто вопросом обработки всяких division by zero (как оно внутри устроено) озаботился чисто ради интереса.

onanij
() автор топика
Ответ на: комментарий от vasily_pupkin

Ну например, я написал цомпилятор некоего язычка, который использует SSE. Он откомпилировал некую функцию, которая делит два числа. Я запускаю её в своём рантайме (который предоставляет сборщик мусора, например, обработку исключений ту же, аллокатор объектов). Функция поделила на 0, прислался SIGFPE (я заранее включил нужное прерывание).

Вопрос, как лучше это обработать. Под обработкой подразумевается выполнение некоторого действие, указанного пользователем, или выпадение в отладчик.

onanij
() автор топика
Ответ на: комментарий от onanij

ЯННП. Что за прерывание, о каком контексте использования речь? Причем тут компилятор? Ты хочешь что бы твой компилятор автоматом встраивал обработчики сигналов? Каких сигналов? Всех подряд? Определенных, причина которых в аппаратных прерываниях?

Думаю тебе надо посмотреть реализации рантаймов в поисках примера в этом случае.

vasily_pupkin ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.