Здравствуйте. Думаю, вопрос уже немало обсосан, но осмелюсь поднять очередную тему.
Реализовал сопрограммы используя WinAPI-функции SetThreadContext и GetThreadContext. Точнее, я подглядел как это сделал другой человек Он эмулировал ими стандартные POSIX-функции getcontext/setcontext/makecontext/swapcontext и потом, на их основе "возвел" класс сопрограммы. Все работает четко, но исключения не ловятся То есть если я внутри сопрограмммы напишу:
try
{
throw 1;
}
catch(int)
{
},
то исключение не словится, будет unhadled exception. Это делает меня плакать, я о сопрограммах джва года мечтал Соответственно, вопросы знатокам:
1. Можно ли как-то "пропатчить" SetThreadContext и GetThreadContext чтобы исключения работали?
2. POSIX-функции getcontext/setcontext/makecontext/swapcontext на Unix-ах дружат с исключениями? Или вообще такой подход нежизнеспособен?
3. boost.Coroutines — стоящая вещь? Она делает хорошие портабельные и компактные сопрограммы? Или она тоже работает только в тепличных условиях?
4. Сопрограммы вообще могут быть портабельными в пределах Win32-Unix(MacOS)?
5. А как с мобильными платформами? Android дружит с этим? Он же вроде потомок Unix. А iOS?
W>Здравствуйте. Думаю, вопрос уже немало обсосан, но осмелюсь поднять очередную тему. W>Реализовал сопрограммы используя WinAPI-функции SetThreadContext и GetThreadContext. Точнее, я подглядел как это сделал другой человек Он эмулировал ими стандартные POSIX-функции getcontext/setcontext/makecontext/swapcontext и потом, на их основе "возвел" класс сопрограммы. Все работает четко, но исключения не ловятся То есть если я внутри сопрограмммы напишу:
винда не ловит исключения если
1) цепочка SEH обработчиков, начинающаяся с _NT_TIB::ExceptionList невалидна
2) текущий esp не укладывается в _NT_TIB::StackBase/StackLimit
Как много веселых ребят, и все делают велосипед...
Здравствуйте, ononim, Вы писали:
W>>Здравствуйте. Думаю, вопрос уже немало обсосан, но осмелюсь поднять очередную тему. W>>Реализовал сопрограммы используя WinAPI-функции SetThreadContext и GetThreadContext. Точнее, я подглядел как это сделал другой человек Он эмулировал ими стандартные POSIX-функции getcontext/setcontext/makecontext/swapcontext и потом, на их основе "возвел" класс сопрограммы. Все работает четко, но исключения не ловятся То есть если я внутри сопрограмммы напишу: O>винда не ловит исключения если O>1) цепочка SEH обработчиков, начинающаяся с _NT_TIB::ExceptionList невалидна O>2) текущий esp не укладывается в _NT_TIB::StackBase/StackLimit
То есть при входе в сопрограмму нужно модифицировать _NT_TIB::StackBase/StackLimit на новый стек, и как-то правильно построить _NT_TIB::ExceptionList? А как мне достучаться к "текущей" _NT_TIB? Я, вообще, не бред говорю?
W>То есть при входе в сопрограмму нужно модифицировать _NT_TIB::StackBase/StackLimit на новый стек, и как-то правильно построить _NT_TIB::ExceptionList? А как мне достучаться к "текущей" _NT_TIB? Я, вообще, не бред говорю?
Не, не бред. Кстати, может вам нужны fiber'ы?
На x86 TEB лежит начиная с FS:[0], удобный адрес TEB в селекторе DS мона достать в FS::[18]
Как много веселых ребят, и все делают велосипед...
[]
O>>1) цепочка SEH обработчиков, начинающаяся с _NT_TIB::ExceptionList невалидна O>>2) текущий esp не укладывается в _NT_TIB::StackBase/StackLimit
W>То есть при входе в сопрограмму нужно модифицировать _NT_TIB::StackBase/StackLimit на новый стек, и как-то правильно построить _NT_TIB::ExceptionList? А как мне достучаться к "текущей" _NT_TIB? Я, вообще, не бред говорю? :)
Сделай свой обработчик VEH и диспатчи исключения в нем, поскольку VEH отрабатывает до SEH.
Что-то типа
"компактные" — это что? в каком смысле?
W>4. Сопрограммы вообще могут быть портабельными в пределах Win32-Unix(MacOS)?
да. см выше.
W>5. А как с мобильными платформами? Android дружит с этим? Он же вроде потомок Unix. А iOS?
см выше.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, Went, Вы писали: W>>2. POSIX-функции getcontext/setcontext/makecontext/swapcontext на Unix-ах дружат с исключениями? Или вообще такой подход нежизнеспособен? X>да. дружат. однажды использовал для подобной задачи. с исключениями проблем не было.
Это радует. Ибо на Win32 без допилки (спасибо ononim) не работало
W>>3. boost.Coroutines — стоящая вещь? Она делает хорошие портабельные и компактные сопрограммы? Или она тоже работает только в тепличных условиях? X>да — портабельные. ибо не использует ничего платформозависимого. посмотри такую реализацию(читать именно с этом порядке): X>http://blog.think-async.com/2009/07/wife-says-i-cant-believe-it-works.html X>http://blog.think-async.com/2009/08/secret-sauce-revealed.html X>http://blog.think-async.com/2009/08/composed-operations-coroutines-and-code.html X>http://blog.think-async.com/2010/03/potted-guide-to-stackless-coroutines.html
Это очень мило Но хотелось бы настоящих сорутин, чтобы со стеком
А разве boost.Coroutines не используют ничего платформеннозависимого? Как они тогда стек двигают?
X>"компактные" — это что? в каком смысле?
Ну, чтобы не приходилось писать специальный синтаксис для функций. Как в приведенном выше примере.
W>>4. Сопрограммы вообще могут быть портабельными в пределах Win32-Unix(MacOS)? X>да. см выше.
W>>5. А как с мобильными платформами? Android дружит с этим? Он же вроде потомок Unix. А iOS? X>см выше.
Здравствуйте, Patalog, Вы писали:
P>Сделай свой обработчик VEH и диспатчи исключения в нем, поскольку VEH отрабатывает до SEH.
То есть это способ руками обрабатывать исключения? Без try/catch ?
Здравствуйте, ononim, Вы писали:
W>>То есть при входе в сопрограмму нужно модифицировать _NT_TIB::StackBase/StackLimit на новый стек, и как-то правильно построить _NT_TIB::ExceptionList? А как мне достучаться к "текущей" _NT_TIB? Я, вообще, не бред говорю? O>Не, не бред. Кстати, может вам нужны fiber'ы? O>На x86 TEB лежит начиная с FS:[0], удобный адрес TEB в селекторе DS мона достать в FS::[18]
Вот это да! Какие, оказывается, дебри можно потянуть из невинной функции __readfsdword! Действительно, если указать правильные _NT_TIB::StackBase/StackLimit до вызова функции SetThreadContext, а также обнулить для нового контекста _NT_TIB::ExceptionList, то все начинает ловиться! Огромное спасибо
Здравствуйте, Went, Вы писали:
W>1. Можно ли как-то "пропатчить" SetThreadContext и GetThreadContext чтобы исключения работали?
Не использовать SetThreadContext, а использовать CreateFiber.
W>2. POSIX-функции getcontext/setcontext/makecontext/swapcontext на Unix-ах дружат с исключениями?
Да
W>3. boost.Coroutines — стоящая вещь? Она делает хорошие портабельные и компактные сопрограммы? Или она тоже работает только в тепличных условиях?
Без поддержки со стороны компилятора сопрограммы в C++ реализовать полностью нельзя. Ну или настолько сложно, что этого никто ещё не сделал.
Типичная проблема как раз связана с обработкой исключений. Например, если оно было выброшено из одной из сопрограмм, то нужно передать его в другие параллельно работающие сопрограммы, завершить часть из них, учесть возможность, что исключение может поймать другая сопрограмма или, если этого не произошло, пробросить исключение в главный поток — это очень сложно без правки компилятора.
Частичная поддержка (без обработки сложных исключений) вполне возможна.
W>4. Сопрограммы вообще могут быть портабельными в пределах Win32-Unix(MacOS)?
С учетом предыдущих оговорок, вполне. У нас используется setcontext для Unix, fibers для Windows и setjmp для других странных платформ.
W>5. А как с мобильными платформами? Android дружит с этим? Он же вроде потомок Unix.
Android же вообще не unix.
Здравствуйте, Went, Вы писали:
W>А разве boost.Coroutines не используют ничего платформеннозависимого? Как они тогда стек двигают?
Только платформозависимое и используют. Для каждой платформы (ОС + компилятор) пишется свой код с ассемблерными вставками и прочими ужасами. Потом при копиляции через define выбирается нужный участок, остальное игнорируется.
Здравствуйте, Went, Вы писали:
W>Здравствуйте, Patalog, Вы писали:
P>>Сделай свой обработчик VEH и диспатчи исключения в нем, поскольку VEH отрабатывает до SEH. W>То есть это способ руками обрабатывать исключения? Без try/catch ?
Нет, это способ их диспатчить, поскольку штатный диспетчер не взлетает, скорее всего по тем причинам, которые озвучил ononim.
Кстати, /nosafeseh пробовал?
Здравствуйте, watch-maker, Вы писали:
WM>Только платформозависимое и используют. Для каждой платформы (ОС + компилятор) пишется свой код с ассемблерными вставками и прочими ужасами. Потом при копиляции через define выбирается нужный участок, остальное игнорируется.
Вот и я про это. Просто мне из прошлого сообщения показалось, что niXman считает, что там нет ничего специфического.
Здравствуйте, watch-maker, Вы писали:
WM>Не использовать SetThreadContext, а использовать CreateFiber.
Ну, вроде помогла "магия" прямой записи в TIB
WM>Да
WM>Частичная поддержка (без обработки сложных исключений) вполне возможна.
Ну, это то что мне нужно.
WM>С учетом предыдущих оговорок, вполне. У нас используется setcontext для Unix, fibers для Windows и setjmp для других странных платформ.
WM>Android же вообще не unix.
Точно, он Linux. Но Linux тоже POSIX, поэтому на нем должны быть setcontext?
Здравствуйте, Went, Вы писали:
W> какие могут быть проблемы? Пока что тестил на Win32
Как минимум отсутствует выравнивание стека. На x86-64 скорее всего упадёт, на x86 выравнивания оказывается достаточно, но, это как бы тоже без гарантий работы.
Здравствуйте, Went, Вы писали:
WM>>Не использовать SetThreadContext, а использовать CreateFiber. W>Ну, вроде помогла "магия" прямой записи в TIB
Жуть, конечно. К чёрту такую магию, fibers куда как лучше
WM>>Android же вообще не unix. W>Точно, он Linux. Но Linux тоже POSIX, поэтому на нем должны быть setcontext?
Не, тут всё не так.
В Android используется ядро Linux, но и только. Оно недоступно извне, да даже до glibc доступа нет.
С таким же успехом можно поставить Windows на VirtualBox на Ubuntu и говорить, что Windows превратилась в unix-систему, — конечно же это не так, ведь из такой установки Windows получить доступ к ядру Linux нельзя, — там непреодалимый барьер, всё закрыто.
Здравствуйте, watch-maker, Вы писали:
WM>Как минимум отсутствует выравнивание стека. На x86-64 скорее всего упадёт, на x86 выравнивания оказывается достаточно, но, это как бы тоже без гарантий работы.
Здравствуйте, Went, Вы писали:
W>Здравствуйте, watch-maker, Вы писали:
WM>>Как минимум отсутствует выравнивание стека. На x86-64 скорее всего упадёт, на x86 выравнивания оказывается достаточно, но, это как бы тоже без гарантий работы.
W>По какому базису его нужно выравнивать?
Зависит от процессора и используемых соглашений о вызове (что в свою очередь зависит от ОС и компилятора). Фактически сейчас достаточно выравнивать на границу 16 байт — это минимум для типичных вызовов в x86-64 и минимум для некоторых вызовов в x86.
Здравствуйте, Went, Вы писали:
W>Здравствуйте. Думаю, вопрос уже немало обсосан, но осмелюсь поднять очередную тему. W>Реализовал сопрограммы используя WinAPI-функции SetThreadContext и GetThreadContext.
Неправильное решение. Используй CreateFiber и SwitchToFiber
W>1. Можно ли как-то "пропатчить" SetThreadContext и GetThreadContext чтобы исключения работали?
Для решения "CreateFiber" это не нужно — для SEH (и исключений MSVC) все будет работать "из коробки".
Единственное, что категорически не рекомендуется — это выпускать исключение из сопрограммы. То есть, функция сопрограммы толжна быть завернута в "try{}catch(...){/*ничего*/}"
W>2. POSIX-функции getcontext/setcontext/makecontext/swapcontext на Unix-ах дружат с исключениями? Или вообще такой подход нежизнеспособен?
Дружат, точнее DWARF-исключениям на них пофигу. А для SjLj-исключений (но это устаревшая архаика) придется малеха похачить.
W>3. boost.Coroutines — стоящая вещь? Она делает хорошие портабельные и компактные сопрограммы? Или она тоже работает только в тепличных условиях?
Не знаю.
W>4. Сопрограммы вообще могут быть портабельными в пределах Win32-Unix(MacOS)?
Да. Я реализовал достаточно мелкий класс для работы с сопрограммами. Работает на юнихах через setcontext, на выни — через CreateFiber. Исключения везде работают (даже SjLj, но это больше из любви к искусству).
W>5. А как с мобильными платформами? Android дружит с этим? Он же вроде потомок Unix. А iOS?
На андроиде — Жаба. Если хочется нативщины (и геморроя), то линух. То есть, setcontext должон работать.
__________
16.There is no cause so right that one cannot find a fool following it.