Тем кто ложится спать, спокойной ночи . А к тем кто бдит, вопрос: Есть такая цепочка вызовов, начинающаяся CreateThread из WndProc. Код (Text): ;===================================================================== ========== WndProc proc uses esi edi ebx hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD .... invoke CreateThread,NULL,NULL,addr GetNextFile,eax,NULL,NULL .... ;===================================================================== ========== GetNextFile proc uses esi dwVector:DWORD .... call GetBitmap ;===================================================================== ========== GetBitmap proc uses ebx .... invoke ImageFromFile,addr szFileName ;===================================================================== ========== ImageFromFile PROC uses ebx pszFileName:DWORD .... invoke OleLoadPicturePath.............................. _ex_safe:: Эта цепочка на некоторых файлах спотыкается на OleLoadPicturePath - ACCESS_VIOLATION. Установил invoke SetUnhandledExceptionFilter, addr exceptions Код (Text): ;===================================================================== ========== exceptions proc uses ebx esi edi lParam:DWORD mov ebx,lParam assume ebx: ptr EXCEPTION_POINTERS mov edx,[ebx].pExceptionRecord assume ebx: nothing assume edx: ptr EXCEPTION_RECORD .if [edx].ExceptionCode == 0C0000005h add ebx,4 mov eax,offset _ex_safe mov [ebx+0B8h],eax m2m [ebx+0A4h],_ebx ;пытался восстанавливать m2m [ebx+0B4h],_ebp ;данные регистров, сохраненные m2m [ebx+0A0h],_esi ;перед OleLoadPicturePath m2m [ebx+09Ch],_edi ;но безрезультатно. m2m [ebx+0C4h],_esp mov eax,EXCEPTION_CONTINUE_EXECUTION .endif assume edx: nothing ret Программа не вылетает, но каждый новый поток, однажды вызвав исключение, уже не закрывается и постоянно продолжает вызывать процедуру exceptions, нагружая проц. Можно конечно попробовать определить и прибить поток, вызвавший исключение, но наверное это не правильно. Как можно и куда можно вернуться после обработки исключения? _ex_safe вставлена сразу после OleLoadPicturePath. Думал установить локальный обработчик, но ни одного рабочего примера не нашёл
cresta Из приведенного кода не совсем ясно как ты используешь и контролируешь результаты вызовов функций. Причина зацикливания может быть в том, что ошибка в OleLoadPicturePath приводит к ошибкам в вызывющих ее функциях - они снова попадают в тот же обработчик и опять возвращаются в _ex_safe, причем возможно уже с неверными значениями _ebx.._esp - смотря где ты их сохраняешь. Если это так, то нужно в обработчике устанавливать признак ошибки через CONTEXT.regEAX (или еще как) и в точке _ex_safe проверять результат и передавать его по цепочке в вызывающие функции (if Ok then do_something else doom&gloom
cresta Да у тебя может элементарная ошибка\описка - что это за add ebx,4 если ebx это ptr EXCEPTION_POINTERS. Нужно просто Код (Text): mov ebx,lParam mov edx,[ebx] ;lpExceptionRecord mov ebx,[ebx+4] ;lpContext А что у тебя возвратит обработчик если ExceptionCode != 0C0000005h или ExceptionFlags = EXCEPTION_NONCONTINUABLE ? Аккуратнее надо бы
leo ExceptionCode и ExceptionFlags проверяются. А с add ebx,4 что-то действительно напортачил Или недоспал, или перепил Код (Text): mov ebx,lParam assume ebx: ptr EXCEPTION_POINTERS mov edx,[ebx].pExceptionRecord assume ebx: nothing assume edx: ptr EXCEPTION_RECORD .if ([edx].ExceptionCode==EXCEPTION_ACCESS_VIOLATION) .if ([edx].ExceptionFlags==0) ;если можно обрабатывать, mov ebx,[ebx+4] ;ebx - указатель на CONTEXT m2m [ebx+0B8h],_eip ;восстановление состояния m2m [ebx+0A4h],_ebx ;регистров, сохраненных m2m [ebx+0B4h],_ebp ;в .data непосредственно m2m [ebx+0A0h],_esi ;перед вызовом m2m [ebx+09Ch],_edi ;OleLoadPicturePath m2m [ebx+0C4h],_esp ;в _eip - адрес метки _safe:: mov eax,EXCEPTION_CONTINUE_EXECUTION ret .endif .endif assume edx: nothing mov eax,EXCEPTION_EXECUTE_HANDLER ret Всё работает. Поток можно и не прибивать. Спасибо.
Тут ещё один вопрос, в контексте обработки исключений Хотел поставить внутрипоточный обработчик, но сколько ни бился, компилятор не хочет воспринимать инструкцию 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] Какой правильный синтаксис этой хрени?
cresta Дык это ... в масме assume fs:nothing, в фасме типа того Код (Text): push dword [fs:0] push dword [fs: word 0] push dword [fs:ecx]
в масме assume fs:nothing Енто точно, вроде как в масме по умолчанию fs assumed to ERROR ох уж этот масм PS: cresta, не стоит забывать "рыться" и на форуме - вроде как недавно этот вопрос поднимался
leo Я их не защищаю. А по fs искал - ничего нету. Поэтому и полез на board.win32asmcommunity, что тут не нашёл.
Quantum Попробовал сейчас снова по ключевому слову fs поиск - ни одной ссылки не найдено. Наверняка слово встречается не один раз, но не найдено