У меня есть нечетный самомодифицирующийся код, но в корне его довольно простая проблема: я хочу иметь возможность выполнить jmp
(или call
), а затем из что произвольная точка генерирует исключение и попадает в блок try/catch, содержащий jmp
/call
.Выбрасывание исключения C++ после перехода inline-asm
Но когда я это делаю (в gcc 4.4.1 x86_64), исключение приводит к terminate()
, как если бы исключение было выбрано из-за пределов попытки/catch. Я действительно не вижу, как это отличается от того, что выбрасывает исключение из какой-либо обширной библиотеки, но очевидно, что это просто не работает.
Как я могу выполнить jmp
или call
, но все же исключить исключение для первоначального try/catch? Почему этот try/catch не продолжает обрабатывать эти исключения, как если бы функция вызывалась нормально?
Код:
#include <iostream>
#include <stdexcept>
using namespace std;
void thrower()
{
cout << "Inside thrower" << endl;
throw runtime_error("some exception");
}
int main()
{
cout << "Top of main" << endl;
try {
asm volatile (
"jmp *%0" // same thing happens with a call instead of a jmp
:
: "r"((long)thrower)
:
);
} catch (exception &e) {
cout << "Caught : " << e.what() << endl;
}
cout << "Bottom of main" << endl << endl;
}
Ожидаемый результат:
Top of main
Inside thrower
Caught : some exception
Bottom of main
Фактический выход:
Top of main
Inside thrower
terminate called after throwing an instance of 'std::runtime_error'
what(): some exception
Aborted
Первоначально я задал аналогичный вопрос в контексте обработчиков сигналов в Linux. Это действительно просто омрачало проблему, поэтому я удалил ее и попросил эту более упрощенную версию. Вся вещь обработчика сигналов просто маскировала мою реальную проблему. – SoapBox
Существует примерно два разных способа реализации обработки исключений. Один из них заключается в том, чтобы украсить код и вызвать сайты, чтобы распространять контекст повсюду, а другой - индексировать точки вызова и возврата, чтобы обработчик исключений мог искать, куда идти. В любом случае, inline asm чего-то не хватает. – spraff