2012-02-12 9 views
4

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

Мне нужно, чтобы 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.

+0

Удивительно, как далеко у вас есть. Вы знаете, что трюк FS работает только для x86? Является ли ваша работа любопытством или вы серьезно занимаетесь разработкой собственных волокон? Насколько я знаю, разработчики CLR попытались также заменить стек, когда они достигли предела стека, но не смогли (http://blogs.msdn.com/b/cbrumme/archive/2003/10/01/51524. ASPX). Возможно, вы можете обмануть ОС, чтобы использовать несколько стеков для одного физического потока, но вполне вероятно, что будущие обновления безопасности будут создавать дополнительные барьеры. –

+0

Вот еще одна жертва: http://stackoverflow.com/questions/2357102/mixing-win32-seh-with-heap-allocated-stack-frames –

+0

Код, очевидно, только x86, да. В среде исполнения языка D уже есть своя реализация волокон, и я бы хотел не переключиться на «CreateFiber» и друзей, потому что в настоящее время пути к кодам Windows и Posix хорошо параллельны - может быть, у меня не будет другого выбора. Во всяком случае, я в настоящее время пытаюсь воспроизвести необходимые обработчики вручную, давайте посмотрим, если это сработает ... (может быть, я буду знать, что может быть разорван с будущими обновлениями) – klickverbot

ответ

1

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

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