Всем привет! Хотелось бы продолжить тему, потому как у меня есть актуальные вопросы. Статью прочитал, первую часть понял, потому как ранее уже использовал что-то подобное, но в статье это рассматривалось более детально, последнее 2 статьи оказались сложноватыми. Так что взял на вооружение предложенные методы в первой части, на данный момент меня и такой куций эксепт устраивает. Но... Есть но, как и ранее, предложенный пример на вырожениях типа *(PWord)0 = 0, отрабатывает на ура. А исключения возникшие к примеру при выполнении RtlRtlUnicodeХХХ функций нет... Я решил поэксперементировать, и убрал из оригинального кода (рис 3) строчку ContextRecord->Eax = (DWORD)&scratch;, и что я получил вместо BSOD как обычно(при вызове RtlUnicodeХХХ), вечный цикл в _except_handler. Теперь вопрос к тем, кто понял эту тему до конца, как сделать так чтобы выйте из этого цикла, при этом нормально завершить выполнение программы или выполнить то или иное условие исходя из полученного кода ошибки?
если функция не может обработать исключение - тогда return ExceptionContinueSearch; в твоём случае она пробует обработать исключение и возвращает return ExceptionContinueExecution; ты же убираешь код обработки (который делает код работоспособным) и поэтому она "говорит", что обработала исключение и код выполняется снова, хотя ошибка не устранена .
noonv, ну я об этом и говорю, что надо для этого, к примеру, на сколько мне известно в асйсе, что-то есть. Как мне завершить этот эксепшен, и продолжить выполнение программы?
1. Определить, какого рода исключение произошло 2. Определить, возможно ли устранить это исключение 3. Если возможно, определить адрес, где оно произошло 4. Проанализировать участок кода, вызвавший исключение, и состояние регистров процессора на момент возникновения исключения на предмет: какая инструкция или какого рода данные могут вызвать ошибку (и какую) в этом участке кода. 5. Для каждого возможного типа ошибки устранить внутри обработчика причину исключения. Например: ошибка деления на ноль - найти место, где происходит деление и посмотреть, каково состояние регистров на момент исключения. Если операнд инструкции div был равен нулю (а так оно и будет), изменить его внутри обработчика, заменив соответствующее регистру поле структуры CONTEXT с нуля на другое значение (которое заведомо не вызовет исключения). Эти изменения в структуре CONTEXT после завершения обработки исключения будут подставлены в регистры и таким образом деление будет происходить не на ноль, а на то значение, которое ты укажешь в этой структуре. 6. Если такие действия могут исказить результат работы программы, можно проигнорировать эту ошибку, перескочив место, вызвавшее исключение, и продолжив выполнение программы с безопасного места, где последствия исключения не окажут влияния на ход работы программы. Для этого пометить глобальной меткой начало этого безопасного места, и при возникновении исключения адрес этой метки вносить в поле RegEip структуры CONTEXT. Таким образом программа перескочит через кусок кода, вызвавший исключение и продолжит работу.
cresta Хорошо сказал, особенно "проанализировать участок кода" - тут без искусственного интеллекта не обойтись По жизни обычно все бывает проще. Локальные SEH'и с возможностью продолжения ставятся только там, где возможна ошибка и заранее известно как ее обойти. Тогда в обработчике либо вообще ничего не нужно анализировать, либо только проверить - действительно ли это та ошибка на которую мы расчитывали (код исключения, адрес) - если да, то обрабатываем и продолжаем, если нет - не обрабатываем. Все непредвиденные ошибки анализировать в программе практически нереально, поэтому их сначала выявляют при отладке программы и затем обходят путем явных проверок или установки SEH'ов. Поэтому основная задача в случае непредвиденной ошибки - во-первых, не допустить ее путешествия и лавинного размножения (поэтому не стоит маскировать исключения FPU и SSE), во-вторых, не допустить тихой смерти программы, вывести вразумительное сообщение и по возможности освободить выделенные ресурсы (закрыть ненужные файлы и прочие хэндлы, освободить память и т.п.). Все это делается обычно в цепочке финальных обработчиков.
leo Дык полдня изобретал эту фразу Естественно речь об исключениях, возникновение которых можно предсказать заранее, а не всех подряд возможных ситуациях. 1738760764__exception_filter.zip