[RTL]: Make RtlUnhandledExceptionFilter show a stack trace, so at least we can see...
authorAlex Ionescu <aionescu@gmail.com>
Fri, 30 Aug 2013 15:37:10 +0000 (15:37 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Fri, 30 Aug 2013 15:37:10 +0000 (15:37 +0000)
svn path=/trunk/; revision=59903

reactos/lib/rtl/exception.c
reactos/ntoskrnl/ke/i386/traphdlr.c

index 60aa0bc..000365d 100644 (file)
@@ -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;
 }
 
index 9bd9670..6f158d4 100644 (file)
@@ -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 */