int _except_handler3(PEXCEPTION_RECORD rec, MSVCRT_EXCEPTION_FRAME* frame, PCONTEXT context, void *dispatcher) { long retval; int trylevel; EXCEPTION_POINTERS exceptPtrs; PSCOPETABLE pScopeTable; //syslog(LOG_DEBUG, "msvcrt: exception %lx flags=%lx at %p handler=%p %p %p semi-stub", // rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress, // frame->handler, context, dispatcher); __asm cld; if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) { // Unwinding the current frame _local_unwind2(frame, TRYLEVEL_END); return ExceptionContinueSearch; } else { // Hunting for handler exceptPtrs.ExceptionRecord = rec; exceptPtrs.ContextRecord = context; *((DWORD *) frame - 1) = (DWORD) &exceptPtrs; trylevel = frame->trylevel; pScopeTable = frame->scopetable; while (trylevel != TRYLEVEL_END) { if (pScopeTable[trylevel].lpfnFilter) { //syslog(LOG_DEBUG, "filter = %p", pScopeTable[trylevel].lpfnFilter); retval = call_filter(pScopeTable[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp); //syslog(LOG_DEBUG, "filter returned %s", retval == EXCEPTION_CONTINUE_EXECUTION ? // "CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ? // "EXECUTE_HANDLER" : "CONTINUE_SEARCH"); if (retval == EXCEPTION_CONTINUE_EXECUTION) return ExceptionContinueExecution; if (retval == EXCEPTION_EXECUTE_HANDLER) { // Unwind all higher frames, this one will handle the exception _global_unwind2((PEXCEPTION_FRAME) frame); _local_unwind2(frame, trylevel); // Set our trylevel to the enclosing block, and call the __finally code, which won't return frame->trylevel = pScopeTable->previousTryLevel; //syslog(LOG_DEBUG, "__finally block %p",pScopeTable[trylevel].lpfnHandler); call_finally_block(pScopeTable[trylevel].lpfnHandler, &frame->_ebp); panic("Returned from __finally block"); } } trylevel = pScopeTable->previousTryLevel; } } return ExceptionContinueSearch; }
void __stdcall _seh_longjmp_unwind(_JUMP_BUFFER *jmp) { _local_unwind2((MSVCRT_EXCEPTION_FRAME*) jmp->Registration, jmp->TryLevel); }