Вот потенциальное решение. Это, вероятно, довольно сложно реализовать, и, конечно, по крайней мере, часть из них нуждается в повторной реализации для каждого сочетания архитектуры CPU и ОС и / или библиотеки C:
В обработчике сигналов стек содержит сохраненную копию всех регистров прерванного кода. Вы можете манипулировать этим, чтобы изменить состояние программы после выхода из обработчика сигнала. Вы бы хотели сделать что-то подобное в обработчике:
1) Переместить нижнюю часть стека вниз (текущий кадр стека, состояние процессора, сохраненное ядром, все, что требуется для возврата обработчиком обратно в ядро) в памяти.
2) В свободном пространстве посередине стека придумайте новый кадр стека, как если бы выполнялась какая-то функция «вызова исключений», когда был поднят сигнал. Этот кадр должен быть расположен точно так же, как если бы прерванный код вызывал эту функцию обычным способом.
3) Измените ПК сохраненного состояния ЦП так, чтобы он указывал на эту функцию «вызова исключений».
4) Выход из обработчика сигнала.
Обработчик сигнала вернется к ядру. Ядро вернется к этому новому стековому фрейму (функция «вызов исключения») вместо исходного кода. Эта функция «вызова исключений» должна просто вызывать любое исключение, которое вы хотите вызвать.
Возможно, здесь есть несколько деталей; e.g.:
1) Функция "вызова исключений", вероятно, должна сохранять в стек кучу регистров, чего обычно не было бы; все регистры, сохраненные вызываемым абонентом, которые, возможно, использовал прерванный код. Вам может понадобиться написать (часть?) Функцию «вызова исключений» в ассемблере, чтобы помочь здесь. Возможно, шаг 2, описанный выше, может сохранить регистры как часть настройки стекового кадра.
2) Обработчик сигнала возится со стеком. Это сильно запутает сгенерированный компилятором код. Вам, вероятно, придется написать обработчик исключений (или просто какую-то функцию, которую он вызывает, что потребовало бы перемещения большего количества кадров стека) в сборке, чтобы это работало.
3) Вам может потребоваться вручную сгенерировать некоторую информацию о размотке обработчика исключений C ++, чтобы код обработки исключений C ++ знал, как разматывать стек из этой функции «вызова исключений». Если вы можете написать функцию на C ++, вероятно, нет. Если не можете, то почти наверняка.
4) Вероятно, все виды неприятных деталей, которые я упустил из виду: -)