mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
[RTL]: Make RtlUnhandledExceptionFilter show a stack trace, so at least we can see where the exception came from.
svn path=/trunk/; revision=59903
This commit is contained in:
parent
3d4f9a8c5a
commit
0da3197b71
2 changed files with 132 additions and 0 deletions
|
@ -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], "<invalid address>", " ");
|
||||
}
|
||||
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("<error dumping stack trace: 0x%x>\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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue