- KDBG: Correct the use of PsLookupThread/ProcessByThread/ProcessId -- the caller...
[reactos.git] / reactos / ntoskrnl / kdbg / kdb.c
index 288725f..2155e40 100644 (file)
@@ -11,7 +11,7 @@
 
 #include <ntoskrnl.h>
 #define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
 
 /* TYPES *********************************************************************/
 
@@ -51,6 +51,7 @@ PKDB_KTRAP_FRAME KdbCurrentTrapFrame = NULL; /* Pointer to the current trapframe
 STATIC KDB_KTRAP_FRAME KdbTrapFrame = { { 0 } };  /* The trapframe which was passed to KdbEnterDebuggerException */
 STATIC KDB_KTRAP_FRAME KdbThreadTrapFrame = { { 0 } }; /* The trapframe of the current thread (KdbCurrentThread) */
 STATIC KAPC_STATE KdbApcState;
+extern BOOLEAN KdbpBugCheckRequested;
 
 /* Array of conditions when to enter KDB */
 STATIC KDB_ENTER_CONDITION KdbEnterConditions[][2] =
@@ -1081,6 +1082,7 @@ KdbpAttachToThread(
    if (KeIsExecutingDpc() && Process != KdbCurrentProcess)
    {
       KdbpPrint("Cannot attach to thread within another process while executing a DPC.\n");
+      ObDereferenceObject(Thread);
       return FALSE;
    }
 
@@ -1129,6 +1131,7 @@ KdbpAttachToThread(
       KdbCurrentProcess = Process;
    }
 
+   ObDereferenceObject(Thread);
    return TRUE;
 }
 
@@ -1157,6 +1160,7 @@ KdbpAttachToProcess(
    }
 
    Entry = Process->ThreadListHead.Flink;
+   ObDereferenceObject(Process);
    if (Entry == &KdbCurrentProcess->ThreadListHead)
    {
       KdbpPrint("No threads in process 0x%08x, cannot attach to process!\n", (ULONG)ProcessId);
@@ -1203,9 +1207,9 @@ KdbpInternalEnter()
    Thread->Tcb.StackLimit = (ULONG)KdbStack;
    Thread->Tcb.KernelStack = (char*)KdbStack + KDB_STACK_SIZE;
 
-   /*KdbpPrint("Switching to KDB stack 0x%08x-0x%08x\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase);*/
+   /*KdbpPrint("Switching to KDB stack 0x%08x-0x%08x (Current Stack is 0x%08x)\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase, Esp);*/
 
-   KdbpStackSwitchAndCall(Thread->Tcb.KernelStack, KdbpCallMainLoop);
+   KdbpStackSwitchAndCall(KdbStack + KDB_STACK_SIZE - sizeof(ULONG), KdbpCallMainLoop);
 
    Thread->Tcb.InitialStack = SavedInitialStack;
    Thread->Tcb.StackBase = SavedStackBase;
@@ -1330,8 +1334,8 @@ KdbEnterDebuggerException(
          if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address,
                                                   BreakPoint->Data.SavedInstruction, NULL)))
          {
-            DbgPrint("Couldn't restore original instruction after INT3! Cannot continue execution.\n");
-            KEBUGCHECK(0);
+            KdbpPrint("Couldn't restore original instruction after INT3! Cannot continue execution.\n");
+            KeBugCheck(0); // FIXME: Proper bugcode!
          }
       }
 
