Функция UnhandledExceptionFilter изнутри
Начав работать с исключениями, я решил, что можно извлечь массу информации, если детально вникнуть в механизм работы функции UnhandledExceptionFilter. Поэтому я тщательно его исследовал. Вот что делает функция UnhandledExceptionFilter.
1. Если возникло нарушение доступа и его причина связана с попыткой записи, система проверяет, не пытались ли Вы модифицировать ресурс в EXE- или DLL модуле. По умолчанию такие ресурсы предназначены только для чтения. Од нако 16-разрядная Windows разрешала модифицировать эти ресурсы, и из соображений обратной совместимости такие операции должны поддерживать ся как в 32-, так и в 64-разрядной Windows Поэтому, когда Вы пытаетесь мо дифицировать ресурс, UnhandledExeptionFilter вызывает VirtualProtect для из менения атрибута защиты страницы с этим ресурсом на PAGE_READWRTTE и возвpamae EXCEPTION_CONTINUE_EXECUTION.
2. Если Вы установили свой фильтр вызовом SetUnhandledExceptionFilter, функция UnhandledExceptionFilter обращается к Вашей функции фильтра. И если она возвращает EXCEPTION_EXECUTE_НANDLER или EXCEPTION_CONTINUE_EXE CUTION, UnhandledExceptionFilter передает его системе. Но, если Вы не устанав ливали свой фильтр необработанных исключений или если функция фильтра возрращает EXCEPTION_CONTINUE_SEARCH, UnhandledExceptionFilter перехо дит к операциям, описанным в п. 3
WINDOWS 98
Из-за ошибки в Windows 98 Ваша функция фильтра необработанных исклю чений вызывается, только если к процессу не подключен отладчик. По той же причине в Windows 98 невозможна отладка программы Spreadsheet, представ ленной в следующем разделе
3. Если Ваш процесс выполняется под управлением отладчика, то возвращается EXCEPTION_CONTINUE_SEARCH. Это может показаться странным, так как сис тема уже выполняет самый «верхний» блок try или except и другого фильтра выше по дереву вызовов просто нст lIo, обнаружив этот факт, система сооб щит отладчику о необработанном исключении в подопечном ему процессе. В ответ на это отладчик выведет окно, где предложит пачать отладку (Кстати, функция IsDebuggerPresent позволяет узнать, работает ли данный процесс под управлением очладчика.)
4. Если поток в Вашем процессе вызовет SetErrorMode с флагом SEM_NOGPFAUL TERRORBOX, то UnhandledExceptionFilter вернет EXCEPTION_EXECUTE_HANDLER.
5. Если процесс включен в задание (см. главу 5), на которое наложено ограниче ние JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION, то UnhandledExcep tionFtlter также вернет EXCEPTION_EXECUTE_HANDLER
WINDOWS 98
Windows 98 не поддерживает задания, и в ней этот этап пропускается.
6. UnhandledExceptionFilter считывает в реестре значение параметра Auto. Если оно равно 1, происходит переход на этап 7, в ином случае выводится окно с информацией об исключении. Если в реестре присутствует и параметр Debug ger, в этом окне появляются кнопки OK и Cancel. A если этого параметра нет — только кнопка ОК. Как только пользователь щелкнет кнопку OK, функция UnbandledExceptionFilter вернет EXCEPTION_EXECUTE_HANDLER. Щелчок кноп ки Cancel (если она ссть) вызывает переход на следующий этап.
WINDOWS 98
В Windows 98 упомянутые параметры хранятся не в реестре, а в файле Win.ini.
7. На этом этапе UnhandledExceptionFilter запускает отладчик как дочерний про цесс. Но сначала создает событие со сбросом вручную в занятом состоянии и наследуемым описателем. Затем извлекает из реестра значение параметра Debugger и вызывает sprintf для вставки идентификатора процесса (получен ного через функцию GetCurrentProcessd) и описателя события в командную строку. Элементу lpDesktop структуры STARTUPINFO присваивается значение "Winsta0\\Default", чтобы отладчик был доступен в интерактивном рсжимс на рабочем столе. Далее вызывается CreateProcess со значением TRUE в парамет ре bInherttHandles, благодаря чему отладчик получает возможность наследовать описатель объекта "событие" После этого UnhandledExceptionFilter ждет завер шения инициализации отладчика, вызвав WaitForSingleObjectEx с передачей ей описателя события. Заметьте, что вместо WaitForSingleObject используется Wait ForSingleObjectEx Это заставляет поток ждать в "тревожном* состоянии, кото рое позволяет ему обрабатывать все поступающие AРС-вызовы.
8. Закончив инициализацию, отладчик освобождает- событие, и поток Unbandled ExceptionFilter пробуждается. Теперь, когда процесс находится под управлени ем отладчика, UnbandledExceptionFilter возвращает EXCEPTION_CONTINUE_ SEARCH. Обратите внимание: все, что здесь происходит, точно соответствует этапу 3.