diff --git a/reactos/lib/rtl/exception.c b/reactos/lib/rtl/exception.c index 60aa0bcaaed..000365d7815 100644 --- a/reactos/lib/rtl/exception.c +++ b/reactos/lib/rtl/exception.c @@ -169,6 +169,128 @@ RtlCaptureStackBackTrace(IN ULONG FramesToSkip, return (USHORT)i; } +/* +* Private helper function to lookup the module name from a given address. +* The address can point to anywhere within the module. +*/ +static const char* + _module_name_from_addr(const void* addr, void **module_start_addr, + char* psz, size_t nChars) +{ +#if 0 + MEMORY_BASIC_INFORMATION mbi; + if (VirtualQuery(addr, &mbi, sizeof(mbi)) != sizeof(mbi) || + !GetModuleFileNameA((HMODULE) mbi.AllocationBase, psz, nChars)) + { + psz[0] = '\0'; + *module_start_addr = 0; + } + else + { + *module_start_addr = (void *) mbi.AllocationBase; + } + return psz; +#else + psz[0] = '\0'; + *module_start_addr = 0; + return psz; +#endif +} + + +static VOID + _dump_context(PCONTEXT pc) +{ +#ifdef _M_IX86 + /* + * Print out the CPU registers + */ + DbgPrint("CS:EIP %x:%x\n", pc->SegCs & 0xffff, pc->Eip); + DbgPrint("DS %x ES %x FS %x GS %x\n", pc->SegDs & 0xffff, pc->SegEs & 0xffff, + pc->SegFs & 0xffff, pc->SegGs & 0xfff); + DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n", pc->Eax, pc->Ebx, pc->Ecx); + 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:RIP %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 +#endif +} + +static VOID + PrintStackTrace(struct _EXCEPTION_POINTERS *ExceptionInfo) +{ + PVOID StartAddr; + CHAR szMod[128] = ""; + PEXCEPTION_RECORD ExceptionRecord = ExceptionInfo->ExceptionRecord; + PCONTEXT ContextRecord = ExceptionInfo->ContextRecord; + + /* Print a stack trace. */ + DbgPrint("Unhandled exception\n"); + DbgPrint("ExceptionCode: %8x\n", ExceptionRecord->ExceptionCode); + + if ((NTSTATUS) ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION && + ExceptionRecord->NumberParameters == 2) + { + DbgPrint("Faulting Address: %8x\n", ExceptionRecord->ExceptionInformation[1]); + } + + _dump_context(ContextRecord); + _module_name_from_addr(ExceptionRecord->ExceptionAddress, &StartAddr, szMod, sizeof(szMod)); + DbgPrint("Address:\n %8x+%-8x %s\n", + (PVOID) StartAddr, + (ULONG_PTR) ExceptionRecord->ExceptionAddress - (ULONG_PTR) StartAddr, + szMod); +#ifdef _M_IX86 + DbgPrint("Frames:\n"); + + _SEH2_TRY + { + UINT i; + PULONG Frame = (PULONG) ContextRecord->Ebp; + + for (i = 0; Frame[1] != 0 && Frame[1] != 0xdeadbeef && i < 128; i++) + { + //if (IsBadReadPtr((PVOID) Frame[1], 4)) + if (Frame[1] == 0) + { + DbgPrint(" %8x%9s %s\n", Frame[1], "", " "); + } + else + { + _module_name_from_addr((const void*) Frame[1], &StartAddr, + szMod, sizeof(szMod)); + DbgPrint(" %8x+%-8x %s\n", + (PVOID) StartAddr, + (ULONG_PTR) Frame[1] - (ULONG_PTR) StartAddr, + szMod); + } + + if (Frame[0] == 0) break; + //if (IsBadReadPtr((PVOID) Frame[0], sizeof(*Frame) * 2)) + //break; + + Frame = (PULONG) Frame[0]; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + DbgPrint("\n", _SEH2_GetExceptionCode()); + } + _SEH2_END; +#endif +} + + /* * @unimplemented */ @@ -178,6 +300,7 @@ RtlUnhandledExceptionFilter(IN struct _EXCEPTION_POINTERS* ExceptionInfo) { /* This is used by the security cookie checks, and calso called externally */ UNIMPLEMENTED; + PrintStackTrace(ExceptionInfo); return ERROR_CALL_NOT_IMPLEMENTED; } diff --git a/reactos/ntoskrnl/ke/i386/traphdlr.c b/reactos/ntoskrnl/ke/i386/traphdlr.c index 9bd96704ec7..6f158d44559 100644 --- a/reactos/ntoskrnl/ke/i386/traphdlr.c +++ b/reactos/ntoskrnl/ke/i386/traphdlr.c @@ -1234,6 +1234,15 @@ KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame) /* Continue execution */ KiEoiHelper(TrapFrame); } + else + { + /* Do what windows does and issue an invalid access violation */ + KiDispatchException2Args(KI_EXCEPTION_ACCESS_VIOLATION, + TrapFrame->Eip, + TrapFrame->ErrCode & 2 ? TRUE : FALSE, + Cr2, + TrapFrame); + } } /* Call the access fault handler */