@@ -1349,7 +1353,7 @@ KdbEnterDebuggerException(
       else if (BreakPoint->Type == KdbBreakPointTemporary &&
                BreakPoint->Process == KdbCurrentProcess)
       {
-         ASSERT((TrapFrame->EFlags & X86_EFLAGS_TF) == 0);
+         ASSERT((TrapFrame->EFlags & EFLAGS_TF) == 0);
 
          /*
           * Delete the temporary breakpoint which was used to step over or into the instruction.
@@ -1361,7 +1365,7 @@ KdbEnterDebuggerException(
             if ((KdbSingleStepOver && !KdbpStepOverInstruction(TrapFrame->Eip)) ||
                 (!KdbSingleStepOver && !KdbpStepIntoInstruction(TrapFrame->Eip)))
             {
-               TrapFrame->EFlags |= X86_EFLAGS_TF;
+               Context->EFlags |= EFLAGS_TF;
             }
             goto continue_execution; /* return */
          }
@@ -1377,7 +1381,7 @@ KdbEnterDebuggerException(
                BreakPoint->Type == KdbBreakPointTemporary)
       {
          ASSERT(ExceptionCode == STATUS_BREAKPOINT);
-         TrapFrame->EFlags |= X86_EFLAGS_TF;
+         Context->EFlags |= EFLAGS_TF;
          KdbBreakPointToReenable = BreakPoint;
       }
 
@@ -1410,12 +1414,12 @@ KdbEnterDebuggerException(
 
       if (BreakPoint->Type == KdbBreakPointSoftware)
       {
-         DbgPrint("Entered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
+         KdbpPrint("Entered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
                   KdbLastBreakPointNr, TrapFrame->SegCs & 0xffff, TrapFrame->Eip);
       }
       else if (BreakPoint->Type == KdbBreakPointHardware)
       {
-         DbgPrint("Entered debugger on breakpoint #%d: %s 0x%08x\n",
+         KdbpPrint("Entered debugger on breakpoint #%d: %s 0x%08x\n",
                   KdbLastBreakPointNr,
                   (BreakPoint->Data.Hw.AccessType == KdbAccessRead) ? "READ" :
                   ((BreakPoint->Data.Hw.AccessType == KdbAccessWrite) ? "WRITE" :
@@ -1444,36 +1448,38 @@ KdbEnterDebuggerException(
          if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address, 0xCC,
                                                   &BreakPoint->Data.SavedInstruction)))
          {
-            DbgPrint("Warning: Couldn't reenable breakpoint %d\n",
+            KdbpPrint("Warning: Couldn't reenable breakpoint %d\n",
                      BreakPoint - KdbBreakPoints);
          }
 
          /* Unset TF if we are no longer single stepping. */
          if (KdbNumSingleSteps == 0)
-            TrapFrame->EFlags &= ~X86_EFLAGS_TF;
+            Context->EFlags &= ~EFLAGS_TF;
          goto continue_execution; /* return */
       }
 
       /* Check if we expect a single step */
       if ((TrapFrame->Dr6 & 0xf) == 0 && KdbNumSingleSteps > 0)
       {
-         /*ASSERT((TrapFrame->Eflags & X86_EFLAGS_TF) != 0);*/
+         /*ASSERT((Context->Eflags & EFLAGS_TF) != 0);*/
          if (--KdbNumSingleSteps > 0)
          {
             if ((KdbSingleStepOver && KdbpStepOverInstruction(TrapFrame->Eip)) ||
                 (!KdbSingleStepOver && KdbpStepIntoInstruction(TrapFrame->Eip)))
             {
-               TrapFrame->EFlags &= ~X86_EFLAGS_TF;
+               Context->EFlags &= ~EFLAGS_TF;
             }
             else
             {
-               TrapFrame->EFlags |= X86_EFLAGS_TF;
+               Context->EFlags |= EFLAGS_TF;
             }
-            goto continue_execution; /* return */
+                       goto continue_execution; /* return */
          }
-
-         TrapFrame->EFlags &= ~X86_EFLAGS_TF;
-         KdbEnteredOnSingleStep = TRUE;
+                else 
+                {
+                        Context->EFlags &= ~EFLAGS_TF;
+                        KdbEnteredOnSingleStep = TRUE;
+                }
       }
       else
       {
@@ -1481,7 +1487,7 @@ KdbEnterDebuggerException(
          {
             return kdHandleException;
          }
-         DbgPrint("Entered debugger on unexpected debug trap!\n");
+         KdbpPrint("Entered debugger on unexpected debug trap!\n");
       }
    }
    else if (ExceptionCode == STATUS_BREAKPOINT)
@@ -1496,7 +1502,7 @@ KdbEnterDebuggerException(
          return kdHandleException;
       }
 
-      DbgPrint("Entered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
+      KdbpPrint("Entered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
                TrapFrame->SegCs & 0xffff, TrapFrame->Eip - 1);
    }
    else
@@ -1510,7 +1516,7 @@ KdbEnterDebuggerException(
          return ContinueType;
       }
 
-      DbgPrint("Entered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
+      KdbpPrint("Entered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
                FirstChance ? "first" : "last", ExceptionCode, ExceptionString);
       if (ExceptionCode == STATUS_ACCESS_VIOLATION &&
           ExceptionRecord != NULL && ExceptionRecord->NumberParameters != 0)
@@ -1528,15 +1534,15 @@ KdbEnterDebuggerException(
 #endif
 
          Err = TrapFrame->ErrCode;
-         DbgPrint("Memory at 0x%p could not be %s: ", TrapCr2, (Err & (1 << 1)) ? "written" : "read");
+         KdbpPrint("Memory at 0x%p could not be %s: ", TrapCr2, (Err & (1 << 1)) ? "written" : "read");
          if ((Err & (1 << 0)) == 0)
-            DbgPrint("Page not present.\n");
+            KdbpPrint("Page not present.\n");
          else
          {
             if ((Err & (1 << 3)) != 0)
-               DbgPrint("Reserved bits in page directory set.\n");
+               KdbpPrint("Reserved bits in page directory set.\n");
             else
-               DbgPrint("Page protection violation.\n");
+               KdbpPrint("Page protection violation.\n");
          }
       }
    }
@@ -1572,12 +1578,12 @@ KdbEnterDebuggerException(
       if ((KdbSingleStepOver && KdbpStepOverInstruction(KdbCurrentTrapFrame->Tf.Eip)) ||
           (!KdbSingleStepOver && KdbpStepIntoInstruction(KdbCurrentTrapFrame->Tf.Eip)))
       {
-         ASSERT((KdbCurrentTrapFrame->Tf.EFlags & X86_EFLAGS_TF) == 0);
-         /*KdbCurrentTrapFrame->Tf.EFlags &= ~X86_EFLAGS_TF;*/
+         ASSERT((KdbCurrentTrapFrame->Tf.EFlags & EFLAGS_TF) == 0);
+         /*KdbCurrentTrapFrame->Tf.EFlags &= ~EFLAGS_TF;*/
       }
       else
       {
-         KdbCurrentTrapFrame->Tf.EFlags |= X86_EFLAGS_TF;
+         Context->EFlags |= EFLAGS_TF;
       }
    }
 
@@ -1599,14 +1605,22 @@ KdbEnterDebuggerException(
    /* Leave critical section */
    Ke386RestoreFlags(OldEflags);
 
+   /* Check if user requested a bugcheck */
+   if (KdbpBugCheckRequested)
+   {
+       /* Clear the flag and bugcheck the system */
+       KdbpBugCheckRequested = FALSE;
+       KeBugCheck(MANUALLY_INITIATED_CRASH);
+   }
+
 continue_execution:
    /* Clear debug status */
-   if (ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT) /* FIXME: Why clear DR6 on INT3? */
+   if (ExceptionCode == STATUS_BREAKPOINT) /* FIXME: Why clear DR6 on INT3? */
    {
       /* Set the RF flag so we don't trigger the same breakpoint again. */
       if (Resume)
       {
-         TrapFrame->EFlags |= X86_EFLAGS_RF;
+         TrapFrame->EFlags |= EFLAGS_RF;
       }
 
       /* Clear dr6 status flags. */
@@ -1628,12 +1642,12 @@ KdbDeleteProcessHook(IN PEPROCESS Process)
 }
 
 VOID
-STDCALL
+NTAPI
 KdbpGetCommandLineSettings(PCHAR p1)
 {
     PCHAR p2;
 
-    while (p1 && (p2 = strchr(p1, '/')))
+    while (p1 && (p2 = strchr(p1, ' ')))
     {
         p2++;
 
@@ -1658,21 +1672,31 @@ KdbpSafeReadMemory(OUT PVOID Dest,
                    IN PVOID Src,
                    IN ULONG Bytes)
 {
-   NTSTATUS Status = STATUS_SUCCESS;
+    BOOLEAN Result = TRUE;
 
-   _SEH_TRY
-   {
-      RtlCopyMemory(Dest,
-                    Src,
-                    Bytes);
-   }
-   _SEH_HANDLE
-   {
-      Status = _SEH_GetExceptionCode();
-   }
-   _SEH_END;
+    switch (Bytes)
+    {
+    case 1:
+    case 2:
+    case 4:
+    case 8:
+        Result = KdpSafeReadMemory((ULONG_PTR)Src, Bytes, Dest);
+        break;
+    default:
+    {
+        ULONG_PTR Start, End, Write;
+        for (Start = (ULONG_PTR)Src, 
+                 End = Start + Bytes, 
+                 Write = (ULONG_PTR)Dest; 
+             Result && (Start < End); 
+             Start++, Write++)
+            if (!KdpSafeReadMemory(Start, 1, (PVOID)Write))
+                Result = FALSE;
+        break;
+    }
+    }
 
-   return Status;
+    return Result ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION;
 }
 
 NTSTATUS
@@ -1680,19 +1704,16 @@ KdbpSafeWriteMemory(OUT PVOID Dest,
                     IN PVOID Src,
                     IN ULONG Bytes)
 {
-   NTSTATUS Status = STATUS_SUCCESS;
-
-   _SEH_TRY
-   {
-      RtlCopyMemory(Dest,
-                    Src,
-                    Bytes);
-   }
-   _SEH_HANDLE
-   {
-      Status = _SEH_GetExceptionCode();
-   }
-   _SEH_END;
-
-   return Status;
+    BOOLEAN Result = TRUE;
+    ULONG_PTR Start, End, Write;
+
+    for (Start = (ULONG_PTR)Src, 
+             End = Start + Bytes, 
+             Write = (ULONG_PTR)Dest; 
+         Result && (Start < End); 
+         Start++, Write++)
+        if (!KdpSafeWriteMemory(Write, 1, *((PCHAR)Start)))
+            Result = FALSE;
+
+    return Result ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION;
 }