Перекрестная исключительная ситуация - PullRequest
0 голосов
/ 15 января 2009

У меня есть приложение, которое позволяет пользователям писать свой собственный код на собственном языке, похожем на C ++. Однако у нас возникают проблемы, когда иногда наши пользователи случайно записывают бесконечный цикл в свой скрипт. Как только скрипт попадает в бесконечный цикл, единственный выход, который они могут получить, - это закрыть приложение и перезапустить, что может привести к потере работы. Я хотел бы добавить некоторые средства, где пользователь, когда он понимает, что его код находится в бесконечном цикле, может нажать специальную клавишу, например, F10 или что-то еще, и код выйдет из цикла. Но я хотел бы сделать это, не применяя тонну проверок во время выполнения скрипта. Оптимально, я хотел бы иметь отдельный поток «отладчик», который в основном бездействует, но в качестве одной из своих задач он прослушивает этот ключ F10, а когда он получает ключ F10, он заставит поток времени выполнения сценария генерировать исключение , чтобы он прекратил выполнение скрипта. Итак, мой вопрос, есть ли способ заставить один поток вызвать другой поток исключения? Мое приложение написано на C ++.

Ответы [ 6 ]

2 голосов
/ 15 января 2009

Если скрипт действительно интерпретируется вашим приложением, тогда вы можете просто сказать интерпретатору прекратить выполнение при возникновении какого-либо пользовательского события.

1 голос
/ 16 января 2009

Это возможно. Определите нажатие клавиши в отдельном потоке, например, в скрытом окне и WM_HOTKEY. Вызовите SuspendThread (), чтобы заморозить поток интерпретатора. Теперь используйте GetThreadContext (), чтобы получить регистры процессора потока интерпретатора. Измените CONTEXT.Eip по адресу функции и вызовите SetThreadContext (). Пусть эта функция вызовет RaiseException () или вызовет исключение C ++. ResumeThread () и boom.

0 голосов
/ 23 января 2009

Независимо от того, кодируете ли вы это явно или нет, вам потребуется проверить переменную «прерывание» в цикле сообщений. Если вы реализуете это простым volatile int, у вас будет очень простой тест и очень небольшие накладные расходы.

0 голосов
/ 15 января 2009

Прекращение потока небезопасно, так как он, вероятно, использует ресурсы, общие для всего процесса.

Менее небезопасно завершать весь процесс, но это вам не поможет.

Более безопасный способ справиться с этим состоит в том, чтобы интерпретатор регулярно проверял наличие событий и рассматривал событие остановки как случай завершения (или, по крайней мере, выливания в более высокий цикл).

Для окон вы также можете поставить APC в очередь к тому потоку, который вызывает RaiseException(...) или выдает исключение (хотя я бы избегал последнего, так как это пересекает границы API), но это также подразумевает, что поток будет помещен в состояние тревоги. И я не очень рекомендую это.

0 голосов
/ 15 января 2009

Проблема с этим решением заключается в том, что для реализации реализации отправки сообщений мне потребуется настроить «слушатель» как часть интерпретатора сценария. Прямо сейчас интерпретатор просто выполняет функцию. Цикл сообщений реализован вне интерпретатора. Если внутри функции есть бесконечный цикл, то, чтобы выйти из этого скрипта, мне нужно было бы проверить сообщение между выполнением каждой инструкции в интерпретаторе, то есть while (дополнительные инструкции) {проверить F10, выполнить инструкцию скрипта }. Это похоже на множество лишних ненужных проверок, которые могут замедлить выполнение скрипта. Но если это единственное решение, то, наверное, так оно и должно быть. Я все еще думаю, что должен быть лучший способ. Возможно, интерпретатор сценариев должен быть запущен в дочернем потоке, в то время как основной поток продолжает цикл обработки сообщений и затем уничтожает поток интерпретатора сценариев, когда получает F10.

0 голосов
/ 15 января 2009

Короткий ответ - нет.

Если ваше приложение работает в Windows, может быть, вы можете отправить сообщение из этого шага «отладчик» и иметь цикл сообщений в основном?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...