#define NDEBUG
#include <debug.h>
-LPTOP_LEVEL_EXCEPTION_FILTER GlobalTopLevelExceptionFilter = UnhandledExceptionFilter;
+LPTOP_LEVEL_EXCEPTION_FILTER GlobalTopLevelExceptionFilter = NULL;
UINT
WINAPI
return psz;
}
-#ifdef _M_IX86
+
static VOID
_dump_context(PCONTEXT pc)
{
+#ifdef _M_IX86
/*
* Print out the CPU registers
*/
DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x ESP: %.8x\n", pc->Edx,
pc->Ebp, pc->Esi, pc->Esp);
DbgPrint("EDI: %.8x EFLAGS: %.8x\n", pc->Edi, pc->EFlags);
-}
+#elif defined(_M_AMD64)
+ DbgPrint("CS:EIP %x:%I64x\n", pc->SegCs&0xffff, pc->Rip );
+ DbgPrint("DS %x ES %x FS %x GS %x\n", pc->SegDs&0xffff, pc->SegEs&0xffff,
+ pc->SegFs&0xffff, pc->SegGs&0xfff);
+ DbgPrint("RAX: %I64x RBX: %I64x RCX: %I64x RDI: %I64x\n", pc->Rax, pc->Rbx, pc->Rcx, pc->Rdi);
+ DbgPrint("RDX: %I64x RBP: %I64x RSI: %I64x RSP: %I64x\n", pc->Rdx, pc->Rbp, pc->Rsi, pc->Rsp);
+ DbgPrint("R8: %I64x R9: %I64x R10: %I64x R11: %I64x\n", pc->R8, pc->R9, pc->R10, pc->R11);
+ DbgPrint("R12: %I64x R13: %I64x R14: %I64x R15: %I64x\n", pc->R12, pc->R13, pc->R14, pc->R15);
+ DbgPrint("EFLAGS: %.8x\n", pc->EFlags);
#else
#warning Unknown architecture
-static VOID
-_dump_context(PCONTEXT pc)
-{
-}
#endif
+}
static LONG
BasepCheckForReadOnlyResource(IN PVOID Ptr)
use SEH here because we don't know if it's actually a
resource mapping */
- _SEH_TRY
+ _SEH2_TRY
{
Data = RtlImageDirectoryEntryToData(mbi.AllocationBase,
TRUE,
}
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
- _SEH_END;
+ _SEH2_END;
}
return Ret;
/*
* @unimplemented
*/
-LONG STDCALL
+LONG WINAPI
UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
LONG RetValue;
HANDLE DebugPort = NULL;
NTSTATUS ErrCode;
+ ULONG_PTR ErrorParameters[4];
+ ULONG ErrorResponse;
- if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION &&
- ExceptionInfo->ExceptionRecord->ExceptionInformation[0])
+ if ((NTSTATUS)ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION &&
+ ExceptionInfo->ExceptionRecord->NumberParameters >= 2)
{
- /* Change the protection on some write attempts, some InstallShield setups
- have this bug */
- RetValue = BasepCheckForReadOnlyResource(
- (PVOID)ExceptionInfo->ExceptionRecord->ExceptionInformation[1]);
- if (RetValue == EXCEPTION_CONTINUE_EXECUTION)
- return EXCEPTION_CONTINUE_EXECUTION;
+ switch(ExceptionInfo->ExceptionRecord->ExceptionInformation[0])
+ {
+ case EXCEPTION_WRITE_FAULT:
+ /* Change the protection on some write attempts, some InstallShield setups
+ have this bug */
+ RetValue = BasepCheckForReadOnlyResource(
+ (PVOID)ExceptionInfo->ExceptionRecord->ExceptionInformation[1]);
+ if (RetValue == EXCEPTION_CONTINUE_EXECUTION)
+ return EXCEPTION_CONTINUE_EXECUTION;
+ break;
+ case EXCEPTION_EXECUTE_FAULT:
+ /* FIXME */
+ break;
+ }
}
/* Is there a debugger running ? */
return EXCEPTION_CONTINUE_SEARCH;
}
+ if (GlobalTopLevelExceptionFilter)
+ {
+ LONG ret = GlobalTopLevelExceptionFilter( ExceptionInfo );
+ if (ret != EXCEPTION_CONTINUE_SEARCH)
+ return ret;
+ }
+
if ((GetErrorMode() & SEM_NOGPFAULTERRORBOX) == 0)
{
-#ifdef _X86_
+#ifdef __i386__
PULONG Frame;
#endif
PVOID StartAddr;
/* Print a stack trace. */
DbgPrint("Unhandled exception\n");
DbgPrint("ExceptionCode: %8x\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
- if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION &&
+ if ((NTSTATUS)ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION &&
ExceptionInfo->ExceptionRecord->NumberParameters == 2)
{
DbgPrint("Faulting Address: %8x\n", ExceptionInfo->ExceptionRecord->ExceptionInformation[1]);
ExceptionInfo->ExceptionRecord->ExceptionAddress,
_module_name_from_addr(ExceptionInfo->ExceptionRecord->ExceptionAddress, &StartAddr, szMod, sizeof(szMod)));
_dump_context ( ExceptionInfo->ContextRecord );
-#ifdef _X86_
+#ifdef __i386__
DbgPrint("Frames:\n");
- _SEH_TRY
+ _SEH2_TRY
{
Frame = (PULONG)ExceptionInfo->ContextRecord->Ebp;
while (Frame[1] != 0 && Frame[1] != 0xdeadbeef)
Frame = (PULONG)Frame[0];
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- DbgPrint("<error dumping stack trace: 0x%x>\n", _SEH_GetExceptionCode());
+ DbgPrint("<error dumping stack trace: 0x%x>\n", _SEH2_GetExceptionCode());
}
- _SEH_END;
+ _SEH2_END;
#endif
}
+ /* Save exception code and address */
+ ErrorParameters[0] = (ULONG)ExceptionInfo->ExceptionRecord->ExceptionCode;
+ ErrorParameters[1] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
+
+ if ((NTSTATUS)ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION)
+ {
+ /* get the type of operation that caused the access violation */
+ ErrorParameters[2] = ExceptionInfo->ExceptionRecord->ExceptionInformation[0];
+ }
+ else
+ {
+ ErrorParameters[2] = ExceptionInfo->ExceptionRecord->ExceptionInformation[2];
+ }
+
+ /* Save faulting address */
+ ErrorParameters[3] = ExceptionInfo->ExceptionRecord->ExceptionInformation[1];
+
+ /* Raise the harderror */
+ ErrCode = NtRaiseHardError(STATUS_UNHANDLED_EXCEPTION | 0x10000000,
+ 4, 0, ErrorParameters, OptionOkCancel, &ErrorResponse);
+
+ if (NT_SUCCESS(ErrCode) && (ErrorResponse == ResponseCancel))
+ {
+ /* FIXME: Check the result, if the "Cancel" button was
+ clicked run a debugger */
+ DPRINT1("Debugging is not implemented yet\n");
+ }
+
/*
* Returning EXCEPTION_EXECUTE_HANDLER means that the code in
* the __except block will be executed. Normally this will end up in a
}
}
+ if (dwExceptionCode == 0xeedface)
+ {
+ DPRINT1("Delphi Exception at address: %p\n", ExceptionRecord.ExceptionInformation[0]);
+ DPRINT1("Exception-Object: %p\n", ExceptionRecord.ExceptionInformation[1]);
+ DPRINT1("Exception text: %s\n", ExceptionRecord.ExceptionInformation[2]);
+ }
+
+ /* Trace the wine special error and show the modulename and functionname */
+ if (dwExceptionCode == 0x80000100 /*EXCEPTION_WINE_STUB*/)
+ {
+ /* Numbers of parameter must be equal to two */
+ if (ExceptionRecord.NumberParameters == 2)
+ {
+ DPRINT1("Missing function in : %s\n", ExceptionRecord.ExceptionInformation[0]);
+ DPRINT1("with the functionname : %s\n", ExceptionRecord.ExceptionInformation[1]);
+ }
+ }
+
/* Raise the exception */
RtlRaiseException(&ExceptionRecord);
}