У меня есть серверное приложение, которое в своем процессе запускает внешние объекты (plugin), загружаемые из dll. Внещний код выполняется в одном из рабочих потоков сервера. Необходимо защитить сервер от ошибок, которые могут быть в плагинах. Самая первая идея, которая пришла мне в голову — обернуть вызов внешнего кода в блок обработки исключений try-catch или __try-except .
Я столкнулся с кодом, который убивает приложение, но не отлавливается обработкой исключений. Вот пример такого кода:
Т.к. в строке параметров функции _vstprintf_s количество ожидаемых параметров превышает количество реально передаваемых — вываливается ошибка, которая не отлавливается ни __try — __except, ни try-catch, программа умирает .
Вопрос:
1) Как отловить такую ошибку или защитить приложение от таких ошибок ?
2) Как лучше реализовать защиту приложения от ошибок во внешнем коде ?
Приходит в голову вариант с созданием внешнего процесса, в кот. выполнять код (так, чтобы если внешний код убивает приложение, то вываливался бы только процесс-хостер внешнего кода), и организацией межпроцессного взаимодейтсвия, но этот путь видится мне достаточно трудоемким и непростым в реализации.
Спасибо,
Armastab.
Re: Не перехватывается ошибка(как сделать устойч. приложение
Здравствуйте, Armastab, Вы писали:
A>Вопрос: A>1) Как отловить такую ошибку или защитить приложение от таких ошибок ? A>2) Как лучше реализовать защиту приложения от ошибок во внешнем коде ? A>Приходит в голову вариант с созданием внешнего процесса, в кот. выполнять код (так, чтобы если внешний код убивает приложение, то вываливался бы только процесс-хостер внешнего кода), и организацией межпроцессного взаимодейтсвия, но этот путь видится мне достаточно трудоемким и непростым в реализации.
Единственный работающий вариант — это вынесение в отдельный процесс.
По поводу перехвата ошибок. Под виндой тебе надо поставить как минимум десяток обработчиков различных ошибок — это ошибки С райнтайма, С++ рантайма и ОС. Плюс надо перехватывать TerminateProcess(), т.к. некоторые кртешные функции любят без предупреждения вызывать TerminateProcess().
Вот примерный список того, что тебе надо перехватывать:
Win32:
SetThreadStackGuarantee()
SetUnhandledExceptionFilter()
TerminateProcess()
CRT:
signal(SIGABRT);
_set_security_error_handler() // если есть
_set_invalid_parameter_handler()
_set_error_mode(_OUT_TO_STDERR);
_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
Здравствуйте, Armastab, Вы писали:
A>А вот еще интересно, как разные веб-сервера от кривых cgi-скриптов защищаются, или они их во внешних процессах запускают?
Ну собственно интерфейс CGI скриптов и подразумевает, что они запускаются в отдельных процессах.
Здравствуйте, remark, Вы писали:
R>Здравствуйте, Armastab, Вы писали:
A>>А вот еще интересно, как разные веб-сервера от кривых cgi-скриптов защищаются, или они их во внешних процессах запускают?
R>Ну собственно интерфейс CGI скриптов и подразумевает, что они запускаются в отдельных процессах.
хм, правда ведь. Что-то я ступил...
Re[2]: Не перехватывается ошибка(как сделать устойч. приложе
Здравствуйте, remark, Вы писали:
R>Единственный работающий вариант — это вынесение в отдельный процесс.
+1.
R>По поводу перехвата ошибок. Под виндой тебе надо поставить как минимум десяток обработчиков различных ошибок — это ошибки С райнтайма, С++ рантайма и ОС. Плюс надо перехватывать TerminateProcess(), т.к. некоторые кртешные функции любят без предупреждения вызывать TerminateProcess().
R>Вот примерный список того, что тебе надо перехватывать:
Кроме всего прочего — никакой перехват не защитит от сошедшего с ума плагина, который возьмётся писать случайную фигню в случайные адреса. Разве что тотальная защита всех страниц памяти от записи, но тогда негде будет работать самому приложению и всем остальным плагинам.
В Windows Explorer’е как раз есть отдельный процесс для кривых shell extension’ов. И как раз недавно аналогичный механизм прикрутили к Firefox’у.
Re[4]: Не перехватывается ошибка(как сделать устойч. приложе
Здравствуйте, remark, Вы писали:
R>Здравствуйте, Armastab, Вы писали:
R>>>TerminateProcess() A>>А как TerminateProcess перехватить?
R>Аааа... ну... пишешь в начало функции jmp на свой обработчик, что-то типа такого: R>