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

Тема в разделе "WASM.BEGINNERS", создана пользователем cresta, 15 июл 2005.

  1. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Тем кто ложится спать, спокойной ночи .



    А к тем кто бдит, вопрос:

    Есть такая цепочка вызовов, начинающаяся CreateThread из WndProc.


    Код (Text):
    1. ;=====================================================================  ==========
    2. WndProc proc uses esi edi ebx hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
    3.     ....
    4.     invoke  CreateThread,NULL,NULL,addr GetNextFile,eax,NULL,NULL
    5.     ....
    6.  
    7. ;=====================================================================  ==========
    8. GetNextFile proc uses esi dwVector:DWORD
    9.     ....
    10.     call    GetBitmap
    11.  
    12. ;=====================================================================  ==========
    13. GetBitmap proc uses ebx
    14.     ....
    15.     invoke  ImageFromFile,addr szFileName
    16.  
    17. ;=====================================================================  ==========
    18. ImageFromFile PROC uses ebx pszFileName:DWORD
    19.     ....
    20.     invoke  OleLoadPicturePath..............................
    21. _ex_safe::
    22.  




    Эта цепочка на некоторых файлах спотыкается на OleLoadPicturePath - ACCESS_VIOLATION.

    Установил invoke SetUnhandledExceptionFilter, addr exceptions


    Код (Text):
    1. ;=====================================================================  ==========
    2. exceptions proc uses ebx esi edi lParam:DWORD
    3.  
    4.     mov     ebx,lParam
    5.     assume  ebx: ptr EXCEPTION_POINTERS
    6.     mov     edx,[ebx].pExceptionRecord
    7.     assume  ebx: nothing
    8.    
    9.     assume  edx: ptr EXCEPTION_RECORD
    10.     .if     [edx].ExceptionCode == 0C0000005h
    11.         add     ebx,4
    12.         mov     eax,offset _ex_safe
    13.         mov     [ebx+0B8h],eax
    14.  
    15.         m2m     [ebx+0A4h],_ebx         ;пытался восстанавливать
    16.         m2m     [ebx+0B4h],_ebp         ;данные регистров, сохраненные
    17.         m2m     [ebx+0A0h],_esi         ;перед OleLoadPicturePath
    18.         m2m     [ebx+09Ch],_edi         ;но безрезультатно.
    19.         m2m     [ebx+0C4h],_esp
    20.         mov     eax,EXCEPTION_CONTINUE_EXECUTION
    21.     .endif
    22.     assume  edx: nothing
    23.     ret




    Программа не вылетает, но каждый новый поток, однажды вызвав исключение, уже не закрывается и постоянно продолжает вызывать процедуру exceptions, нагружая проц. Можно конечно попробовать определить и прибить поток, вызвавший исключение, но наверное это не правильно.

    Как можно и куда можно вернуться после обработки исключения?

    _ex_safe вставлена сразу после OleLoadPicturePath.



    Думал установить локальный обработчик, но ни одного рабочего примера не нашёл :dntknw:
     
  2. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    cresta



    Из приведенного кода не совсем ясно как ты используешь и контролируешь результаты вызовов функций.

    Причина зацикливания может быть в том, что ошибка в OleLoadPicturePath приводит к ошибкам в вызывющих ее функциях - они снова попадают в тот же обработчик и опять возвращаются в _ex_safe, причем возможно уже с неверными значениями _ebx.._esp - смотря где ты их сохраняешь. Если это так, то нужно в обработчике устанавливать признак ошибки через CONTEXT.regEAX (или еще как) и в точке _ex_safe проверять результат и передавать его по цепочке в вызывающие функции (if Ok then do_something else doom&gloom ;)
     
  3. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    cresta

    Да у тебя может элементарная ошибка\описка - что это за add ebx,4 если ebx это ptr EXCEPTION_POINTERS. Нужно просто
    Код (Text):
    1.     mov ebx,lParam
    2.     mov edx,[ebx]   ;lpExceptionRecord
    3.     mov ebx,[ebx+4] ;lpContext
    А что у тебя возвратит обработчик если ExceptionCode != 0C0000005h или ExceptionFlags = EXCEPTION_NONCONTINUABLE ? Аккуратнее надо бы ;)
     
  4. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    leo

    ExceptionCode и ExceptionFlags проверяются.

    А с add ebx,4 что-то действительно напортачил :dntknw: Или недоспал, или перепил :dntknw:


    Код (Text):
    1.     mov     ebx,lParam
    2.     assume  ebx: ptr EXCEPTION_POINTERS
    3.     mov     edx,[ebx].pExceptionRecord
    4.     assume  ebx: nothing
    5.     assume  edx: ptr EXCEPTION_RECORD
    6.    
    7.     .if     ([edx].ExceptionCode==EXCEPTION_ACCESS_VIOLATION)
    8.         .if     ([edx].ExceptionFlags==0)                       ;если можно обрабатывать,
    9.             mov     ebx,[ebx+4]                                 ;ebx - указатель на CONTEXT
    10.             m2m     [ebx+0B8h],_eip                             ;восстановление состояния
    11.             m2m     [ebx+0A4h],_ebx                             ;регистров, сохраненных
    12.             m2m     [ebx+0B4h],_ebp                             ;в .data непосредственно
    13.             m2m     [ebx+0A0h],_esi                             ;перед вызовом
    14.             m2m     [ebx+09Ch],_edi                             ;OleLoadPicturePath
    15.             m2m     [ebx+0C4h],_esp                             ;в _eip - адрес метки _safe::
    16.             mov     eax,EXCEPTION_CONTINUE_EXECUTION
    17.             ret
    18.         .endif
    19.     .endif
    20.     assume  edx: nothing
    21.     mov     eax,EXCEPTION_EXECUTE_HANDLER
    22.     ret




    Всё работает. Поток можно и не прибивать. Спасибо.
     
  5. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Тут ещё один вопрос, в контексте обработки исключений :)



    Хотел поставить внутрипоточный обработчик, но сколько ни бился, компилятор не хочет воспринимать инструкцию

    push fs[0] - либо синтаксическая ошибка, либо use of register assumed to ERROR

    Пробовал поглядеть в Оле, как выглядит синтаксис, порылся на board.win32asmcommunity, смотрел в исходниках, набрал несколько вариантов, ни один компилятор не хочет воспринимать.



    push fs[0]

    push [fs:0]

    push dword ptr[fs:0]

    push dword ptr fs:[0]

    xor ecx,ecx

    push [fs:ecx]



    Какой правильный синтаксис этой хрени?
     
  6. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    cresta




    Дык это ... в масме assume fs:nothing, в фасме типа того
    Код (Text):
    1. push dword [fs:0]
    2. push dword [fs: word 0]
    3. push dword [fs:ecx]
     
  7. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    в масме assume fs:nothing

    Енто точно, вроде как в масме по умолчанию fs assumed to ERROR :dntknw: ох уж этот масм ;)



    PS: cresta, не стоит забывать "рыться" и на форуме - вроде как недавно этот вопрос поднимался ;)
     
  8. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Данке.
     
  9. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    [private]...[/private]
     
  10. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    leo

    Я их не защищаю.

    А по fs искал - ничего нету. Поэтому и полез на board.win32asmcommunity, что тут не нашёл.
     
  11. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    cresta



    Вот же оно!
     
  12. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Quantum



    Попробовал сейчас снова по ключевому слову fs поиск - ни одной ссылки не найдено. Наверняка слово встречается не один раз, но не найдено :dntknw:
     
  13. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    В поиске надо больше 2-х буквъ :)
     
  14. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    кто бы мог подумать :dntknw: