необработанные исключения

Тема в разделе "WASM.WIN32", создана пользователем Velheart, 17 дек 2008.

  1. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Привет.
    Мне нужно отлавливать все необработанные исключения в приложении для создания минидампа + сбора некоторой доп инфы.
    Я для этого использую UnhandledExceptionFilter + VectoredExceptionHandler + хук
    UnhandledExceptionFilter в kernel32 для обработки gsfailure. Вроде бы все исключения, кроме повреждения esp, которое описывал Clerk
    в http://www.wasm.ru/forum/viewtopic.php?id=29865 ловятся. Никто не знает, есть ли еще какие-нибудь фичи типа gsfailure, когда CRT прибивает процесс, не давая выполнится указанным обработчикам,
    или, возможно, некоторые специфические условия, при которых что-нибудь пройдет мимо ?(например в outproc-com-сервере, если исключение возникает в конструкторе
    требуемого объекта без векторного обработчика процесс просто дохнет, и даже хук ZwTerminateProcess не помогает)
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Исключение в юзермоде не удастся словить в случае:
    > Регистр Esp указывает на страницу не доступную для записи.
    > Селектор стека являетсо невалидным, либо в совокупности с регистром Esp они ссылаются на невалидный адрес(в страницу запрещена запись).
    В обоих случаях при копировании аргументов в стек потока, в котором произошло исключение изза невалидности/запрета на запись в ядре возникает исключение и процесс ядро завершает, не выполняя конечную развёртку исключения в этом потоке, посылая сообщение отладчику, если он активен.
    Иначе перехватив точку входа в диспетчер исключений, любое исключение будет развёрнуто в нём.
     
  3. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Clerk
    Сенкс
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Velheart
    Ковырялся в отладчике и вспомнил про этот топик. Есть одно замечание. Механизм по сути тотже. Вызов сервиса посредством инструкции sysenter требует чтобы регистр Edx указывал на параметры в стеке, а собственно указатель на стек в регистре Esp значения не имеет, допускается вызов сервиса хоть с нулевым значением в Esp. По возврату из сервиса на KiFastSystemCallRet ядро перезагружает регистр Esp, помещая в него значение, которое было в регистре Edx при вызове сервиса, тоесть восстанавливает стек. Если вызвать сервис с невалидным указателем в регистре Edx, то из сервиса поток вернётся, возвратив код ошибки STATUS_ACCESS_VIOLATION, но так как в Esp будет загружен невалидный указатель из Edx, а возврат исполняется на инструкцию Ret, то при выполнении этой инструкции исключение не может быть развёрнуто и ядро процесс прибьёт.
     
  5. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Clerk
    Я вот еще с такой фигней столкнулся: при некоторых исключениях в начали инициализации (я сейчас точно не помню, на по-моему даже деление на 0, хотя я думаю это не принципиально) com-сервера он молча умирал и мой UnhandledExceptionFilter не вызывался, но более того не вызывался ZwTerminateProcess, который я хукал, я подумал, что возможно процесс репортит об ошибке службе RPC, которая его запускает и видимо прибивает..Ведь процесс же не может себя уничтожить из юзермода, не вызывая ZwTerminateProcess и не производя одно из описанных тобой исключений, или я чего-то не знаю (причем c подопытным процессом все по-честному, обработка происходит в ole32.dll и rpcrt4.dll и это они чего-то делают)?
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Velheart
    Собсвенно ядро вроде как ни при каких обстоятельствах кроме описанных не уничтожает процесс. Используй ядерный отладчик и посмотри откуда в ядре юзоется NtTerminateProcess/ZwTerminateProcess. Если KiDispatchException() - то однозначно невалидный стек. Возможная причина - после сохранения в стеке очередного значения он не был расширен, изза исчерпания его(возможных размеров).
    Возможно ты пропустил вызов.. Например при возникновении ошибки в загрузчике при загрузке модуля, загрузчик убивает текущий процесс, а такое может быть при наличии оконных хуков..
    Посмотри вобщем под отладчиком.
     
  7. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Да, действительно, посмотрел сисером -- процесс прибивает служба удаленного вызова процедур, благодарю за помощь. А с багами при наличии оконных хуков я уже столкнулся, когда в тестовом приложении у меня один эксепшн ловился, а у всех остальных -- нет, из-за лингвы, как потом случайно выяснилось =)
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Velheart
    Интересно, что за служба и какой модуль прибивает ?
     
  9. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Clerk
    Сорри, я наврал, процесс прибивает не RPC - служба, а DCOM, она же его и запускает, там я насколько понял такая фишка: мы в клиенте запрашиваем нужный нам интерфейс, DCOM служба запускает прцесс в котором находится наш ко-класс, и ждет на LPC порте сообщения о том что и как, и если все плохо -- убивает процесс. При этом UnhandledExceptionFilter не работает, т.к. исключение обрабатывается, но в дефолтном обработчике происходит вся эта фигня..
    А вообще, мне это для работы надо.., там есть приложение с несколькими модулями-процессами, так вот нужно уметь перехватывать максимальное количество типов необработанных исключений, чтобы перед смертью сгенерировать крэш-дамп+собрать некотурую инфу о системе и хорошо представлять все случаи, когда это невозможно, и по каким причинам.
     
  10. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Velheart
    Ага, я сразу понял что это не рпк(там не юзоется сервис NtTerminateProcess, смотрел). Советую перейти в режим ядра, там как угодно сможешь любые исключения обработать, либо единственный вариант для юзермода - используй отладчик, который будет управлять основным приложением, но с единственной целью ловить исключения(ловятся все).