Активирована настройка SEH для волокон с проверкой цепочки исключений (SEHOP) - PullRequest
4 голосов
/ 12 февраля 2012

Я работаю над собственной реализацией волокна / сопрограммы - достаточно стандартной, для каждого волокна выделяется отдельный стек, и для переключения контекстов регистры помещаются в стек исходного контекста и извлекаются из целевого стека. Это хорошо работает, но теперь я столкнулся с небольшой проблемой:

Мне нужно, чтобы SEH работал в волокне (это нормально, если программа завершается или странные вещи начинают происходить, когда исключение остается необработанным до последнего кадра стека волокна, не будет). Просто сохраните / восстановите FS:[0] (вместе с FS:[4] и FS:[8], очевидно) во время переключения контекста и первоначально установите FS: [0] для вновь выделенных волокон на 0xFFFFFFFF (чтобы обработчик исключений устанавливался после контекста переключатель будет корнем цепи) почти работает.

Если быть точным, он работает на всех несерверных операционных системах Windows, которые я тестировал - проблема в том, что в Windows Server 2008 и 2008 R2 включена функция проверки цепочки исключений (SEHOP, защита от перезаписи SEH), что делает RaiseException проверьте, является ли исходный обработчик (где-то в ntdll.dll) все еще корнем цепочки, и немедленно завершает программу, как будто никакие обработчики не были установлены в противном случае.

Таким образом, я сталкиваюсь с проблемой создания соответствующего корневого фрейма в стеке, чтобы код проверки был доволен. Есть ли какие-либо (скрытые?) API-функции, которые я могу вызвать, чтобы сделать это, или мне нужно выяснить, что нужно для того, чтобы RtlDispatchException и друзья были довольны, и самостоятельно создать соответствующую запись _EXCEPTION_REGISTRATION? Я не могу просто использовать предоставленный Windows один из потока создания, потому что это было бы по неправильному адресу (реализация SEH также проверяет, находится ли адрес обработчика в границах, заданных FS:[4] и FS:[8], и, возможно, также если порядок адресов соответствует).

О, и я бы настоятельно предпочел , а не , чтобы прибегнуть к семейству функций CreateFiber WinAPI.

1 Ответ

1 голос
/ 11 ноября 2012

Подход, который я упомянул в комментариях, генерирующий поддельную запись EXCEPTION_REGISTRATION, указывающую на ntdll!FinalExceptionHandler, кажется, действительно работает на практике - по крайней мере, это то, что мы имеем сейчас во время выполнения D, и до сих пор не было сообщения о проблемах:

https://github.com/D-Programming-Language/druntime/blob/c39de42dd11311844c0ef90953aa65f333ea55ab/src/core/thread.d#L4027

...