Author: dgorbachev
Date: Sat Nov 26 22:23:00 2011
New Revision: 54503

URL: http://svn.reactos.org/svn/reactos?rev=54503&view=rev
Log:
[NTOSKRNL]
KDB: print more useful backtrace after double fault or NMI.

Modified:
    trunk/reactos/ntoskrnl/kdbg/kdb_cli.c

Modified: trunk/reactos/ntoskrnl/kdbg/kdb_cli.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kdbg/kdb_cli.c?rev=54503&r1=54502&r2=54503&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/kdbg/kdb_cli.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kdbg/kdb_cli.c [iso-8859-1] Sat Nov 26 22:23:00 2011
@@ -948,6 +948,86 @@
     return TRUE;
 }
 
+static BOOLEAN
+KdbpTrapFrameFromPrevTss(
+    PKTRAP_FRAME TrapFrame)
+{
+    ULONG_PTR Eip, Ebp;
+    KDESCRIPTOR Gdtr;
+    KGDTENTRY Desc;
+    USHORT Sel;
+    PKTSS Tss;
+
+    Ke386GetGlobalDescriptorTable(&Gdtr.Limit);
+    Sel = Ke386GetTr();
+
+    if ((Sel & (sizeof(KGDTENTRY) - 1)) ||
+        (Sel < sizeof(KGDTENTRY)) ||
+        (Sel + sizeof(KGDTENTRY) - 1 > Gdtr.Limit))
+        return FALSE;
+
+    if (!NT_SUCCESS(KdbpSafeReadMemory(&Desc,
+                                       (PVOID)(Gdtr.Base + Sel),
+                                       sizeof(KGDTENTRY))))
+        return FALSE;
+
+    if (Desc.HighWord.Bits.Type != 0xB)
+        return FALSE;
+
+    Tss = (PKTSS)(ULONG_PTR)(Desc.BaseLow |
+                             Desc.HighWord.Bytes.BaseMid << 16 |
+                             Desc.HighWord.Bytes.BaseHi << 24);
+
+    if (!NT_SUCCESS(KdbpSafeReadMemory(&Sel,
+                                       (PVOID)&Tss->Backlink,
+                                       sizeof(USHORT))))
+        return FALSE;
+
+    if ((Sel & (sizeof(KGDTENTRY) - 1)) ||
+        (Sel < sizeof(KGDTENTRY)) ||
+        (Sel + sizeof(KGDTENTRY) - 1 > Gdtr.Limit))
+        return FALSE;
+
+    if (!NT_SUCCESS(KdbpSafeReadMemory(&Desc,
+                                       (PVOID)(Gdtr.Base + Sel),
+                                       sizeof(KGDTENTRY))))
+        return FALSE;
+
+    if (Desc.HighWord.Bits.Type != 0xB)
+        return FALSE;
+
+    Tss = (PKTSS)(ULONG_PTR)(Desc.BaseLow |
+                             Desc.HighWord.Bytes.BaseMid << 16 |
+                             Desc.HighWord.Bytes.BaseHi << 24);
+
+    if (!NT_SUCCESS(KdbpSafeReadMemory(&Eip,
+                                       (PVOID)&Tss->Eip,
+                                       sizeof(ULONG_PTR))))
+        return FALSE;
+
+    if (!NT_SUCCESS(KdbpSafeReadMemory(&Ebp,
+                                       (PVOID)&Tss->Ebp,
+                                       sizeof(ULONG_PTR))))
+        return FALSE;
+
+    TrapFrame->Eip = Eip;
+    TrapFrame->Ebp = Ebp;
+    return TRUE;
+}
+
+VOID __cdecl KiTrap02(VOID);
+VOID FASTCALL KiTrap03Handler(IN PKTRAP_FRAME);
+VOID __cdecl KiTrap08(VOID);
+VOID __cdecl KiTrap09(VOID);
+
+static BOOLEAN
+KdbpInNmiOrDoubleFaultHandler(
+    ULONG_PTR Address)
+{
+    return (Address > (ULONG_PTR)KiTrap02 && Address < 
(ULONG_PTR)KiTrap03Handler) ||
+           (Address > (ULONG_PTR)KiTrap08 && Address < (ULONG_PTR)KiTrap09);
+}
+
 /*!\brief Displays a backtrace.
  */
 static BOOLEAN
@@ -1054,6 +1134,20 @@
 
         if (Address == 0)
             break;
+
+        if (KdbpInNmiOrDoubleFaultHandler(Address))
+        {
+            if ((GotNextFrame = KdbpTrapFrameFromPrevTss(&TrapFrame)))
+            {
+                Address = TrapFrame.Eip;
+                Frame = TrapFrame.Ebp;
+
+                if (!KdbSymPrintAddress((PVOID)Address, &TrapFrame))
+                    KdbpPrint("<%08x>\n", Address);
+                else
+                    KdbpPrint("\n");
+            }
+        }
 
         if (!GotNextFrame)
         {


Reply via email to