Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, MaximE, Вы писали:
>>> ME>Вывод из этого следующий: ты просто не можешь прервать выполнение любого потока в произвольной точке и перевести управление при помощи исключения в другую точку, ожидая при этом, что состояние структур данных сохранит инвариант и останется в каком-либо относительно корректном состоянии.
К>Давайте вспомним исходную задачу: К>Ведомый поток зависает в какой-то системной функции. Хочется вышибить его оттуда наименее болезненным способом. К>TerminateThread() (или даже exit()) — заведомо худший вариант.
Если исходный поток "зависает" в какой-то системной функции, то таким макаром его нельзя вышибить (во всяком
случае в винде). Все дело в том, что такой поток исключается из очереди готовности (ready queue) и переводится
в waiting queue. Обратно он будет переведен, только после того, как сработает соотв. ожидаемый объект, или истечет
время заданное sleep'ом.
Так что реальное использование такой методы очень сомнительно и небезопасно.
ЗЫ
Проверил на Sleep'е — исключение возникает только после истечения соотв. времени ожидания...
On Fri, 03 Jun 2005 16:34:53 +0400, adontz <2053@users.rsdn.ru> wrote:
> Решение судя по всему кросс-компиляторное. > Что кинуть исключение в другом потоке (и вообще как метод одноразовой передачи сообщения потоку)
[]
> Мне такое удобно делать, чтоб остановить поток слушающий сокет, потому что message-queue там нету и по-другому сообщение не передать.
Куря кольян, на меня снизошло понимание: брошенное таким способом исключение разрушает любой код, включая код с гарантиями strong exception safety и nothrow. Этот метод нельзя использовать никогда, когда предполагается восстановление и продолжение работы после обработки исключения.
Код с гарантиями strong exception safety и nothrow и весь код на С полагается на операции, которые гарантировано не бросают исключений, такие, как, например, многие простые операции над встроенными типами.
Рассмотрим операцию вставки в двусвязанный список. Эта операция является nothrow (конечно при условии, что указатели валидны).
Для валидного списка, этот код всегда исполняется от начала до конца, т.к. операции присвоения для валидных указателей никогда не могут бросить исключения.
Если в поток, выполняющий этот код, пробросить исключение предлагаемым варварским методом в тот момент, когда была выполнена строка (*), но не была еще выполнена следующая строка, список будет разрушен. Чтобы этот код сохранил свойство nothrow при таких новых условиях, когда исключение может возникнуть в любой момент из ниоткуда "на ровном месте", возможно необходимо либо каждую строку обернуть в __try / __except конструкцию, либо, возможно, исполнять весь код в блоке __finally (я не спец в SEH). Никто, естественно, в здравом уме этого делать не будет. Примеры подобного кода можно приводить бесконечно.
Вывод из этого следующий: ты просто не можешь прервать выполнение любого потока в произвольной точке и перевести управление при помощи исключения в другую точку, ожидая при этом, что состояние структур данных сохранит инвариант и останется в каком-либо относительно корректном состоянии.
Да, поначалу выглядит круто порулить руками регистрами и наебать остальной код и компилятор, но if you lie to the compiler, it will take its revenge...
AS>>>Гм, вообще то такие вещи можно делать при помощи APC. С блокирующими сокетами вполне работает на всей линейке вин32.
SH>>Т.е. пока поток ждёт в recv, он находится в алертабельном состоянии? Интересно. Это где-нибудь описано?
AS>Да. http://gzip.rsdn.ru/Forum/Message.aspx?mid=1213466&only=1
Извиняюсь, что поднимаю древнюю тему, но, возможно, народу будет интересно узнать ответ на столь животрепещущий вопрос...
Итак, оказывается, это вполне документировано, но как обычно, размазано по нескольким частям msdn. Для затравки смотрим http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/sol_socket_socket_options.asp
опция SO_OPENTYPE.
#define SO_SYNCHRONOUS_ALERT 0x10
#define SO_SYNCHRONOUS_NONALERT 0x20
При создании сокета при помощи socket по умолчанию задается режим overlapped\alert (== 0), все остальные приведены выше. Изменить можно при помощи setsockopt, либо создавая сокет при помощи WSASocket. Т.о. описываемое выше поведение сокета является официально документированым, а, следовательно, его использование не только вполне безопасно, но и даже очень полезно.
Здравствуйте, SergH, Вы писали:
SH>Честно говоря, я вообще не очень хорошо представляю, как происходит обработка C++-ных исключений. Буду рад, если ты мне объяснишь.
Объясню как это делается в Microsoft Visual C++ начиная с версии 6 (может и раньше так же работало, но я не проверял)
Оператор try заменятся на засылку по адресу FS:[00000000] адреса таблицы соответсвия тип<->catch block (всё несколько сложнее, но по сути так)
Оператор throw инициирует простотр таблицы соответствия находящейся по адресу FS:[00000000] и если найдён соответствующий блок обработки то управление передайтся ему (всё несколько сложнее, но по сути так)
Оператору throw совершенно плевать откуда он вызвался если по адресу FS:[00000000] корректная таблица
Адреса деструкторов локальных объектов храниться рядом с таблицей соответсвия (которая по адресу FS:[00000000])
Таким образом вызов деструкторов и нужного блока catch выполняется вне зависимости от того откуда вызван throw.
adontz wrote:
> Решение судя по всему кросс-компиляторное.
Представь, что когда ты останавливаешь поток, в которой ты хочешь прокинуть исключение, этот поток находится в коде, скомпилированном с синхронной моделью обработки исключений, или в ф-ции third-party С библиотеки или в С/С++ runtime (malloc, к примеру). Тот код не ожидает исключения и не сможет его обработать, оставив структуры данных в рассогласованном состоянии...
Здравствуйте, Сергей Мухин, Вы писали:
СМ>да, интерсно. при этом фраза "замечательно рабатют" не очень понятня. Т.е. пацан отвечает что это будет работать и в моем проекте на С++?
Замечательно означает, что в отличие от, например, этих исходников The Code Project: How a C++ compiler implements exception handling
мои не тянут STL и работают не только при синхронной (/EHs), но и при асинхронной (/EHa) обработке исключений (/EHa — позволяет в catch ловить аппаратные исключения) Исходники
Они нагло выдраны, но надеюсь что чтобы заставить это всё скомпилироваться особо мучаться не придёться.
Если будут вопросы — пишите, хотя я уже и не очень хорошо помню как всё работает.
Hit! Типы для RTTI и обработки исключений нигде не описаны, но компилятор о них знает (как будто они встроенные), а отладчик показывает (в окне Watch)
А если серьезно — то официального описания этого бехавира я не встречал. Но тем не менее, apc вполне работают с блокирующими сокетами, причем, я практически уверен, что сокеты блокируются в alertable wait state специально (причем делается это явно в цикле, поскольку после выполнения apc вайт функция возвращается, надо проверить значение возврата и ждать наново). Поднимать исходники думаю смысла нет — скорее всего, найдем нечто вроде цикла с WaitForSingleObjectEx.
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, RST_Angellab, Вы писали:
RST>>А если попробовать QueueUserAPC? Вроде бы более гуманный способ, чем кидать эксепшен.
A>В объекте исключения можно много информанции удобно передать. A>Буду думать как подготовить целевой поток...
единственные данные, которые имхо нужно передавать — это укзатель. Все остальное в структуре, на которую этот указатель ссылается.
Последний параметра в QueueuserAPC как раз для этого и предназначен.
В дополнение могу сказать следующее : если код повис (ждет) в ведре, к примеру на Sleep, или на WaitForSingleObject, то suspendthread возможно обломается. Т.к. MSDN гласит :
[quote]
If the function succeeds, execution of the specified thread is suspended and the thread's suspend count is incremented. Suspending a thread causes the thread to stop executing user-mode (application) code.
[/quote]
Т.е. оно работает только для юзермода.
А сокеты уходят в ведро (если не ошибаюсь).
Всякие wait на пайпах тоже туда уходят.
Здравствуйте, MaximE, Вы писали:
ME>Представь, что когда ты останавливаешь поток, в которой ты хочешь прокинуть исключение, этот поток находится в коде, скомпилированном с синхронной моделью обработки исключений, или в ф-ции third-party С библиотеки или в С/С++ runtime (malloc, к примеру). Тот код не ожидает исключения и не сможет его обработать, оставив структуры данных в рассогласованном состоянии...
Насколько я знаю, такой код допустим:
int third_party_c_function(int (* mycallback)())
{
return mycallback();
}
int func()
{
throw some(123);
}
int main()
{
try
{
third_party_c_function(func);
}
catch (some& s)
{
}
}
SergH wrote:
> Здравствуйте, MaximE, Вы писали: > > ME>Представь, что когда ты останавливаешь поток, в которой ты хочешь прокинуть исключение, этот поток находится в коде, скомпилированном с синхронной моделью обработки исключений, или в ф-ции third-party С библиотеки или в С/С++ runtime (malloc, к примеру). Тот код не ожидает исключения и не сможет его обработать, оставив структуры данных в рассогласованном состоянии... > > Насколько я знаю, такой код допустим:
[]
> Поэтому, имхо, ты не прав.
Тогда расскажи мне, как С-шный код, например код malloc, обработает не весть откуда взявшеесе С++ исключение, откатив все сделанные к этому моменту действия?
Другими словами, чтобы этот код работал и сохранял прогу в определенном состаянии (инвариант), нужно, чтобы весь код, который использует твоя прога, обеспечивал strong exception safety. Чтобы далеко не ходить, можно попробовать отыскать такой код в С — runtime твоего компилятора...
adontz wrote:
> ME>Представь, что когда ты останавливаешь поток, в которой ты хочешь прокинуть исключение, этот поток находится в коде, скомпилированном с синхронной моделью обработки исключений, или в ф-ции third-party С библиотеки или в С/С++ runtime (malloc, к примеру). Тот код не ожидает исключения и не сможет его обработать, оставив структуры данных в рассогласованном состоянии... > > А ещё может быть, что код в том потоке вообще дельфийский и Си++ исключения ловить не умеет. > Конечно этот механизм надо применять с осторожностью, но это не делает его менее применимым.
На мой взгляд он вообще неприменим.
Повторюсь еще раз, что практически любая С++ программа использует в user mode C и С++ код, который не может восстанавливаться после исключений — С и С++ рантайм. Чтобы бросить твоим способом исключение, необходимо гарантировать, что в момент его выстрела, не выполняется такой "небезопасный" с точки зрения исключений код. Это можно гарантировать, но реализации, на мой взгляд, будет слишком сложна, чтобы быть надежной.
Я не вижу, как можно использовать этот код с гарантированно предсказуемым результатом.
AS>>Гм, вообще то такие вещи можно делать при помощи APC. С блокирующими сокетами вполне работает на всей линейке вин32.
SH>Т.е. пока поток ждёт в recv, он находится в алертабельном состоянии? Интересно. Это где-нибудь описано?
Здравствуйте, adontz, Вы писали:
A>Решение судя по всему кросс-компиляторное. A>Что кинуть исключение в другом потоке (и вообще как метод одноразовой передачи сообщения потоку) A>
A>template <typename _type_exception>
A>void _throw_remote_proc(_type_exception * exception_object)
A>{
A> throw exception_object;
A>}
A>//
A>template <typename _type_exception>
A>__declspec(noreturn) void throw_remote(DWORD thread_id, _type_exception * exception_object)
A>{
A> HANDLE hThread = OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, FALSE, thread_id);
A> SuspendThread(hThread);
A> CONTEXT context;
A> ZeroMemory(&context, sizeof(context));
A> context.ContextFlags = CONTEXT_CONTROL;
A> GetThreadContext(hThread, &context);
A> context.Eip = (DWORD)((void(*)(_type_exception *))&_throw_remote_proc<_type_exception>);
A> *((DWORD *)context.Esp) = (DWORD)exception_object;
A> context.Esp -= 4;
A> SetThreadContext(hThread, &context);
A> ResumeThread(hThread);
A> CloseHandle(hThread);
A>}
A>
Имхо, выделенные строчки надо поменять местами. ESP указывает на последнее пристутствующее в стеке слово, а не на первое отсутствующее.
Здравствуйте, MaximE, Вы писали:
ME>Представь, что когда ты останавливаешь поток, в которой ты хочешь прокинуть исключение, этот поток находится в коде, скомпилированном с синхронной моделью обработки исключений, или в ф-ции third-party С библиотеки или в С/С++ runtime (malloc, к примеру). Тот код не ожидает исключения и не сможет его обработать, оставив структуры данных в рассогласованном состоянии...
А ещё может быть, что код в том потоке вообще дельфийский и Си++ исключения ловить не умеет.
Конечно этот механизм надо применять с осторожностью, но это не делает его менее применимым.
Здравствуйте, SergH, Вы писали:
SH>Имхо, выделенные строчки надо поменять местами. ESP указывает на последнее пристутствующее в стеке слово, а не на первое отсутствующее.
Там ещё должен быть адрес возвращения из функции _throw_remote_proc, но так как из неё не возвращаются, то и адрес я не указываю.
Кстати __declspec(noreturn) я получается не туда поставил throw_remote как раз возвращает управления в отличие от простого throw.
Здравствуйте, MaximE, Вы писали:
ME>Тогда расскажи мне, как С-шный код, например код malloc, обработает не весть откуда взявшеесе С++ исключение, откатив все сделанные к этому моменту действия?
Честно говоря, я вообще не очень хорошо представляю, как происходит обработка C++-ных исключений. Буду рад, если ты мне объяснишь. Или ссылку дашь.. Мои аргументы по анологии с SEH: для того чтобы обрабатывать SEH от кода не требуется ничего, любой справится. Если с C++ не так — объясни.
A>Мне такое удобно делать, чтоб остановить поток слушающий сокет, потому что message-queue там нету и по-другому сообщение не передать.
А порт завершения ввода вывода — не поможет ?
Во-первых: __declspec(noreturn) убери и поставь у _throw_remote_proc (уже писал об этом, извини перепутал)
Во-вторых: accept судя по всему использует что-то вроже WaitForSingleObject, потому что если вызов accept заменить на for(;;Sleep(1)); то всё работает.
Если кто-то знает как вывести поток из состояния ожижания буду благодарен.
Здравствуйте, MaximE, Вы писали:
ME>Куря кольян, на меня снизошло понимание: брошенное таким способом исключение разрушает любой код, включая код с гарантиями strong exception safety и nothrow. Этот метод нельзя использовать никогда, когда предполагается восстановление и продолжение работы после обработки исключения.
Интересно как ты себе представляешь продолжение работы после программного исключения?
ME>Код с гарантиями strong exception safety и nothrow и весь код на С полагается на операции, которые гарантировано не бросают исключений, такие, как, например, многие простые операции над встроенными типами.
Предположим, что так.
ME>Рассмотрим операцию вставки в двусвязанный список. Эта операция является nothrow (конечно при условии, что указатели валидны).
Замечательно.
ME>Для валидного списка, этот код всегда исполняется от начала до конца, т.к. операции присвоения для валидных указателей никогда не могут бросить исключения.
Чудесно!
ME>Если в поток, выполняющий этот код, пробросить исключение предлагаемым варварским методом в тот момент, когда была выполнена строка (*), но не была еще выполнена следующая строка, список будет разрушен.
А вот отсюда уже не верно. С какой стати он будет разрушен? Квадратики и стрелки на салфетке рисовал? После выполнения указанной строки весь список от начала и до конца можно проглядеть имея указатель head. Да, return не выполнился, ну и что? Что при этом мешает корректно отработать деструкторам?
ME>Вывод из этого следующий: ты просто не можешь прервать выполнение любого потока в произвольной точке и перевести управление при помощи исключения в другую точку, ожидая при этом, что состояние структур данных сохранит инвариант и останется в каком-либо относительно корректном состоянии.
Во-первых, могу. Во-вторых, могу не только я. Требования такие же как и у Multiple Readers — Single Writer многопоточных структур. В частности весь STLPort будет на это нормально реагировать.
On Sat, 04 Jun 2005 03:35:16 +0400, adontz <2053@users.rsdn.ru> wrote:
[]
> ME>Если в поток, выполняющий этот код, пробросить исключение предлагаемым варварским методом в тот момент, когда была выполнена строка (*), но не была еще выполнена следующая строка, список будет разрушен. > > А вот отсюда уже не верно. С какой стати он будет разрушен? Квадратики и стрелки на салфетке рисовал? После выполнения указанной строки весь список от начала и до конца можно проглядеть имея указатель head. Да, return не выполнился, ну и что? Что при этом мешает корректно отработать деструкторам?
Ты потерял меня: список разрушен.
> ME>Вывод из этого следующий: ты просто не можешь прервать выполнение любого потока в произвольной точке и перевести управление при помощи исключения в другую точку, ожидая при этом, что состояние структур данных сохранит инвариант и останется в каком-либо относительно корректном состоянии. > > Во-первых, могу. Во-вторых, могу не только я. Требования такие же как и у Multiple Readers — Single Writer многопоточных структур. В частности весь STLPort будет на это нормально реагировать.
Элементарно показать, что контейнеры из STLPort не смогут оправиться после таких исключений.
Здравствуйте, MaximE, Вы писали:
>> ME>Вывод из этого следующий: ты просто не можешь прервать выполнение любого потока в произвольной точке и перевести управление при помощи исключения в другую точку, ожидая при этом, что состояние структур данных сохранит инвариант и останется в каком-либо относительно корректном состоянии.
Давайте вспомним исходную задачу:
Ведомый поток зависает в какой-то системной функции. Хочется вышибить его оттуда наименее болезненным способом.
TerminateThread() (или даже exit()) — заведомо худший вариант.
Если есть штатные рукоятки для экстренного завершения операции — таймауты, альтернативы (select(), WaitForMultipleObjects()), сигналы — то лучше пользоваться ими: мало ли, какие ритуалы и протоколы соблюдаются внутри вызова функции. Но за неимением, или если есть железная уверенность в безопасности данного конкретного кода — то почему бы и не подкинуть исключение?
On Sat, 04 Jun 2005 13:06:12 +0400, Кодт <4783@users.rsdn.ru> wrote:
> Здравствуйте, MaximE, Вы писали: > >>> ME>Вывод из этого следующий: ты просто не можешь прервать выполнение любого потока в произвольной точке и перевести управление при помощи исключения в другую точку, ожидая при этом, что состояние структур данных сохранит инвариант и останется в каком-либо относительно корректном состоянии. > > Давайте вспомним исходную задачу: > Ведомый поток зависает в какой-то системной функции. Хочется вышибить его оттуда наименее болезненным способом.
Как ты из другого потока определишь, что поток заблокирован в системной ф-ции в частности или что сейчас безопасно пробросить в другой поток асинхронное исключение в общем?
Такое решение приведет к UB не только в случае вызова исключения в системеной функции.
Рассмотрим такой код:
class A
{
A();
~A();
};
voif F()
{
A a;
....
}
Предположим, исключение будет перекито в этот поток тогда, когда идет выполнение ....
Предположим, компилятор смог определить, что в .... не кидаются исключения. Тогда не будет сформирован код, гарантирующий вызов декструктора. Впрочем, MaximE уже привел пример со списком. Компилятор ожидает ожидает исключения от throw, а не между произвольными ассемлерными командами.
И вообще, где гаранития, что это хак с подменой eip будет всегда работать корректно?
Правильно работающая программа — просто частный случай Undefined Behavior
FRED, у меня между прочим есть исходники реализации обработки Си++ исключений. Правда, не спёртые МСные, а свои, но работают замечательно. В любом случае они получены дизассемблированием и медитацией так что от МСных наверное мало отличаются.
Здравствуйте, adontz, Вы писали:
A>FRED, у меня между прочим есть исходники реализации обработки Си++ исключений. Правда, не спёртые МСные, а свои, но работают замечательно. В любом случае они получены дизассемблированием и медитацией так что от МСных наверное мало отличаются.
С интересом бы ознакомился , например здесь (e-mail), или любым другим образом!
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, adontz, Вы писали:
A>>FRED, у меня между прочим есть исходники реализации обработки Си++ исключений. Правда, не спёртые МСные, а свои, но работают замечательно. В любом случае они получены дизассемблированием и медитацией так что от МСных наверное мало отличаются.
да, интерсно. при этом фраза "замечательно рабатют" не очень понятня. Т.е. пацан отвечает что это будет работать и в моем проекте на С++ ?
Здравствуйте, Сергей Мухин, Вы писали:
A>>>FRED, у меня между прочим есть исходники реализации обработки Си++ исключений. Правда, не спёртые МСные, а свои, но работают замечательно. В любом случае они получены дизассемблированием и медитацией так что от МСных наверное мало отличаются. СМ>да, интерсно. при этом фраза "замечательно рабатют" не очень понятня. Т.е. пацан отвечает что это будет работать и в моем проекте на С++ ?
Ну зачем же так строго Однако проверка действительно пойдёт на пользу
under «Metallica — Mama Said»,
... << RSDN@Home 1.1.4 beta 7 rev. 462>>
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, Сергей Мухин, Вы писали:
A>>>>FRED, у меня между прочим есть исходники реализации обработки Си++ исключений. Правда, не спёртые МСные, а свои, но работают замечательно. В любом случае они получены дизассемблированием и медитацией так что от МСных наверное мало отличаются. СМ>>да, интерсно. при этом фраза "замечательно рабатют" не очень понятня. Т.е. пацан отвечает что это будет работать и в моем проекте на С++ ?
_FR>Ну зачем же так строго Однако проверка действительно пойдёт на пользу
ну да. вот я например сам все обрабатываю (исключения), без seh. но у меня задача такая. и убиваю (а куда деться) практически так. но я никогда не посоветую делать так другим! да это работает. но, надо отдавать себе отчет, что иногда это не сработает.
я то после этого всеравно закрываю, все. а вот например посадка самолета. кто полетит на нем, если его управление так написано. увольте! так что для студентов это сойдет, для реальных — ну это на вашей совести.
Здравствуйте, Сергей Мухин, Вы писали: A>>>>>FRED, у меня между прочим есть исходники реализации обработки Си++ исключений. Правда, не спёртые МСные, а свои, но работают замечательно. В любом случае они получены дизассемблированием и медитацией так что от МСных наверное мало отличаются. СМ>>>да, интерсно. при этом фраза "замечательно рабатют" не очень понятня. Т.е. пацан отвечает что это будет работать и в моем проекте на С++ ? _FR>>Ну зачем же так строго Однако проверка действительно пойдёт на пользу
СМ>ну да. вот я например сам все обрабатываю (исключения), без seh. но у меня задача такая. и убиваю (а куда деться) практически так. но я никогда не посоветую делать так другим! да это работает. но, надо отдавать себе отчет, что иногда это не сработает. СМ>я то после этого всеравно закрываю, все.
Что Вы имеете в виду? Я просто не могу представить как эти термины выглядят в коде .
сам все обрабатываю — значит ловите все исключения? и убиваю — удаляете объекты исключений?? после этого всеравно закрываю —
СМ>а вот например посадка самолета. кто полетит на нем, если его управление так написано. увольте! так что для студентов это сойдет, для реальных — ну это на вашей совести.
Да, у меня интерес сугубо академический. Пытаюсь расширить кругозор и вооружиться на будущее.
under «*none*»,
... << RSDN@Home 1.1.4 beta 7 rev. 462>>
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, Сергей Мухин, Вы писали:
СМ>>да, интерсно. при этом фраза "замечательно рабатют" не очень понятня. Т.е. пацан отвечает что это будет работать и в моем проекте на С++?
A>Замечательно означает, что в отличие от, например, этих исходников A>The Code Project: How a C++ compiler implements exception handling A>мои не тянут STL и работают не только при синхронной (/EHs), но и при асинхронной (/EHa) обработке исключений (/EHa — позволяет в catch ловить аппаратные исключения) A>Исходники A>Они нагло выдраны, но надеюсь что чтобы заставить это всё скомпилироваться особо мучаться не придёться. A>Если будут вопросы — пишите, хотя я уже и не очень хорошо помню как всё работает. A>Hit! Типы для RTTI и обработки исключений нигде не описаны, но компилятор о них знает (как будто они встроенные), а отладчик показывает (в окне Watch)
как они относятся к фиберам? какимим исходниками пользовались 7 или 7.1 там разница есть
Здравствуйте, _FRED_, Вы писали:
_FR> Что Вы имеете в виду? Я просто не могу представить как эти термины выглядят в коде . _FR>
_FR>сам все обрабатываю — значит ловите все исключения?
да UnexceptionHandler
_FR>и убиваю — удаляете объекты исключений??
ну конечно не объекты. я про и слово такое не прозносид. убиваб thread
_FR>после этого всеравно закрываю —
_FR>
мб это трудно представить, у нас тут свой язык, со своей поддержкой. и без seh (хотя планируется и это). и ошибки обрабатываем. вот только две проблемы. thread (ну тут мы пытаемся сказать, что кто запустил, тот пусть и останавливает). и ctrl+c для консольных. тут система свой thread создат, а мы с него пытаемся остановить пользовательский. пока никто не жаловался. но мы то знам, что вовремя нажатый клавишь приводит к """cenzored@@@
СМ>>а вот например посадка самолета. кто полетит на нем, если его управление так написано. увольте! так что для студентов это сойдет, для реальных — ну это на вашей совести.
_FR>Да, у меня интерес сугубо академический. Пытаюсь расширить кругозор и вооружиться на будущее.
а что тут академического. обычный программистский разговор. программа работать будет, сдать заказчику ее можно, но если она вылетит в момент посадки самолета (читай переключния подстанции (для москвичей)), то что? совесть не будет мучать?
Да уж , простым чтением-запуском там не обойтись, на первый взгляд подчти вся логика в __asm {...}
A>Они нагло выдраны, но надеюсь что чтобы заставить это всё скомпилироваться особо мучаться не придёться. A>Если будут вопросы — пишите, хотя я уже и не очень хорошо помню как всё работает.
Закачал с сайта всю библиотеку (здесь) (некоторых хидеров не хватало), буду разбираться.
under «*none*»,
... << RSDN@Home 1.1.4 beta 7 rev. 462>>
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Да уж , простым чтением-запуском там не обойтись, на первый взгляд подчти вся логика в __asm {...}
На самом деле там просто много параметров в регистрах передаётся, на Си такое не обработать.
_FR>Закачал с сайта всю библиотеку (здесь) (некоторых хидеров не хватало), буду разбираться.
Это зря. Там позапрошлогодняя версия. Лучше я на почту новую скину.
Здравствуйте, Сергей Мухин, Вы писали:
СМ>как они относятся к фиберам?
Если честно, то без понятия. Там используется TLS, а не FLS там что могут быть проблемы при одновремнном кидании исключений (А могут и не быть, я в фиберах не силён). Зато вместо _beginthread можно CreateThread использовать.
СМ>какимим исходниками пользовались 7 или 7.1 там разница есть
[...прочитано...]
СМ>>>а вот например посадка самолета. кто полетит на нем, если его управление так написано. увольте! так что для студентов это сойдет, для реальных — ну это на вашей совести.
_FR>>Да, у меня интерес сугубо академический. Пытаюсь расширить кругозор и вооружиться на будущее.
СМ>а что тут академического. обычный программистский разговор. программа работать будет, сдать заказчику ее можно, но [...]
"Это не наш метод" (с)
СМ>если она вылетит в момент посадки самолета (читай переключния подстанции (для москвичей)), то что? совесть не будет мучать?
Конечно, будет, но, имхо, для _изучения_ полезно и то, что при некоторых, даже заранее известных, условиях не работет, потому что зачастую в таких проектах отдельные компоненты реализованы... как-то... интереснее что ли, чем в хорошо проверенной "железной" (если такие есть ) библитотеке и "оно" заставляет придаваться мечтам или дискуссиям о вкусной панацее.
under «*none*»,
... << RSDN@Home 1.1.4 beta 7 rev. 462>>
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Да уж , простым чтением-запуском там не обойтись, на первый взгляд подчти вся логика в __asm {...}
Чтоб отлаживаться (поглядеть что да как) поставь точку останова внутри __CxxFrameHandler (run to cursor не делай, исключения обрабатываются с заходом в kernel32 и не все методы отладки работают) кинь исключение и смотри что будет.
Вся логика в __CxxFrameHandlerInternal
А если попробовать вместо C++ исключений использовать SEH с кодом EXCEPTION_CONTINUE_EXECUTION ?
void _throw_remote_proc(DWORD nNumberOfArgs, const ULONG_PTR* args)
{
RaiseException(MY_REMOTE_EX_CODE, 0, nNumberOfArgs, args); // exception
}
// ........class ex
{
public:
int data;
public:
ex(): data(0)
{
}
ex(int _data): data(_data)
{
}
};
//bool ready = false;
//int ex_handler(int current_thread_state)
{
if (GetExceptionCode() == MY_REMOTE_EX_CODE)
{
LPEXCEPTION_POINTERS pp = GetExceptionInformation();
....
// report the thread state using `current_thread_state`
...
return EXCEPTION_CONTINUE_EXECUTION;
}
else
return EXCEPTION_CONTINIUE_SEARCH;
}
DWORD CALLBACK ThreadProc(LPVOID lpParam)
{
ready = true;
int current_thread_state = 0;__try
{
for(;)
{
current_thread_state++;
Sleep(1);
}
}
__catch (ex_handler(current_thread_state))
{
// Сюда никогда не попадаем
}
ready = true;
return 0;
}
//int main(int argc, char * argv[])
{
DWORD thread_id;
CloseHandle(CreateThread(NULL, 0, ThreadProc, NULL, 0, &thread_id));
while (!ready)
{
Sleep(1);
}
ex * e = new ex(10);
ready = false;
throw_remote(thread_id, e);
while (!ready)
{
Sleep(1);
}
return 0;
}
Раскритикуйте и это плиз.
По-моему этот вариант должен работать всегда кроме случаев когда поток уже находится в состоянии обработки SEH исключения.
Но эти куски кода можно защитить обернув блоки в которых можно кидать исключения "извне" критической секцией.
Здравствуйте, adontz, Вы писали:
A>Решение судя по всему кросс-компиляторное.
И определенно не кросс-платформенное. А надежное и кросс-платформенное, в том числе и кросс-компиляторное, решение предложил MaximE: Re: Межпотоковое кидание исключений
Здравствуйте, Andrew S, Вы писали:
AS>Гм, вообще то такие вещи можно делать при помощи APC. С блокирующими сокетами вполне работает на всей линейке вин32.
Т.е. пока поток ждёт в recv, он находится в алертабельном состоянии? Интересно. Это где-нибудь описано?
Здравствуйте, Andrew S, Вы писали:
AS>Извиняюсь, что поднимаю древнюю тему, но, возможно, народу будет интересно узнать ответ на столь животрепещущий вопрос...