ReactOS  0.4.14-dev-1332-g6db3d88
kdb.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for kdb.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define KDB_STACK_SIZE   (4096*3)
 
#define KDB_MAXIMUM_BREAKPOINT_COUNT   256
 
#define KDB_MAXIMUM_HW_BREAKPOINT_COUNT   4
 
#define KDB_MAXIMUM_SW_BREAKPOINT_COUNT   256
 
#define __STRING(x)   #x
 
#define _STRING(x)   __STRING(x)
 
#define CONST_STR_LEN(x)   (sizeof(x)/sizeof(x[0]) - 1)
 

Functions

ULONG NTAPI KiSsFromTrapFrame (IN PKTRAP_FRAME TrapFrame)
 
ULONG NTAPI KiEspFromTrapFrame (IN PKTRAP_FRAME TrapFrame)
 
VOID NTAPI KiSsToTrapFrame (IN PKTRAP_FRAME TrapFrame, IN ULONG Ss)
 
VOID NTAPI KiEspToTrapFrame (IN PKTRAP_FRAME TrapFrame, IN ULONG Esp)
 
static VOID KdbpTrapFrameToKdbTrapFrame (PKTRAP_FRAME TrapFrame, PKDB_KTRAP_FRAME KdbTrapFrame)
 
static VOID KdbpKdbTrapFrameToTrapFrame (PKDB_KTRAP_FRAME KdbTrapFrame, PKTRAP_FRAME TrapFrame)
 
static VOID KdbpKdbTrapFrameFromKernelStack (PVOID KernelStack, PKDB_KTRAP_FRAME KdbTrapFrame)
 
static NTSTATUS KdbpOverwriteInstruction (IN PEPROCESS Process, IN ULONG_PTR Address, IN UCHAR NewInst, OUT PUCHAR OldInst OPTIONAL)
 Overwrites the instruction at Address with NewInst and stores the old instruction in *OldInst. More...
 
BOOLEAN KdbpShouldStepOverInstruction (ULONG_PTR Eip)
 Checks whether the given instruction can be single stepped or has to be stepped over using a temporary breakpoint. More...
 
BOOLEAN KdbpStepOverInstruction (ULONG_PTR Eip)
 Steps over an instruction. More...
 
BOOLEAN KdbpStepIntoInstruction (ULONG_PTR Eip)
 Steps into an instruction (interrupts) More...
 
LONG KdbpGetNextBreakPointNr (IN ULONG Start OPTIONAL)
 Gets the number of the next breakpoint >= Start. More...
 
BOOLEAN KdbpGetBreakPointInfo (IN ULONG BreakPointNr, OUT ULONG_PTR *Address OPTIONAL, OUT KDB_BREAKPOINT_TYPE *Type OPTIONAL, OUT UCHAR *Size OPTIONAL, OUT KDB_ACCESS_TYPE *AccessType OPTIONAL, OUT UCHAR *DebugReg OPTIONAL, OUT BOOLEAN *Enabled OPTIONAL, OUT BOOLEAN *Global OPTIONAL, OUT PEPROCESS *Process OPTIONAL, OUT PCHAR *ConditionExpression OPTIONAL)
 Returns information of the specified breakpoint. More...
 
NTSTATUS KdbpInsertBreakPoint (IN ULONG_PTR Address, IN KDB_BREAKPOINT_TYPE Type, IN UCHAR Size OPTIONAL, IN KDB_ACCESS_TYPE AccessType OPTIONAL, IN PCHAR ConditionExpression OPTIONAL, IN BOOLEAN Global, OUT PLONG BreakPointNr OPTIONAL)
 Inserts a breakpoint into the breakpoint array. More...
 
BOOLEAN KdbpDeleteBreakPoint (IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
 Deletes a breakpoint. More...
 
static LONG KdbpIsBreakPointOurs (IN NTSTATUS ExceptionCode, IN PKTRAP_FRAME TrapFrame)
 Checks if the breakpoint was set by the debugger. More...
 
BOOLEAN KdbpEnableBreakPoint (IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
 Enables a breakpoint. More...
 
BOOLEAN KdbpDisableBreakPoint (IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
 Disables a breakpoint. More...
 
BOOLEAN KdbpGetEnterCondition (IN LONG ExceptionNr, IN BOOLEAN FirstChance, OUT KDB_ENTER_CONDITION *Condition)
 Gets the first or last chance enter-condition for exception nr. ExceptionNr. More...
 
BOOLEAN KdbpSetEnterCondition (IN LONG ExceptionNr, IN BOOLEAN FirstChance, IN KDB_ENTER_CONDITION Condition)
 Sets the first or last chance enter-condition for exception nr. ExceptionNr. More...
 
BOOLEAN KdbpAttachToThread (PVOID ThreadId)
 Switches to another thread context. More...
 
BOOLEAN KdbpAttachToProcess (PVOID ProcessId)
 Switches to another process/thread context. More...
 
static VOID KdbpCallMainLoop (VOID)
 Calls the main loop ... More...
 
static VOID KdbpInternalEnter (VOID)
 Internal function to enter KDB. More...
 
static ULONG KdbpGetExceptionNumberFromStatus (IN NTSTATUS ExceptionCode)
 
KD_CONTINUE_TYPE KdbEnterDebuggerException (IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL, IN KPROCESSOR_MODE PreviousMode, IN PCONTEXT Context, IN OUT PKTRAP_FRAME TrapFrame, IN BOOLEAN FirstChance)
 KDB Exception filter. More...
 
INIT_FUNCTION VOID NTAPI KdbpGetCommandLineSettings (PCHAR p1)
 
NTSTATUS KdbpSafeReadMemory (OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
 
NTSTATUS KdbpSafeWriteMemory (OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
 

Variables

static LONG KdbEntryCount = 0
 
static CHAR KdbStack [KDB_STACK_SIZE]
 
static ULONG KdbBreakPointCount = 0
 
static KDB_BREAKPOINT KdbBreakPoints [KDB_MAXIMUM_BREAKPOINT_COUNT] = {{0}}
 
static ULONG KdbSwBreakPointCount = 0
 
static ULONG KdbHwBreakPointCount = 0
 
static PKDB_BREAKPOINT KdbSwBreakPoints [KDB_MAXIMUM_SW_BREAKPOINT_COUNT]
 
static PKDB_BREAKPOINT KdbHwBreakPoints [KDB_MAXIMUM_HW_BREAKPOINT_COUNT]
 
static PKDB_BREAKPOINT KdbBreakPointToReenable = NULL
 
static BOOLEAN KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep
 
LONG KdbLastBreakPointNr = -1
 
ULONG KdbNumSingleSteps = 0
 
BOOLEAN KdbSingleStepOver = FALSE
 
ULONG KdbDebugState = 0
 
static BOOLEAN KdbEnteredOnSingleStep = FALSE
 
PEPROCESS KdbCurrentProcess = NULL
 
PEPROCESS KdbOriginalProcess = NULL
 
PETHREAD KdbCurrentThread = NULL
 
PETHREAD KdbOriginalThread = NULL
 
PKDB_KTRAP_FRAME KdbCurrentTrapFrame = NULL
 
static KDB_KTRAP_FRAME KdbTrapFrame = { { 0 } }
 
static KDB_KTRAP_FRAME KdbThreadTrapFrame = { { 0 } }
 
static KAPC_STATE KdbApcState
 
BOOLEAN KdbpBugCheckRequested
 
static KDB_ENTER_CONDITION KdbEnterConditions [][2]
 
static const CHARExceptionNrToString []
 

Macro Definition Documentation

◆ __STRING

#define __STRING (   x)    #x

Definition at line 25 of file kdb.c.

◆ _STRING

#define _STRING (   x)    __STRING(x)

Definition at line 26 of file kdb.c.

◆ CONST_STR_LEN

#define CONST_STR_LEN (   x)    (sizeof(x)/sizeof(x[0]) - 1)

◆ KDB_MAXIMUM_BREAKPOINT_COUNT

#define KDB_MAXIMUM_BREAKPOINT_COUNT   256

Definition at line 21 of file kdb.c.

◆ KDB_MAXIMUM_HW_BREAKPOINT_COUNT

#define KDB_MAXIMUM_HW_BREAKPOINT_COUNT   4

Definition at line 22 of file kdb.c.

◆ KDB_MAXIMUM_SW_BREAKPOINT_COUNT

#define KDB_MAXIMUM_SW_BREAKPOINT_COUNT   256

Definition at line 23 of file kdb.c.

◆ KDB_STACK_SIZE

#define KDB_STACK_SIZE   (4096*3)

Definition at line 20 of file kdb.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file kdb.c.

Function Documentation

◆ KdbEnterDebuggerException()

KD_CONTINUE_TYPE KdbEnterDebuggerException ( IN PEXCEPTION_RECORD ExceptionRecord  OPTIONAL,
IN KPROCESSOR_MODE  PreviousMode,
IN PCONTEXT  Context,
IN OUT PKTRAP_FRAME  TrapFrame,
IN BOOLEAN  FirstChance 
)

KDB Exception filter.

Called by the exception dispatcher.

Parameters
ExceptionRecordUnused.
PreviousModeUserMode if the exception was raised from umode, otherwise KernelMode.
ContextContext, IN/OUT parameter.
TrapFrameException TrapFrame.
FirstChanceTRUE when called before exception frames were serached, FALSE for the second call.
Returns
KD_CONTINUE_TYPE

Definition at line 1318 of file kdb.c.

1324 {
1325  KDB_ENTER_CONDITION EnterCondition;
1326  KD_CONTINUE_TYPE ContinueType = kdHandleException;
1327  PKDB_BREAKPOINT BreakPoint;
1328  ULONG ExpNr;
1329  ULONGLONG ull;
1330  BOOLEAN Resume = FALSE;
1331  BOOLEAN EnterConditionMet = TRUE;
1332  ULONG OldEflags;
1333  KIRQL OldIrql;
1335 
1336  ExceptionCode = (ExceptionRecord ? ExceptionRecord->ExceptionCode : STATUS_BREAKPOINT);
1337 
1339 
1340  /* Set continue type to kdContinue for single steps and breakpoints */
1344  {
1345  ContinueType = kdContinue;
1346  }
1347 
1348  /* Check if we should handle the exception. */
1349  /* FIXME - won't get all exceptions here :( */
1351  EnterCondition = KdbEnterConditions[ExpNr][FirstChance ? 0 : 1];
1352  if (EnterCondition == KdbDoNotEnter ||
1353  (EnterCondition == KdbEnterFromUmode && PreviousMode == KernelMode) ||
1354  (EnterCondition == KdbEnterFromKmode && PreviousMode != KernelMode))
1355  {
1356  EnterConditionMet = FALSE;
1357  }
1358 
1359  /* If we stopped on one of our breakpoints then let the user know */
1360  KdbLastBreakPointNr = -1;
1362 
1363  if (FirstChance && (ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT) &&
1365  {
1366  BreakPoint = KdbBreakPoints + KdbLastBreakPointNr;
1367 
1369  {
1370  /* ... and restore the original instruction */
1372  BreakPoint->Data.SavedInstruction, NULL)))
1373  {
1374  KdbpPrint("Couldn't restore original instruction after INT3! Cannot continue execution.\n");
1375  KeBugCheck(0); // FIXME: Proper bugcode!
1376  }
1377 
1378  /* Also since we are past the int3 now, decrement EIP in the
1379  TrapFrame. This is only needed because KDBG insists on working
1380  with the TrapFrame instead of with the Context, as it is supposed
1381  to do. The context has already EIP point to the int3, since
1382  KiDispatchException accounts for that. Whatever we do here with
1383  the TrapFrame does not matter anyway, since KiDispatchException
1384  will overwrite it with the values from the Context! */
1385  TrapFrame->Eip--;
1386  }
1387 
1388  if ((BreakPoint->Type == KdbBreakPointHardware) &&
1389  (BreakPoint->Data.Hw.AccessType == KdbAccessExec))
1390  {
1391  Resume = TRUE; /* Set the resume flag when continuing execution */
1392  }
1393 
1394  /*
1395  * When a temporary breakpoint is hit we have to make sure that we are
1396  * in the same context in which it was set, otherwise it could happen
1397  * that another process/thread hits it before and it gets deleted.
1398  */
1399  else if (BreakPoint->Type == KdbBreakPointTemporary &&
1400  BreakPoint->Process == KdbCurrentProcess)
1401  {
1402  ASSERT((TrapFrame->EFlags & EFLAGS_TF) == 0);
1403 
1404  /* Delete the temporary breakpoint which was used to step over or into the instruction */
1405  KdbpDeleteBreakPoint(-1, BreakPoint);
1406 
1407  if (--KdbNumSingleSteps > 0)
1408  {
1409  if ((KdbSingleStepOver && !KdbpStepOverInstruction(TrapFrame->Eip)) ||
1410  (!KdbSingleStepOver && !KdbpStepIntoInstruction(TrapFrame->Eip)))
1411  {
1412  Context->EFlags |= EFLAGS_TF;
1413  }
1414 
1415  goto continue_execution; /* return */
1416  }
1417 
1419  }
1420 
1421  /*
1422  * If we hit a breakpoint set by the debugger we set the single step flag,
1423  * ignore the next single step and reenable the breakpoint.
1424  */
1425  else if (BreakPoint->Type == KdbBreakPointSoftware ||
1426  BreakPoint->Type == KdbBreakPointTemporary)
1427  {
1429  Context->EFlags |= EFLAGS_TF;
1430  KdbBreakPointToReenable = BreakPoint;
1431  }
1432 
1433  /* Make sure that the breakpoint should be triggered in this context */
1434  if (!BreakPoint->Global && BreakPoint->Process != KdbCurrentProcess)
1435  {
1436  goto continue_execution; /* return */
1437  }
1438 
1439  /* Check if the condition for the breakpoint is met. */
1440  if (BreakPoint->Condition)
1441  {
1442  /* Setup the KDB trap frame */
1444 
1445  ull = 0;
1446  if (!KdbpRpnEvaluateParsedExpression(BreakPoint->Condition, &KdbTrapFrame, &ull, NULL, NULL))
1447  {
1448  /* FIXME: Print warning? */
1449  }
1450  else if (ull == 0) /* condition is not met */
1451  {
1452  goto continue_execution; /* return */
1453  }
1454  }
1455 
1456  if (BreakPoint->Type == KdbBreakPointSoftware)
1457  {
1458  KdbpPrint("\nEntered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
1459  KdbLastBreakPointNr, TrapFrame->SegCs & 0xffff, TrapFrame->Eip);
1460  }
1461  else if (BreakPoint->Type == KdbBreakPointHardware)
1462  {
1463  KdbpPrint("\nEntered debugger on breakpoint #%d: %s 0x%08x\n",
1465  (BreakPoint->Data.Hw.AccessType == KdbAccessRead) ? "READ" :
1466  ((BreakPoint->Data.Hw.AccessType == KdbAccessWrite) ? "WRITE" :
1467  ((BreakPoint->Data.Hw.AccessType == KdbAccessReadWrite) ? "RDWR" : "EXEC")),
1468  BreakPoint->Address);
1469  }
1470  }
1471  else if (ExceptionCode == STATUS_SINGLE_STEP)
1472  {
1473  /* Silently ignore a debugger initiated single step. */
1474  if ((TrapFrame->Dr6 & 0xf) == 0 && KdbBreakPointToReenable)
1475  {
1476  /* FIXME: Make sure that the breakpoint was really hit (check bp->Address vs. tf->Eip) */
1477  BreakPoint = KdbBreakPointToReenable;
1479  ASSERT(BreakPoint->Type == KdbBreakPointSoftware ||
1480  BreakPoint->Type == KdbBreakPointTemporary);
1481 
1482  /*
1483  * Reenable the breakpoint we disabled to execute the breakpointed
1484  * instruction.
1485  */
1487  &BreakPoint->Data.SavedInstruction)))
1488  {
1489  KdbpPrint("Warning: Couldn't reenable breakpoint %d\n",
1490  BreakPoint - KdbBreakPoints);
1491  }
1492 
1493  /* Unset TF if we are no longer single stepping. */
1494  if (KdbNumSingleSteps == 0)
1495  Context->EFlags &= ~EFLAGS_TF;
1496 
1498  {
1499  goto continue_execution; /* return */
1500  }
1501  }
1502 
1503  /* Quoth the raven, 'Nevermore!' */
1505 
1506  /* Check if we expect a single step */
1507  if ((TrapFrame->Dr6 & 0xf) == 0 && KdbNumSingleSteps > 0)
1508  {
1509  /*ASSERT((Context->Eflags & EFLAGS_TF) != 0);*/
1510  if (--KdbNumSingleSteps > 0)
1511  {
1512  if ((KdbSingleStepOver && KdbpStepOverInstruction(TrapFrame->Eip)) ||
1513  (!KdbSingleStepOver && KdbpStepIntoInstruction(TrapFrame->Eip)))
1514  {
1515  Context->EFlags &= ~EFLAGS_TF;
1516  }
1517  else
1518  {
1519  Context->EFlags |= EFLAGS_TF;
1520  }
1521 
1522  goto continue_execution; /* return */
1523  }
1524  else
1525  {
1526  Context->EFlags &= ~EFLAGS_TF;
1528  }
1529  }
1530  else
1531  {
1532  if (!EnterConditionMet)
1533  {
1534  return kdHandleException;
1535  }
1536 
1537  KdbpPrint("\nEntered debugger on unexpected debug trap!\n");
1538  }
1539  }
1540  else if (ExceptionCode == STATUS_BREAKPOINT)
1541  {
1542  if (KdbInitFileBuffer)
1543  {
1545  EnterConditionMet = FALSE;
1546  }
1547  if (!EnterConditionMet)
1548  {
1549  return kdHandleException;
1550  }
1551 
1552  KdbpPrint("\nEntered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
1553  TrapFrame->SegCs & 0xffff, TrapFrame->Eip - 1);
1554  }
1555  else
1556  {
1557  const CHAR *ExceptionString = (ExpNr < RTL_NUMBER_OF(ExceptionNrToString)) ?
1558  (ExceptionNrToString[ExpNr]) :
1559  ("Unknown/User defined exception");
1560 
1561  if (!EnterConditionMet)
1562  {
1563  return ContinueType;
1564  }
1565 
1566  KdbpPrint("\nEntered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
1567  FirstChance ? "first" : "last", ExceptionCode, ExceptionString);
1568 
1570  ExceptionRecord && ExceptionRecord->NumberParameters != 0)
1571  {
1572  /* FIXME: Add noexec memory stuff */
1573  ULONG_PTR TrapCr2;
1574  ULONG Err;
1575 
1576  TrapCr2 = __readcr2();
1577 
1578  Err = TrapFrame->ErrCode;
1579  KdbpPrint("Memory at 0x%p could not be %s: ", TrapCr2, (Err & (1 << 1)) ? "written" : "read");
1580 
1581  if ((Err & (1 << 0)) == 0)
1582  {
1583  KdbpPrint("Page not present.\n");
1584  }
1585  else
1586  {
1587  if ((Err & (1 << 3)) != 0)
1588  KdbpPrint("Reserved bits in page directory set.\n");
1589  else
1590  KdbpPrint("Page protection violation.\n");
1591  }
1592  }
1593  }
1594 
1595  /* Once we enter the debugger we do not expect any more single steps to happen */
1596  KdbNumSingleSteps = 0;
1597 
1598  /* Update the current process pointer */
1602 
1603  /* Setup the KDB trap frame */
1605 
1606  /* Enter critical section */
1607  OldEflags = __readeflags();
1608  _disable();
1609 
1610  /* HACK: Save the current IRQL and pretend we are at passive level,
1611  * although interrupts are off. Needed because KDBG calls pageable code. */
1614 
1615  /* Exception inside the debugger? Game over. */
1617  {
1618  __writeeflags(OldEflags);
1619  return kdHandleException;
1620  }
1621 
1622  /* Call the main loop */
1624 
1625  /* Check if we should single step */
1626  if (KdbNumSingleSteps > 0)
1627  {
1628  /* Variable explains itself! */
1630 
1633  {
1635  /*KdbCurrentTrapFrame->Tf.EFlags &= ~EFLAGS_TF;*/
1636  }
1637  else
1638  {
1639  Context->EFlags |= EFLAGS_TF;
1640  }
1641  }
1642 
1643  /* We can't update the current thread's trapframe 'cause it might not have one */
1644 
1645  /* Detach from attached process */
1647  {
1649  }
1650 
1651  /* Update the exception TrapFrame */
1653 
1654  /* Decrement the entry count */
1656 
1657  /* HACK: Raise back to old IRQL */
1659 
1660  /* Leave critical section */
1661  __writeeflags(OldEflags);
1662 
1663  /* Check if user requested a bugcheck */
1665  {
1666  /* Clear the flag and bugcheck the system */
1668  KeBugCheck(MANUALLY_INITIATED_CRASH);
1669  }
1670 
1671 continue_execution:
1672  /* Clear debug status */
1673  if (ExceptionCode == STATUS_BREAKPOINT) /* FIXME: Why clear DR6 on INT3? */
1674  {
1675  /* Set the RF flag so we don't trigger the same breakpoint again. */
1676  if (Resume)
1677  {
1678  TrapFrame->EFlags |= EFLAGS_RF;
1679  }
1680 
1681  /* Clear dr6 status flags. */
1682  TrapFrame->Dr6 &= ~0x0000e00f;
1683 
1685  {
1686  /* Skip the current instruction */
1687  Context->Eip++;
1688  }
1689  }
1690 
1691  return ContinueType;
1692 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
BOOLEAN KdbpDeleteBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Deletes a breakpoint.
Definition: kdb.c:654
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1782
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
static PKDB_BREAKPOINT KdbBreakPointToReenable
Definition: kdb.c:39
__INTRIN_INLINE unsigned long __readcr2(void)
Definition: intrin_x86.h:1699
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
BOOLEAN Global
Definition: kdb.h:44
static VOID KdbpInternalEnter(VOID)
Internal function to enter KDB.
Definition: kdb.c:1213
BOOLEAN KdbpStepIntoInstruction(ULONG_PTR Eip)
Steps into an instruction (interrupts)
Definition: kdb.c:355
PETHREAD KdbOriginalThread
Definition: kdb.c:50
PEPROCESS KdbCurrentProcess
Definition: kdb.c:47
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_SINGLE_STEP
Definition: ntstatus.h:173
BOOLEAN KdbpStepOverInstruction(ULONG_PTR Eip)
Steps over an instruction.
Definition: kdb.c:327
VOID KdbpCliInterpretInitFile(VOID)
This function is called by KdbEnterDebuggerException...
Definition: kdb_cli.c:3719
PEPROCESS KdbOriginalProcess
Definition: kdb.c:48
uint32_t ULONG_PTR
Definition: typedefs.h:64
static ULONG KdbpGetExceptionNumberFromStatus(IN NTSTATUS ExceptionCode)
Definition: kdb.c:1252
UCHAR KIRQL
Definition: env_spec_w32.h:591
static LONG KdbpIsBreakPointOurs(IN NTSTATUS ExceptionCode, IN PKTRAP_FRAME TrapFrame)
Checks if the breakpoint was set by the debugger.
Definition: kdb.c:704
static LONG KdbEntryCount
Definition: kdb.c:30
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1555
static KDB_ENTER_CONDITION KdbEnterConditions[][2]
Definition: kdb.c:58
static VOID KdbpKdbTrapFrameToTrapFrame(PKDB_KTRAP_FRAME KdbTrapFrame, PKTRAP_FRAME TrapFrame)
Definition: kdb.c:158
static const CHAR * ExceptionNrToString[]
Definition: kdb.c:86
static NTSTATUS KdbpOverwriteInstruction(IN PEPROCESS Process, IN ULONG_PTR Address, IN UCHAR NewInst, OUT PUCHAR OldInst OPTIONAL)
Overwrites the instruction at Address with NewInst and stores the old instruction in *OldInst.
Definition: kdb.c:210
static BOOLEAN KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep
Definition: kdb.c:41
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_BREAKPOINT
Definition: ntstatus.h:172
ULONG_PTR Address
Definition: kdb.h:43
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
PVOID Condition
Definition: kdb.h:47
static VOID KdbpTrapFrameToKdbTrapFrame(PKTRAP_FRAME TrapFrame, PKDB_KTRAP_FRAME KdbTrapFrame)
Definition: kdb.c:136
PKDB_KTRAP_FRAME KdbCurrentTrapFrame
Definition: kdb.c:51
#define STATUS_ASSERTION_FAILURE
Definition: ntstatus.h:946
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:66
VOID KdbpPrint(IN PCHAR Format, IN ... OPTIONAL)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:2651
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _KDB_BREAKPOINT::@1766::@1767 Hw
ULONG KdbNumSingleSteps
Definition: kdb.c:43
#define InterlockedDecrement
Definition: armddk.h:52
enum _KDB_ENTER_CONDITION KDB_ENTER_CONDITION
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1550
#define EFLAGS_RF
Definition: cpu.c:19
BOOLEAN KdbSingleStepOver
Definition: kdb.c:44
#define EFLAGS_TF
Definition: ketypes.h:125
BOOLEAN KdbpBugCheckRequested
Definition: kdb_cli.c:125
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
ULONG Eip
Definition: ketypes.h:267
BOOLEAN KdbpRpnEvaluateParsedExpression(IN PVOID Expression, IN PKDB_KTRAP_FRAME TrapFrame, OUT PULONGLONG Result, OUT PLONG ErrOffset OPTIONAL, OUT PCHAR ErrMsg OPTIONAL)
Evaluates the given expression and returns the result.
Definition: kdb_expr.c:1185
PEPROCESS Process
Definition: kdb.h:45
UCHAR SavedInstruction
Definition: kdb.h:50
#define InterlockedIncrement
Definition: armddk.h:53
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
KTRAP_FRAME Tf
Definition: kdb.h:15
LONG KdbLastBreakPointNr
Definition: kdb.c:42
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:753
static KAPC_STATE KdbApcState
Definition: kdb.c:54
static KDB_KTRAP_FRAME KdbTrapFrame
Definition: kdb.c:52
PETHREAD KdbCurrentThread
Definition: kdb.c:49
void __cdecl _disable(void)
Definition: intrin_arm.h:365
unsigned int ULONG
Definition: retypes.h:1
union _KDB_BREAKPOINT::@1766 Data
static KDB_BREAKPOINT KdbBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT]
Definition: kdb.c:34
KDB_BREAKPOINT_TYPE Type
Definition: kdb.h:41
static BOOLEAN KdbEnteredOnSingleStep
Definition: kdb.c:46
ULONG EFlags
Definition: ketypes.h:384
PCHAR KdbInitFileBuffer
Definition: kdb_cli.c:124

Referenced by KdpEnterDebuggerException().

◆ KdbpAttachToProcess()

BOOLEAN KdbpAttachToProcess ( PVOID  ProcessId)

Switches to another process/thread context.

This function switches to the first thread in the specified process.

Parameters
ProcessIdId of the process to switch to.
Return values
TRUESuccess.
FALSEFailure (i.e. invalid process id)

Definition at line 1173 of file kdb.c.

1175 {
1177  PETHREAD Thread;
1179 
1180  /* Get a pointer to the process */
1182  {
1183  KdbpPrint("Invalid process id: 0x%08x\n", (ULONG_PTR)ProcessId);
1184  return FALSE;
1185  }
1186 
1187  Entry = Process->ThreadListHead.Flink;
1190  {
1191  KdbpPrint("No threads in process 0x%p, cannot attach to process!\n", ProcessId);
1192  return FALSE;
1193  }
1194 
1195  Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
1196 
1198 }
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2697
struct _Entry Entry
Definition: kefuncs.h:627
BOOLEAN KdbpAttachToThread(PVOID ThreadId)
Switches to another thread context.
Definition: kdb.c:1092
PEPROCESS KdbCurrentProcess
Definition: kdb.c:47
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
uint32_t ULONG_PTR
Definition: typedefs.h:64
smooth NULL
Definition: ftsmooth.c:416
LIST_ENTRY ThreadListHead
Definition: pstypes.h:1260
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CLIENT_ID Cid
Definition: pstypes.h:1059
VOID KdbpPrint(IN PCHAR Format, IN ... OPTIONAL)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:2651
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
HANDLE UniqueThread
Definition: compat.h:483
NTSTATUS NTAPI PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process)
Definition: process.c:919
Definition: typedefs.h:118
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
base of all file and directory entries
Definition: entries.h:82

Referenced by KdbpCmdProc().

◆ KdbpAttachToThread()

BOOLEAN KdbpAttachToThread ( PVOID  ThreadId)

Switches to another thread context.

Parameters
ThreadIdId of the thread to switch to.
Return values
TRUESuccess.
FALSEFailure (i.e. invalid thread id)

Definition at line 1092 of file kdb.c.

1094 {
1095  PETHREAD Thread = NULL;
1097 
1098  /* Get a pointer to the thread */
1099  if (!NT_SUCCESS(PsLookupThreadByThreadId(ThreadId, &Thread)))
1100  {
1101  KdbpPrint("Invalid thread id: 0x%08x\n", (ULONG_PTR)ThreadId);
1102  return FALSE;
1103  }
1104  Process = Thread->ThreadsProcess;
1105 
1107  {
1108  KdbpPrint("Cannot attach to thread within another process while executing a DPC.\n");
1110  return FALSE;
1111  }
1112 
1113  /* Save the current thread's context (if we previously attached to a thread) */
1115  {
1117  /* Actually, we can't save the context, there's no guarantee that there was a trap frame */
1118  }
1119  else
1120  {
1122  }
1123 
1124  /* Switch to the thread's context */
1125  if (Thread != KdbOriginalThread)
1126  {
1127  /* The thread we're attaching to isn't the thread on which we entered
1128  * kdb and so the thread we're attaching to is not running. There
1129  * is no guarantee that it actually has a trap frame. So we have to
1130  * peek directly at the registers which were saved on the stack when the
1131  * thread was preempted in the scheduler */
1135  }
1136  else /* Switching back to original thread */
1137  {
1139  }
1141 
1142  /* Attach to the thread's process */
1144  if (KdbCurrentProcess != Process)
1145  {
1146  if (KdbCurrentProcess != KdbOriginalProcess) /* detach from previously attached process */
1147  {
1149  }
1150 
1151  if (KdbOriginalProcess != Process)
1152  {
1154  }
1155 
1157  }
1158 
1160  return TRUE;
1161 }
#define TRUE
Definition: types.h:120
PETHREAD KdbOriginalThread
Definition: kdb.c:50
PEPROCESS KdbCurrentProcess
Definition: kdb.c:47
NTSTATUS NTAPI PsLookupThreadByThreadId(IN HANDLE ThreadId, OUT PETHREAD *Thread)
Definition: thread.c:643
KTHREAD Tcb
Definition: pstypes.h:1034
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
static VOID KdbpKdbTrapFrameFromKernelStack(PVOID KernelStack, PKDB_KTRAP_FRAME KdbTrapFrame)
Definition: kdb.c:174
BOOLEAN NTAPI KeIsExecutingDpc(VOID)
Definition: dpc.c:946
static KDB_KTRAP_FRAME KdbThreadTrapFrame
Definition: kdb.c:53
PEPROCESS KdbOriginalProcess
Definition: kdb.c:48
uint32_t ULONG_PTR
Definition: typedefs.h:64
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:701
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
PVOID KernelStack
Definition: ketypes.h:1565
PKDB_KTRAP_FRAME KdbCurrentTrapFrame
Definition: kdb.c:51
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID KdbpPrint(IN PCHAR Format, IN ... OPTIONAL)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:2651
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:753
static KAPC_STATE KdbApcState
Definition: kdb.c:54
static KDB_KTRAP_FRAME KdbTrapFrame
Definition: kdb.c:52
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
PETHREAD KdbCurrentThread
Definition: kdb.c:49

Referenced by KdbpAttachToProcess(), and KdbpCmdThread().

◆ KdbpCallMainLoop()

static VOID KdbpCallMainLoop ( VOID  )
static

Calls the main loop ...

Definition at line 1203 of file kdb.c.

1204 {
1206 }
VOID KdbpCliMainLoop(IN BOOLEAN EnteredOnSingleStep)
KDB Main Loop.
Definition: kdb_cli.c:3641
static BOOLEAN KdbEnteredOnSingleStep
Definition: kdb.c:46

Referenced by KdbpInternalEnter().

◆ KdbpDeleteBreakPoint()

BOOLEAN KdbpDeleteBreakPoint ( IN LONG BreakPointNr  OPTIONAL,
IN OUT PKDB_BREAKPOINT BreakPoint  OPTIONAL 
)

Deletes a breakpoint.

Parameters
BreakPointNrNumber of the breakpoint to delete. Can be -1
BreakPointBreakpoint to delete. Can be NULL.
Return values
TRUESuccess.
FALSEFailure (invalid breakpoint number)

Definition at line 654 of file kdb.c.

657 {
658  if (BreakPointNr < 0)
659  {
660  ASSERT(BreakPoint);
661  BreakPointNr = BreakPoint - KdbBreakPoints;
662  }
663 
664  if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
665  {
666  KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
667  return FALSE;
668  }
669 
670  if (!BreakPoint)
671  {
672  BreakPoint = KdbBreakPoints + BreakPointNr;
673  }
674 
675  if (BreakPoint->Type == KdbBreakPointNone)
676  {
677  KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
678  return FALSE;
679  }
680 
681  if (BreakPoint->Enabled && !KdbpDisableBreakPoint(-1, BreakPoint))
682  return FALSE;
683 
684  if (BreakPoint->Type != KdbBreakPointTemporary)
685  KdbpPrint("Breakpoint %d deleted.\n", BreakPointNr);
686 
687  BreakPoint->Type = KdbBreakPointNone;
689 
690  return TRUE;
691 }
#define TRUE
Definition: types.h:120
static ULONG KdbBreakPointCount
Definition: kdb.c:33
#define KDB_MAXIMUM_BREAKPOINT_COUNT
Definition: kdb.c:21
BOOLEAN KdbpDisableBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Disables a breakpoint.
Definition: kdb.c:924
VOID KdbpPrint(IN PCHAR Format, IN ... OPTIONAL)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:2651
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static KDB_BREAKPOINT KdbBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT]
Definition: kdb.c:34

Referenced by KdbEnterDebuggerException(), and KdbpCmdEnableDisableClearBreakPoint().

◆ KdbpDisableBreakPoint()

BOOLEAN KdbpDisableBreakPoint ( IN LONG BreakPointNr  OPTIONAL,
IN OUT PKDB_BREAKPOINT BreakPoint  OPTIONAL 
)

Disables a breakpoint.

Parameters
BreakPointNrNumber of the breakpoint to disable. Can be -1
BreakPointBreakpoint to disable. Can be NULL.
Return values
TRUESuccess.
FALSEFailure.
See also
KdbpEnableBreakPoint

Definition at line 924 of file kdb.c.

927 {
928  ULONG i;
930 
931  if (BreakPointNr < 0)
932  {
933  ASSERT(BreakPoint);
934  BreakPointNr = BreakPoint - KdbBreakPoints;
935  }
936 
937  if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
938  {
939  KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
940  return FALSE;
941  }
942 
943  if (!BreakPoint)
944  {
945  BreakPoint = KdbBreakPoints + BreakPointNr;
946  }
947 
948  if (BreakPoint->Type == KdbBreakPointNone)
949  {
950  KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
951  return FALSE;
952  }
953 
954  if (BreakPoint->Enabled == FALSE)
955  {
956  KdbpPrint("Breakpoint %d is not enabled.\n", BreakPointNr);
957  return TRUE;
958  }
959 
960  if (BreakPoint->Type == KdbBreakPointSoftware ||
961  BreakPoint->Type == KdbBreakPointTemporary)
962  {
964  Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
965  BreakPoint->Data.SavedInstruction, NULL);
966 
967  if (!NT_SUCCESS(Status))
968  {
969  KdbpPrint("Couldn't restore original instruction.\n");
970  return FALSE;
971  }
972 
973  for (i = 0; i < KdbSwBreakPointCount; i++)
974  {
975  if (KdbSwBreakPoints[i] == BreakPoint)
976  {
978  i = -1; /* if the last breakpoint is disabled dont break with i >= KdbSwBreakPointCount */
979  break;
980  }
981  }
982 
983  if (i != MAXULONG) /* not found */
984  ASSERT(0);
985  }
986  else
987  {
988  ASSERT(BreakPoint->Type == KdbBreakPointHardware);
989 
990  /* Clear the breakpoint. */
991  KdbTrapFrame.Tf.Dr7 &= ~(0x3 << (BreakPoint->Data.Hw.DebugReg * 2));
992  if ((KdbTrapFrame.Tf.Dr7 & 0xFF) == 0)
993  {
994  /* If no breakpoints are enabled then clear the exact match flags. */
995  KdbTrapFrame.Tf.Dr7 &= 0xFFFFFCFF;
996  }
997 
998  for (i = 0; i < KdbHwBreakPointCount; i++)
999  {
1000  if (KdbHwBreakPoints[i] == BreakPoint)
1001  {
1003  i = -1; /* if the last breakpoint is disabled dont break with i >= KdbHwBreakPointCount */
1004  break;
1005  }
1006  }
1007 
1008  if (i != MAXULONG) /* not found */
1009  ASSERT(0);
1010  }
1011 
1012  BreakPoint->Enabled = FALSE;
1013  if (BreakPoint->Type != KdbBreakPointTemporary)
1014  KdbpPrint("Breakpoint %d disabled.\n", BreakPointNr);
1015 
1016  return TRUE;
1017 }
#define TRUE
Definition: types.h:120
#define KDB_MAXIMUM_BREAKPOINT_COUNT
Definition: kdb.c:21
static ULONG KdbSwBreakPointCount
Definition: kdb.c:35
LONG NTSTATUS
Definition: precomp.h:26
static PKDB_BREAKPOINT KdbHwBreakPoints[KDB_MAXIMUM_HW_BREAKPOINT_COUNT]
Definition: kdb.c:38
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static NTSTATUS KdbpOverwriteInstruction(IN PEPROCESS Process, IN ULONG_PTR Address, IN UCHAR NewInst, OUT PUCHAR OldInst OPTIONAL)
Overwrites the instruction at Address with NewInst and stores the old instruction in *OldInst.
Definition: kdb.c:210
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static PKDB_BREAKPOINT KdbSwBreakPoints[KDB_MAXIMUM_SW_BREAKPOINT_COUNT]
Definition: kdb.c:37
VOID KdbpPrint(IN PCHAR Format, IN ... OPTIONAL)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:2651
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
#define MAXULONG
Definition: typedefs.h:250
KTRAP_FRAME Tf
Definition: kdb.h:15
static KDB_KTRAP_FRAME KdbTrapFrame
Definition: kdb.c:52
unsigned int ULONG
Definition: retypes.h:1
UINT64 Dr7
Definition: ketypes.h:347
static KDB_BREAKPOINT KdbBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT]
Definition: kdb.c:34
static ULONG KdbHwBreakPointCount
Definition: kdb.c:36

Referenced by KdbpCmdEnableDisableClearBreakPoint(), and KdbpDeleteBreakPoint().

◆ KdbpEnableBreakPoint()

BOOLEAN KdbpEnableBreakPoint ( IN LONG BreakPointNr  OPTIONAL,
IN OUT PKDB_BREAKPOINT BreakPoint  OPTIONAL 
)

Enables a breakpoint.

Parameters
BreakPointNrNumber of the breakpoint to enable Can be -1.
BreakPointBreakpoint to enable. Can be NULL.
Return values
TRUESuccess.
FALSEFailure.
See also
KdbpDisableBreakPoint

Definition at line 757 of file kdb.c.

760 {
762  INT i;
763  ULONG ul;
764 
765  if (BreakPointNr < 0)
766  {
767  ASSERT(BreakPoint);
768  BreakPointNr = BreakPoint - KdbBreakPoints;
769  }
770 
771  if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
772  {
773  KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
774  return FALSE;
775  }
776 
777  if (!BreakPoint)
778  {
779  BreakPoint = KdbBreakPoints + BreakPointNr;
780  }
781 
782  if (BreakPoint->Type == KdbBreakPointNone)
783  {
784  KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
785  return FALSE;
786  }
787 
788  if (BreakPoint->Enabled)
789  {
790  KdbpPrint("Breakpoint %d is already enabled.\n", BreakPointNr);
791  return TRUE;
792  }
793 
794  if (BreakPoint->Type == KdbBreakPointSoftware ||
795  BreakPoint->Type == KdbBreakPointTemporary)
796  {
798  {
799  KdbpPrint("Maximum number of SW breakpoints (%d) used. "
800  "Disable another breakpoint in order to enable this one.\n",
802  return FALSE;
803  }
804 
805  Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
806  0xCC, &BreakPoint->Data.SavedInstruction);
807  if (!NT_SUCCESS(Status))
808  {
809  KdbpPrint("Couldn't access memory at 0x%p\n", BreakPoint->Address);
810  return FALSE;
811  }
812 
813  KdbSwBreakPoints[KdbSwBreakPointCount++] = BreakPoint;
814  }
815  else
816  {
817  if (BreakPoint->Data.Hw.AccessType == KdbAccessExec)
818  ASSERT(BreakPoint->Data.Hw.Size == 1);
819 
820  ASSERT((BreakPoint->Address % BreakPoint->Data.Hw.Size) == 0);
821 
823  {
824  KdbpPrint("Maximum number of HW breakpoints (%d) already used. "
825  "Disable another breakpoint in order to enable this one.\n",
827 
828  return FALSE;
829  }
830 
831  /* Find unused hw breakpoint */
833  for (i = 0; i < KDB_MAXIMUM_HW_BREAKPOINT_COUNT; i++)
834  {
835  if ((KdbTrapFrame.Tf.Dr7 & (0x3 << (i * 2))) == 0)
836  break;
837  }
838 
840 
841  /* Set the breakpoint address. */
842  switch (i)
843  {
844  case 0:
845  KdbTrapFrame.Tf.Dr0 = BreakPoint->Address;
846  break;
847  case 1:
848  KdbTrapFrame.Tf.Dr1 = BreakPoint->Address;
849  break;
850  case 2:
851  KdbTrapFrame.Tf.Dr2 = BreakPoint->Address;
852  break;
853  case 3:
854  KdbTrapFrame.Tf.Dr3 = BreakPoint->Address;
855  break;
856  }
857 
858  /* Enable the global breakpoint */
859  KdbTrapFrame.Tf.Dr7 |= (0x2 << (i * 2));
860 
861  /* Enable the exact match bits. */
862  KdbTrapFrame.Tf.Dr7 |= 0x00000300;
863 
864  /* Clear existing state. */
865  KdbTrapFrame.Tf.Dr7 &= ~(0xF << (16 + (i * 4)));
866 
867  /* Set the breakpoint type. */
868  switch (BreakPoint->Data.Hw.AccessType)
869  {
870  case KdbAccessExec:
871  ul = 0;
872  break;
873  case KdbAccessWrite:
874  ul = 1;
875  break;
876  case KdbAccessRead:
877  case KdbAccessReadWrite:
878  ul = 3;
879  break;
880  default:
881  ASSERT(0);
882  return TRUE;
883  break;
884  }
885 
886  KdbTrapFrame.Tf.Dr7 |= (ul << (16 + (i * 4)));
887 
888  /* Set the breakpoint length. */
889  KdbTrapFrame.Tf.Dr7 |= ((BreakPoint->Data.Hw.Size - 1) << (18 + (i * 4)));
890 
891  /* Update KdbCurrentTrapFrame - values are taken from there by the CLI */
893  {
900  }
901 
902  BreakPoint->Data.Hw.DebugReg = i;
903  KdbHwBreakPoints[KdbHwBreakPointCount++] = BreakPoint;
904  }
905 
906  BreakPoint->Enabled = TRUE;
907  if (BreakPoint->Type != KdbBreakPointTemporary)
908  KdbpPrint("Breakpoint %d enabled.\n", BreakPointNr);
909 
910  return TRUE;
911 }
#define KDB_MAXIMUM_SW_BREAKPOINT_COUNT
Definition: kdb.c:23
#define TRUE
Definition: types.h:120
#define KDB_MAXIMUM_BREAKPOINT_COUNT
Definition: kdb.c:21
static ULONG KdbSwBreakPointCount
Definition: kdb.c:35
LONG NTSTATUS
Definition: precomp.h:26
int32_t INT
Definition: typedefs.h:57
static PKDB_BREAKPOINT KdbHwBreakPoints[KDB_MAXIMUM_HW_BREAKPOINT_COUNT]
Definition: kdb.c:38
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
UINT64 Dr2
Definition: ketypes.h:344
static NTSTATUS KdbpOverwriteInstruction(IN PEPROCESS Process, IN ULONG_PTR Address, IN UCHAR NewInst, OUT PUCHAR OldInst OPTIONAL)
Overwrites the instruction at Address with NewInst and stores the old instruction in *OldInst.
Definition: kdb.c:210
PKDB_KTRAP_FRAME KdbCurrentTrapFrame
Definition: kdb.c:51
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static PKDB_BREAKPOINT KdbSwBreakPoints[KDB_MAXIMUM_SW_BREAKPOINT_COUNT]
Definition: kdb.c:37
VOID KdbpPrint(IN PCHAR Format, IN ... OPTIONAL)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:2651
UINT64 Dr6
Definition: ketypes.h:346
UINT64 Dr3
Definition: ketypes.h:345
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
UINT64 Dr1
Definition: ketypes.h:343
UINT64 Dr0
Definition: ketypes.h:342
#define KDB_MAXIMUM_HW_BREAKPOINT_COUNT
Definition: kdb.c:22
Status
Definition: gdiplustypes.h:24
KTRAP_FRAME Tf
Definition: kdb.h:15
static KDB_KTRAP_FRAME KdbTrapFrame
Definition: kdb.c:52
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN Enabled
Definition: kdb.h:42
UINT64 Dr7
Definition: ketypes.h:347
static KDB_BREAKPOINT KdbBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT]
Definition: kdb.c:34
static ULONG KdbHwBreakPointCount
Definition: kdb.c:36

Referenced by KdbpCmdEnableDisableClearBreakPoint(), and KdbpInsertBreakPoint().

◆ KdbpGetBreakPointInfo()

BOOLEAN KdbpGetBreakPointInfo ( IN ULONG  BreakPointNr,
OUT ULONG_PTR *Address  OPTIONAL,
OUT KDB_BREAKPOINT_TYPE *Type  OPTIONAL,
OUT UCHAR *Size  OPTIONAL,
OUT KDB_ACCESS_TYPE *AccessType  OPTIONAL,
OUT UCHAR *DebugReg  OPTIONAL,
OUT BOOLEAN *Enabled  OPTIONAL,
OUT BOOLEAN *Global  OPTIONAL,
OUT PEPROCESS *Process  OPTIONAL,
OUT PCHAR *ConditionExpression  OPTIONAL 
)

Returns information of the specified breakpoint.

Parameters
BreakPointNrNumber of the breakpoint to return information of.
AddressReceives the address of the breakpoint.
TypeReceives the type of the breakpoint (hardware or software)
SizeSize - for memory breakpoints.
AccessTypeAccess type - for hardware breakpoints.
DebugRegDebug register - for enabled hardware breakpoints.
EnabledWhether the breakpoint is enabled or not.
ProcessThe owning process of the breakpoint.
ConditionExpressionThe expression which was given as condition for the bp.
Returns
NULL on failure, pointer to a KDB_BREAKPOINT struct on success.

Definition at line 464 of file kdb.c.

475 {
476  PKDB_BREAKPOINT bp;
477 
478  if (BreakPointNr >= RTL_NUMBER_OF(KdbBreakPoints) ||
479  KdbBreakPoints[BreakPointNr].Type == KdbBreakPointNone)
480  {
481  return FALSE;
482  }
483 
484  bp = KdbBreakPoints + BreakPointNr;
485  if (Address)
486  *Address = bp->Address;
487 
488  if (Type)
489  *Type = bp->Type;
490 
491  if (bp->Type == KdbBreakPointHardware)
492  {
493  if (Size)
494  *Size = bp->Data.Hw.Size;
495 
496  if (AccessType)
497  *AccessType = bp->Data.Hw.AccessType;
498 
499  if (DebugReg && bp->Enabled)
500  *DebugReg = bp->Data.Hw.DebugReg;
501  }
502 
503  if (Enabled)
504  *Enabled = bp->Enabled;
505 
506  if (Global)
507  *Global = bp->Global;
508 
509  if (Process)
510  *Process = bp->Process;
511 
512  if (ConditionExpression)
513  *ConditionExpression = bp->ConditionExpression;
514 
515  return TRUE;
516 }
#define TRUE
Definition: types.h:120
Type
Definition: Type.h:6
BOOLEAN Global
Definition: kdb.h:44
PCHAR ConditionExpression
Definition: kdb.h:46
UNICODE_STRING Global
Definition: symlink.c:37
static WCHAR Address[46]
Definition: ping.c:68
ULONG_PTR Address
Definition: kdb.h:43
struct _KDB_BREAKPOINT::@1766::@1767 Hw
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
PEPROCESS Process
Definition: kdb.h:45
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
union _KDB_BREAKPOINT::@1766 Data
BOOLEAN Enabled
Definition: kdb.h:42
static KDB_BREAKPOINT KdbBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT]
Definition: kdb.c:34
KDB_BREAKPOINT_TYPE Type
Definition: kdb.h:41

Referenced by KdbpCmdBreakPointList().

◆ KdbpGetCommandLineSettings()

INIT_FUNCTION VOID NTAPI KdbpGetCommandLineSettings ( PCHAR  p1)

Definition at line 1697 of file kdb.c.

1699 {
1700 #define CONST_STR_LEN(x) (sizeof(x)/sizeof(x[0]) - 1)
1701 
1702  while (p1 && (p1 = strchr(p1, ' ')))
1703  {
1704  /* Skip other spaces */
1705  while (*p1 == ' ') ++p1;
1706 
1707  if (!_strnicmp(p1, "KDSERIAL", CONST_STR_LEN("KDSERIAL")))
1708  {
1709  p1 += CONST_STR_LEN("KDSERIAL");
1711  KdpDebugMode.Serial = TRUE;
1712  }
1713  else if (!_strnicmp(p1, "KDNOECHO", CONST_STR_LEN("KDNOECHO")))
1714  {
1715  p1 += CONST_STR_LEN("KDNOECHO");
1717  }
1718  else if (!_strnicmp(p1, "FIRSTCHANCE", CONST_STR_LEN("FIRSTCHANCE")))
1719  {
1720  p1 += CONST_STR_LEN("FIRSTCHANCE");
1722  }
1723  }
1724 }
BOOLEAN KdbpSetEnterCondition(IN LONG ExceptionNr, IN BOOLEAN FirstChance, IN KDB_ENTER_CONDITION Condition)
Sets the first or last chance enter-condition for exception nr. ExceptionNr.
Definition: kdb.c:1051
#define TRUE
Definition: types.h:120
KDP_DEBUG_MODE KdpDebugMode
Definition: kdinit.c:25
ULONG KdbDebugState
Definition: kdb.c:45
_Check_return_ _CRTIMP int __cdecl _strnicmp(_In_reads_or_z_(_MaxCount) const char *_Str1, _In_reads_or_z_(_MaxCount) const char *_Str2, _In_ size_t _MaxCount)
#define CONST_STR_LEN(x)
char * strchr(const char *String, int ch)
Definition: utclib.c:501

Referenced by KdInitSystem().

◆ KdbpGetEnterCondition()

BOOLEAN KdbpGetEnterCondition ( IN LONG  ExceptionNr,
IN BOOLEAN  FirstChance,
OUT KDB_ENTER_CONDITION Condition 
)

Gets the first or last chance enter-condition for exception nr. ExceptionNr.

Parameters
ExceptionNrNumber of the exception to get condition of.
FirstChanceWhether to get first or last chance condition.
ConditionReceives the condition setting.
Return values
TRUESuccess.
FALSEFailure (invalid exception nr)

Definition at line 1029 of file kdb.c.

1033 {
1034  if (ExceptionNr >= (LONG)RTL_NUMBER_OF(KdbEnterConditions))
1035  return FALSE;
1036 
1037  *Condition = KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1];
1038  return TRUE;
1039 }
#define TRUE
Definition: types.h:120
static KDB_ENTER_CONDITION KdbEnterConditions[][2]
Definition: kdb.c:58
long LONG
Definition: pedump.c:60
IN ULONG IN UCHAR Condition
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12

Referenced by KdbpCmdSet().

◆ KdbpGetExceptionNumberFromStatus()

static ULONG KdbpGetExceptionNumberFromStatus ( IN NTSTATUS  ExceptionCode)
static

Definition at line 1252 of file kdb.c.

1254 {
1255  ULONG Ret;
1256 
1257  switch (ExceptionCode)
1258  {
1260  Ret = 0;
1261  break;
1262  case STATUS_SINGLE_STEP:
1263  Ret = 1;
1264  break;
1265  case STATUS_BREAKPOINT:
1266  Ret = 3;
1267  break;
1269  Ret = 4;
1270  break;
1272  Ret = 5;
1273  break;
1275  Ret = 6;
1276  break;
1278  Ret = 7;
1279  break;
1280  case STATUS_STACK_OVERFLOW:
1281  Ret = 12;
1282  break;
1284  Ret = 14;
1285  break;
1287  Ret = 17;
1288  break;
1290  Ret = 18;
1291  break;
1293  Ret = 20;
1294  break;
1295 
1296  default:
1297  Ret = RTL_NUMBER_OF(KdbEnterConditions) - 1;
1298  break;
1299  }
1300 
1301  return Ret;
1302 }
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1782
#define STATUS_ILLEGAL_INSTRUCTION
Definition: ntstatus.h:252
#define STATUS_SINGLE_STEP
Definition: ntstatus.h:173
#define STATUS_INTEGER_OVERFLOW
Definition: ntstatus.h:371
static KDB_ENTER_CONDITION KdbEnterConditions[][2]
Definition: kdb.c:58
#define STATUS_INTEGER_DIVIDE_BY_ZERO
Definition: ntstatus.h:370
#define STATUS_BREAKPOINT
Definition: ntstatus.h:172
#define STATUS_ASSERTION_FAILURE
Definition: ntstatus.h:946
#define STATUS_FLOAT_MULTIPLE_TRAPS
Definition: ntstatus.h:794
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define STATUS_STACK_OVERFLOW
Definition: ntstatus.h:475
#define STATUS_DATATYPE_MISALIGNMENT
Definition: ntstatus.h:171
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_FLOAT_INVALID_OPERATION
Definition: ntstatus.h:366
#define STATUS_ARRAY_BOUNDS_EXCEEDED
Definition: ntstatus.h:362

Referenced by KdbEnterDebuggerException().

◆ KdbpGetNextBreakPointNr()

LONG KdbpGetNextBreakPointNr ( IN ULONG Start  OPTIONAL)

Gets the number of the next breakpoint >= Start.

Parameters
StartBreakpoint number to start searching at. -1 if no more breakpoints are found.
Returns
Breakpoint number (-1 if no more breakpoints are found)

Definition at line 437 of file kdb.c.

439 {
441  {
443  return Start;
444  }
445 
446  return -1;
447 }
Type
Definition: Type.h:6
Definition: partlist.h:33
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
static KDB_BREAKPOINT KdbBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT]
Definition: kdb.c:34

Referenced by KdbpCmdBreakPointList().

◆ KdbpInsertBreakPoint()

NTSTATUS KdbpInsertBreakPoint ( IN ULONG_PTR  Address,
IN KDB_BREAKPOINT_TYPE  Type,
IN UCHAR Size  OPTIONAL,
IN KDB_ACCESS_TYPE AccessType  OPTIONAL,
IN PCHAR ConditionExpression  OPTIONAL,
IN BOOLEAN  Global,
OUT PLONG BreakPointNr  OPTIONAL 
)

Inserts a breakpoint into the breakpoint array.

The Process of the breakpoint is set to KdbCurrentProcess

Parameters
AddressAddress at which to set the breakpoint.
TypeType of breakpoint (hardware or software)
SizeSize of breakpoint (for hardware/memory breakpoints)
AccessTypeAccess type (for hardware breakpoins)
ConditionExpressionExpression which must evaluate to true for conditional breakpoints.
GlobalWether the breakpoint is global or local to a process.
BreakPointNumberReceives the breakpoint number on success
Returns
NTSTATUS

Definition at line 533 of file kdb.c.

541 {
542  LONG i;
544  PCHAR ConditionExpressionDup;
545  LONG ErrOffset;
546  CHAR ErrMsg[128];
547 
549 
551  {
552  if ((Address % Size) != 0)
553  {
554  KdbpPrint("Address (0x%p) must be aligned to a multiple of the size (%d)\n", Address, Size);
555  return STATUS_UNSUCCESSFUL;
556  }
557 
558  if (AccessType == KdbAccessExec && Size != 1)
559  {
560  KdbpPrint("Size must be 1 for execution breakpoints.\n");
561  return STATUS_UNSUCCESSFUL;
562  }
563  }
564 
566  {
567  return STATUS_UNSUCCESSFUL;
568  }
569 
570  /* Parse conditon expression string and duplicate it */
571  if (ConditionExpression)
572  {
573  Condition = KdbpRpnParseExpression(ConditionExpression, &ErrOffset, ErrMsg);
574  if (!Condition)
575  {
576  if (ErrOffset >= 0)
577  KdbpPrint("Couldn't parse expression: %s at character %d\n", ErrMsg, ErrOffset);
578  else
579  KdbpPrint("Couldn't parse expression: %s", ErrMsg);
580 
581  return STATUS_UNSUCCESSFUL;
582  }
583 
584  i = strlen(ConditionExpression) + 1;
585  ConditionExpressionDup = ExAllocatePoolWithTag(NonPagedPool, i, TAG_KDBG);
586  RtlCopyMemory(ConditionExpressionDup, ConditionExpression, i);
587  }
588  else
589  {
590  Condition = NULL;
591  ConditionExpressionDup = NULL;
592  }
593 
594  /* Find unused breakpoint */
596  {
597  for (i = RTL_NUMBER_OF(KdbBreakPoints) - 1; i >= 0; i--)
598  {
600  break;
601  }
602  }
603  else
604  {
605  for (i = 0; i < (LONG)RTL_NUMBER_OF(KdbBreakPoints); i++)
606  {
608  break;
609  }
610  }
611 
613 
614  /* Set the breakpoint */
621  KdbBreakPoints[i].ConditionExpression = ConditionExpressionDup;
623 
625  {
626  KdbBreakPoints[i].Data.Hw.Size = Size;
627  KdbBreakPoints[i].Data.Hw.AccessType = AccessType;
628  }
629 
631 
633  KdbpPrint("Breakpoint %d inserted.\n", i);
634 
635  /* Try to enable the breakpoint */
637 
638  /* Return the breakpoint number */
639  if (BreakPointNr)
640  *BreakPointNr = i;
641 
642  return STATUS_SUCCESS;
643 }
#define TAG_KDBG
Definition: kdb.h:8
signed char * PCHAR
Definition: retypes.h:7
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
PVOID KdbpRpnParseExpression(IN PCHAR Expression, OUT PLONG ErrOffset OPTIONAL, OUT PCHAR ErrMsg OPTIONAL)
Parses the given expression and returns a "handle" to it.
Definition: kdb_expr.c:1131
Type
Definition: Type.h:6
BOOLEAN Global
Definition: kdb.h:44
static ULONG KdbBreakPointCount
Definition: kdb.c:33
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define KDB_MAXIMUM_BREAKPOINT_COUNT
Definition: kdb.c:21
PEPROCESS KdbCurrentProcess
Definition: kdb.c:47
char CHAR
Definition: xmlstorage.h:175
PCHAR ConditionExpression
Definition: kdb.h:46
UNICODE_STRING Global
Definition: symlink.c:37
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
ULONG_PTR Address
Definition: kdb.h:43
PVOID Condition
Definition: kdb.h:47
IN ULONG IN UCHAR Condition
BOOLEAN KdbpEnableBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Enables a breakpoint.
Definition: kdb.c:757
VOID KdbpPrint(IN PCHAR Format, IN ... OPTIONAL)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:2651
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
struct _KDB_BREAKPOINT::@1766::@1767 Hw
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
PEPROCESS Process
Definition: kdb.h:45
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
union _KDB_BREAKPOINT::@1766 Data
BOOLEAN Enabled
Definition: kdb.h:42
static KDB_BREAKPOINT KdbBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT]
Definition: kdb.c:34
return STATUS_SUCCESS
Definition: btrfs.c:2938
KDB_BREAKPOINT_TYPE Type
Definition: kdb.h:41

Referenced by KdbpCmdBreakPoint(), KdbpStepIntoInstruction(), and KdbpStepOverInstruction().

◆ KdbpInternalEnter()

static VOID KdbpInternalEnter ( VOID  )
static

Internal function to enter KDB.

Disables interrupts, releases display ownership, ...

Definition at line 1213 of file kdb.c.

1214 {
1215  PETHREAD Thread;
1216  PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
1217  ULONG SavedStackLimit;
1218 
1219  KbdDisableMouse();
1220 
1221  /* Take control of the display */
1222  if (KdpDebugMode.Screen)
1223  KdpScreenAcquire();
1224 
1225  /* Call the interface's main loop on a different stack */
1227  SavedInitialStack = Thread->Tcb.InitialStack;
1228  SavedStackBase = Thread->Tcb.StackBase;
1229  SavedStackLimit = Thread->Tcb.StackLimit;
1230  SavedKernelStack = Thread->Tcb.KernelStack;
1234 
1235  // KdbpPrint("Switching to KDB stack 0x%08x-0x%08x (Current Stack is 0x%08x)\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase, Esp);
1236 
1238 
1239  Thread->Tcb.InitialStack = SavedInitialStack;
1240  Thread->Tcb.StackBase = SavedStackBase;
1241  Thread->Tcb.StackLimit = SavedStackLimit;
1242  Thread->Tcb.KernelStack = SavedKernelStack;
1243 
1244  /* Release the display */
1245  if (KdpDebugMode.Screen)
1246  KdpScreenRelease();
1247 
1248  KbdEnableMouse();
1249 }
KDP_DEBUG_MODE KdpDebugMode
Definition: kdinit.c:25
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
KTHREAD Tcb
Definition: pstypes.h:1034
static CHAR KdbStack[KDB_STACK_SIZE]
Definition: kdb.c:31
VOID NTAPI KdbpStackSwitchAndCall(IN PVOID NewStack, IN VOID(*Function)(VOID))
VOID KdpScreenRelease(VOID)
Definition: kdio.c:431
VOID KbdEnableMouse(VOID)
PVOID KernelStack
Definition: ketypes.h:1565
VOID KdpScreenAcquire(VOID)
Definition: kdio.c:412
#define KDB_STACK_SIZE
Definition: kdb.c:20
volatile VOID * StackLimit
Definition: ketypes.h:1555
VOID KbdDisableMouse(VOID)
static VOID KdbpCallMainLoop(VOID)
Calls the main loop ...
Definition: kdb.c:1203
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
PVOID StackBase
Definition: ketypes.h:1556
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
PVOID InitialStack
Definition: ketypes.h:1554

Referenced by KdbEnterDebuggerException().

◆ KdbpIsBreakPointOurs()

static LONG KdbpIsBreakPointOurs ( IN NTSTATUS  ExceptionCode,
IN PKTRAP_FRAME  TrapFrame 
)
static

Checks if the breakpoint was set by the debugger.

Tries to find a breakpoint in the breakpoint array which caused the debug exception to happen.

Parameters
ExpNrException Number (1 or 3)
TrapFrameException trapframe
Returns
Breakpoint number, -1 on error.

Definition at line 704 of file kdb.c.

707 {
708  ULONG i;
710 
711  if (ExceptionCode == STATUS_BREAKPOINT) /* Software interrupt */
712  {
713  ULONG_PTR BpEip = (ULONG_PTR)TrapFrame->Eip - 1; /* Get EIP of INT3 instruction */
714  for (i = 0; i < KdbSwBreakPointCount; i++)
715  {
719 
720  if (KdbSwBreakPoints[i]->Address == BpEip)
721  {
723  }
724  }
725  }
726  else if (ExceptionCode == STATUS_SINGLE_STEP) /* Hardware interrupt */
727  {
728  UCHAR DebugReg;
729 
730  for (i = 0; i < KdbHwBreakPointCount; i++)
731  {
734  DebugReg = KdbHwBreakPoints[i]->Data.Hw.DebugReg;
735 
736  if ((TrapFrame->Dr6 & (1 << DebugReg)) != 0)
737  {
739  }
740  }
741  }
742 
743  return -1;
744 }
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1782
Type
Definition: Type.h:6
static ULONG KdbSwBreakPointCount
Definition: kdb.c:35
#define STATUS_SINGLE_STEP
Definition: ntstatus.h:173
uint32_t ULONG_PTR
Definition: typedefs.h:64
static PKDB_BREAKPOINT KdbHwBreakPoints[KDB_MAXIMUM_HW_BREAKPOINT_COUNT]
Definition: kdb.c:38
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static WCHAR Address[46]
Definition: ping.c:68
#define STATUS_BREAKPOINT
Definition: ntstatus.h:172
static PKDB_BREAKPOINT KdbSwBreakPoints[KDB_MAXIMUM_SW_BREAKPOINT_COUNT]
Definition: kdb.c:37
#define for
Definition: utility.h:88
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _KDB_BREAKPOINT::@1766::@1767 Hw
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned int ULONG
Definition: retypes.h:1
union _KDB_BREAKPOINT::@1766 Data
#define ULONG_PTR
Definition: config.h:101
static KDB_BREAKPOINT KdbBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT]
Definition: kdb.c:34
static ULONG KdbHwBreakPointCount
Definition: kdb.c:36

Referenced by KdbEnterDebuggerException().

◆ KdbpKdbTrapFrameFromKernelStack()

static VOID KdbpKdbTrapFrameFromKernelStack ( PVOID  KernelStack,
PKDB_KTRAP_FRAME  KdbTrapFrame 
)
static

Definition at line 174 of file kdb.c.

177 {
178  ULONG_PTR *StackPtr;
179 
181  StackPtr = (ULONG_PTR *) KernelStack;
182 #ifdef _M_IX86
183  KdbTrapFrame->Tf.Ebp = StackPtr[3];
184  KdbTrapFrame->Tf.Edi = StackPtr[4];
185  KdbTrapFrame->Tf.Esi = StackPtr[5];
186  KdbTrapFrame->Tf.Ebx = StackPtr[6];
187  KdbTrapFrame->Tf.Eip = StackPtr[7];
188  KdbTrapFrame->Tf.HardwareEsp = (ULONG) (StackPtr + 8);
194 #endif
195 
196  /* FIXME: what about the other registers??? */
197 }
#define KGDT_R0_CODE
Definition: ketypes.h:75
ULONG HardwareSegSs
Definition: ketypes.h:271
ULONG Esi
Definition: ketypes.h:263
ULONG Edi
Definition: ketypes.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:64
USHORT SegGs
Definition: ketypes.h:367
USHORT SegEs
Definition: ketypes.h:365
USHORT SegCs
Definition: ketypes.h:380
#define KGDT_R0_DATA
Definition: ketypes.h:76
ULONG HardwareEsp
Definition: ketypes.h:270
USHORT SegDs
Definition: ketypes.h:364
ULONG Eip
Definition: ketypes.h:267
ULONG Ebx
Definition: ketypes.h:264
KTRAP_FRAME Tf
Definition: kdb.h:15
static KDB_KTRAP_FRAME KdbTrapFrame
Definition: kdb.c:52
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
ULONG Ebp
Definition: ketypes.h:265

Referenced by KdbpAttachToThread().

◆ KdbpKdbTrapFrameToTrapFrame()

static VOID KdbpKdbTrapFrameToTrapFrame ( PKDB_KTRAP_FRAME  KdbTrapFrame,
PKTRAP_FRAME  TrapFrame 
)
static

Definition at line 158 of file kdb.c.

161 {
162  /* Copy the TrapFrame only up to Eflags and zero the rest*/
163  RtlCopyMemory(TrapFrame, &KdbTrapFrame->Tf, FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
164 
165  /* FIXME: write cr0, cr2, cr3 and cr4 (not needed atm) */
166 
169 
170  /* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
171 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
ULONG HardwareSegSs
Definition: ketypes.h:271
ULONG HardwareEsp
Definition: ketypes.h:270
VOID NTAPI KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame, IN ULONG_PTR Esp)
Definition: kdb.c:25
KTRAP_FRAME Tf
Definition: kdb.h:15
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
static KDB_KTRAP_FRAME KdbTrapFrame
Definition: kdb.c:52
VOID NTAPI KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame, IN ULONG Ss)
Definition: kdb.c:96

Referenced by KdbEnterDebuggerException().

◆ KdbpOverwriteInstruction()

static NTSTATUS KdbpOverwriteInstruction ( IN PEPROCESS  Process,
IN ULONG_PTR  Address,
IN UCHAR  NewInst,
OUT PUCHAR OldInst  OPTIONAL 
)
static

Overwrites the instruction at Address with NewInst and stores the old instruction in *OldInst.

Parameters
ProcessProcess in which's context to overwrite the instruction.
AddressAddress at which to overwrite the instruction.
NewInstNew instruction (written to Address)
OldInstOld instruction (read from Address)
Returns
NTSTATUS

Definition at line 210 of file kdb.c.

215 {
217  ULONG Protect;
220 
221  /* Get the protection for the address. */
223 
224  /* Return if that page isn't present. */
225  if (Protect & PAGE_NOACCESS)
226  {
228  }
229 
230  /* Attach to the process */
231  if (CurrentProcess != Process)
232  {
234  }
235 
236  /* Make the page writeable if it is read only. */
238  {
241  }
242 
243  /* Copy the old instruction back to the caller. */
244  if (OldInst)
245  {
246  Status = KdbpSafeReadMemory(OldInst, (PUCHAR)Address, 1);
247  if (!NT_SUCCESS(Status))
248  {
250  {
252  }
253 
254  /* Detach from process */
255  if (CurrentProcess != Process)
256  {
257  KeDetachProcess();
258  }
259 
260  return Status;
261  }
262  }
263 
264  /* Copy the new instruction in its place. */
265  Status = KdbpSafeWriteMemory((PUCHAR)Address, &NewInst, 1);
266 
267  /* Restore the page protection. */
269  {
271  }
272 
273  /* Detach from process */
274  if (CurrentProcess != Process)
275  {
277  }
278 
279  return Status;
280 }
KAPC_STATE
Definition: ketypes.h:1273
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG _In_ ULONG Protect
Definition: zwfuncs.h:214
ULONG NTAPI MmGetPageProtect(struct _EPROCESS *Process, PVOID Address)
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:701
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define PAGE_NOACCESS
Definition: nt_native.h:1302
static WCHAR Address[46]
Definition: ping.c:68
#define PAGE_EXECUTE
Definition: nt_native.h:1306
ULONG CurrentProcess
Definition: shell.c:125
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS KdbpSafeWriteMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
Definition: kdb.c:1741
VOID NTAPI MmSetPageProtect(struct _EPROCESS *Process, PVOID Address, ULONG flProtect)
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:618
Status
Definition: gdiplustypes.h:24
NTSTATUS KdbpSafeReadMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
Definition: kdb.c:1727
#define STATUS_MEMORY_NOT_ALLOCATED
Definition: ntstatus.h:382
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:753
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1492
#define PAGE_READONLY
Definition: compat.h:127
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
unsigned int ULONG
Definition: retypes.h:1
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAGE_READWRITE
Definition: nt_native.h:1304

Referenced by KdbEnterDebuggerException(), KdbpDisableBreakPoint(), and KdbpEnableBreakPoint().

◆ KdbpSafeReadMemory()

NTSTATUS KdbpSafeReadMemory ( OUT PVOID  Dest,
IN PVOID  Src,
IN ULONG  Bytes 
)

Definition at line 1727 of file kdb.c.

1731 {
1732  return KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Src,
1733  Dest,
1734  Bytes,
1735  0,
1737  NULL);
1738 }
NTSTATUS NTAPI KdpCopyMemoryChunks(_In_ ULONG64 Address, _In_ PVOID Buffer, _In_ ULONG TotalSize, _In_ ULONG ChunkSize, _In_ ULONG Flags, _Out_opt_ PULONG ActualSize)
Definition: kdapi.c:50
_In_ UINT Bytes
Definition: mmcopy.h:9
uint32_t ULONG_PTR
Definition: typedefs.h:64
smooth NULL
Definition: ftsmooth.c:416
unsigned __int64 ULONG64
Definition: imports.h:198
#define MMDBG_COPY_UNSAFE
Definition: mm.h:55

Referenced by KdbpCmdBackTrace(), KdbpCmdDisassembleX(), KdbpCmdGdtLdtIdt(), KdbpCmdThread(), KdbpIsNestedTss(), KdbpOverwriteInstruction(), KdbpReadMemory(), KdbpRetrieveTss(), KdbpShouldStepOverInstruction(), KdbpStepIntoInstruction(), KdbpSymReadMem(), KdbpTrapFrameFromPrevTss(), and RpnpEvaluateStack().

◆ KdbpSafeWriteMemory()

NTSTATUS KdbpSafeWriteMemory ( OUT PVOID  Dest,
IN PVOID  Src,
IN ULONG  Bytes 
)

Definition at line 1741 of file kdb.c.

1745 {
1746  return KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Dest,
1747  Src,
1748  Bytes,
1749  0,
1751  NULL);
1752 }
NTSTATUS NTAPI KdpCopyMemoryChunks(_In_ ULONG64 Address, _In_ PVOID Buffer, _In_ ULONG TotalSize, _In_ ULONG ChunkSize, _In_ ULONG Flags, _Out_opt_ PULONG ActualSize)
Definition: kdapi.c:50
_In_ UINT Bytes
Definition: mmcopy.h:9
uint32_t ULONG_PTR
Definition: typedefs.h:64
smooth NULL
Definition: ftsmooth.c:416
#define MMDBG_COPY_WRITE
Definition: mm.h:53
unsigned __int64 ULONG64
Definition: imports.h:198
#define MMDBG_COPY_UNSAFE
Definition: mm.h:55

Referenced by KdbpOverwriteInstruction().

◆ KdbpSetEnterCondition()

BOOLEAN KdbpSetEnterCondition ( IN LONG  ExceptionNr,
IN BOOLEAN  FirstChance,
IN KDB_ENTER_CONDITION  Condition 
)

Sets the first or last chance enter-condition for exception nr. ExceptionNr.

Parameters
ExceptionNrNumber of the exception to set condition of (-1 for all)
FirstChanceWhether to set first or last chance condition.
ConditionThe new condition setting.
Return values
TRUESuccess.
FALSEFailure (invalid exception nr)

Definition at line 1051 of file kdb.c.

1055 {
1056  if (ExceptionNr < 0)
1057  {
1058  for (ExceptionNr = 0; ExceptionNr < (LONG)RTL_NUMBER_OF(KdbEnterConditions); ExceptionNr++)
1059  {
1060  if (ExceptionNr == 1 || ExceptionNr == 8 ||
1061  ExceptionNr == 9 || ExceptionNr == 15) /* Reserved exceptions */
1062  {
1063  continue;
1064  }
1065 
1066  KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
1067  }
1068  }
1069  else
1070  {
1071  if (ExceptionNr >= (LONG)RTL_NUMBER_OF(KdbEnterConditions) ||
1072  ExceptionNr == 1 || ExceptionNr == 8 || /* Do not allow changing of the debug */
1073  ExceptionNr == 9 || ExceptionNr == 15) /* trap or reserved exceptions */
1074  {
1075  return FALSE;
1076  }
1077 
1078  KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
1079  }
1080 
1081  return TRUE;
1082 }
#define TRUE
Definition: types.h:120
static KDB_ENTER_CONDITION KdbEnterConditions[][2]
Definition: kdb.c:58
long LONG
Definition: pedump.c:60
IN ULONG IN UCHAR Condition
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12

Referenced by KdbpCmdSet(), and KdbpGetCommandLineSettings().

◆ KdbpShouldStepOverInstruction()

BOOLEAN KdbpShouldStepOverInstruction ( ULONG_PTR  Eip)

Checks whether the given instruction can be single stepped or has to be stepped over using a temporary breakpoint.

Return values
TRUEInstruction is a call.
FALSEInstruction is not a call.

Definition at line 289 of file kdb.c.

291 {
292  UCHAR Mem[3];
293  ULONG i = 0;
294 
295  if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
296  {
297  KdbpPrint("Couldn't access memory at 0x%p\n", Eip);
298  return FALSE;
299  }
300 
301  /* Check if the current instruction is a call. */
302  while ((i < sizeof (Mem)) && (Mem[i] == 0x66 || Mem[i] == 0x67))
303  i++;
304 
305  if (i == sizeof (Mem))
306  return FALSE;
307 
308  if (Mem[i] == 0xE8 || Mem[i] == 0x9A || Mem[i] == 0xF2 || Mem[i] == 0xF3 ||
309  (((i + 1) < sizeof (Mem)) && Mem[i] == 0xFF && (Mem[i+1] & 0x38) == 0x10))
310  {
311  return TRUE;
312  }
313 
314  return FALSE;
315 }
#define TRUE
Definition: types.h:120
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID KdbpPrint(IN PCHAR Format, IN ... OPTIONAL)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:2651
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS KdbpSafeReadMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
Definition: kdb.c:1727
unsigned int ULONG
Definition: retypes.h:1

Referenced by KdbpStepOverInstruction().

◆ KdbpStepIntoInstruction()

BOOLEAN KdbpStepIntoInstruction ( ULONG_PTR  Eip)

Steps into an instruction (interrupts)

If the given instruction should be stepped into, this function inserts a temporary breakpoint at the target instruction and returns TRUE, otherwise it returns FALSE.

Return values
TRUETemporary breakpoint set at target instruction.
FALSENo breakpoint was set.

Definition at line 355 of file kdb.c.

357 {
358  KDESCRIPTOR Idtr = {0};
359  UCHAR Mem[2];
360  INT IntVect;
361  ULONG IntDesc[2];
362  ULONG_PTR TargetEip;
363 
364  /* Read memory */
365  if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
366  {
367  /*KdbpPrint("Couldn't access memory at 0x%p\n", Eip);*/
368  return FALSE;
369  }
370 
371  /* Check for INT instruction */
372  /* FIXME: Check for iret */
373  if (Mem[0] == 0xcc)
374  IntVect = 3;
375  else if (Mem[0] == 0xcd)
376  IntVect = Mem[1];
377  else if (Mem[0] == 0xce && KdbCurrentTrapFrame->Tf.EFlags & (1<<11)) /* 1 << 11 is the overflow flag */
378  IntVect = 4;
379  else
380  return FALSE;
381 
382  if (IntVect < 32) /* We should be informed about interrupts < 32 by the kernel, no need to breakpoint them */
383  {
384  return FALSE;
385  }
386 
387  /* Read the interrupt descriptor table register */
388  __sidt(&Idtr.Limit);
389  if (IntVect >= (Idtr.Limit + 1) / 8)
390  {
391  /*KdbpPrint("IDT does not contain interrupt vector %d.\n", IntVect);*/
392  return TRUE;
393  }
394 
395  /* Get the interrupt descriptor */
396  if (!NT_SUCCESS(KdbpSafeReadMemory(IntDesc, (PVOID)(ULONG_PTR)(Idtr.Base + (IntVect * 8)), sizeof (IntDesc))))
397  {
398  /*KdbpPrint("Couldn't access memory at 0x%p\n", (ULONG_PTR)Idtr.Base + (IntVect * 8));*/
399  return FALSE;
400  }
401 
402  /* Check descriptor and get target eip (16 bit interrupt/trap gates not supported) */
403  if ((IntDesc[1] & (1 << 15)) == 0) /* not present */
404  {
405  return FALSE;
406  }
407  if ((IntDesc[1] & 0x1f00) == 0x0500) /* Task gate */
408  {
409  /* FIXME: Task gates not supported */
410  return FALSE;
411  }
412  else if (((IntDesc[1] & 0x1fe0) == 0x0e00) || /* 32 bit Interrupt gate */
413  ((IntDesc[1] & 0x1fe0) == 0x0f00)) /* 32 bit Trap gate */
414  {
415  /* FIXME: Should the segment selector of the interrupt gate be checked? */
416  TargetEip = (IntDesc[1] & 0xffff0000) | (IntDesc[0] & 0x0000ffff);
417  }
418  else
419  {
420  return FALSE;
421  }
422 
423  /* Insert breakpoint */
425  return FALSE;
426 
427  return TRUE;
428 }
#define TRUE
Definition: types.h:120
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
NTSTATUS KdbpInsertBreakPoint(IN ULONG_PTR Address, IN KDB_BREAKPOINT_TYPE Type, IN UCHAR Size OPTIONAL, IN KDB_ACCESS_TYPE AccessType OPTIONAL, IN PCHAR ConditionExpression OPTIONAL, IN BOOLEAN Global, OUT PLONG BreakPointNr OPTIONAL)
Inserts a breakpoint into the breakpoint array.
Definition: kdb.c:533
int32_t INT
Definition: typedefs.h:57
PVOID Base
Definition: ketypes.h:486
USHORT Limit
Definition: ketypes.h:485
uint32_t ULONG_PTR
Definition: typedefs.h:64
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:1920
smooth NULL
Definition: ftsmooth.c:416
PKDB_KTRAP_FRAME KdbCurrentTrapFrame
Definition: kdb.c:51
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS KdbpSafeReadMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
Definition: kdb.c:1727
KTRAP_FRAME Tf
Definition: kdb.h:15
unsigned int ULONG
Definition: retypes.h:1
ULONG EFlags
Definition: ketypes.h:384

Referenced by KdbEnterDebuggerException().

◆ KdbpStepOverInstruction()

BOOLEAN KdbpStepOverInstruction ( ULONG_PTR  Eip)

Steps over an instruction.

If the given instruction should be stepped over, this function inserts a temporary breakpoint after the instruction and returns TRUE, otherwise it returns FALSE.

Return values
TRUETemporary breakpoint set after instruction.
FALSENo breakpoint was set.

Definition at line 327 of file kdb.c.

329 {
330  LONG InstLen;
331 
333  return FALSE;
334 
335  InstLen = KdbpGetInstLength(Eip);
336  if (InstLen < 1)
337  return FALSE;
338 
339  if (!NT_SUCCESS(KdbpInsertBreakPoint(Eip + InstLen, KdbBreakPointTemporary, 0, 0, NULL, FALSE, NULL)))
340  return FALSE;
341 
342  return TRUE;
343 }
#define TRUE
Definition: types.h:120
NTSTATUS KdbpInsertBreakPoint(IN ULONG_PTR Address, IN KDB_BREAKPOINT_TYPE Type, IN UCHAR Size OPTIONAL, IN KDB_ACCESS_TYPE AccessType OPTIONAL, IN PCHAR ConditionExpression OPTIONAL, IN BOOLEAN Global, OUT PLONG BreakPointNr OPTIONAL)
Inserts a breakpoint into the breakpoint array.
Definition: kdb.c:533
LONG KdbpGetInstLength(IN ULONG_PTR Address)
Definition: i386-dis.c:97
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN KdbpShouldStepOverInstruction(ULONG_PTR Eip)
Checks whether the given instruction can be single stepped or has to be stepped over using a temporar...
Definition: kdb.c:289

Referenced by KdbEnterDebuggerException().

◆ KdbpTrapFrameToKdbTrapFrame()

static VOID KdbpTrapFrameToKdbTrapFrame ( PKTRAP_FRAME  TrapFrame,
PKDB_KTRAP_FRAME  KdbTrapFrame 
)
static

Definition at line 136 of file kdb.c.

139 {
140  /* Copy the TrapFrame only up to Eflags and zero the rest*/
141  RtlCopyMemory(&KdbTrapFrame->Tf, TrapFrame, FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
143  sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
144 
149 
151  KdbTrapFrame->Tf.HardwareSegSs = (USHORT)(KiSsFromTrapFrame(TrapFrame) & 0xFFFF);
152 
153 
154  /* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
155 }
ULONG NTAPI KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
Definition: kdb.c:18
ULONG Cr3
Definition: kdb.h:19
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
__INTRIN_INLINE unsigned long __readcr2(void)
Definition: intrin_x86.h:1699
ULONG Cr4
Definition: kdb.h:20
ULONG HardwareSegSs
Definition: ketypes.h:271
__INTRIN_INLINE unsigned long __readcr3(void)
Definition: intrin_x86.h:1706
uint32_t ULONG_PTR
Definition: typedefs.h:64
ULONG NTAPI KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
Definition: kdb.c:80
ULONG HardwareEsp
Definition: ketypes.h:270
__INTRIN_INLINE unsigned long __readcr0(void)
Definition: intrin_x86.h:1692
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1713
ULONG Cr0
Definition: kdb.h:16
unsigned short USHORT
Definition: pedump.c:61
KTRAP_FRAME Tf
Definition: kdb.h:15
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
static KDB_KTRAP_FRAME KdbTrapFrame
Definition: kdb.c:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
ULONG Cr2
Definition: kdb.h:18

Referenced by KdbEnterDebuggerException().

◆ KiEspFromTrapFrame()

ULONG NTAPI KiEspFromTrapFrame ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 18 of file kdb.c.

19 {
20  return TrapFrame->Rsp;
21 }

Referenced by KdbpTrapFrameToKdbTrapFrame(), KeTrapFrameToContext(), and KiEspToTrapFrame().

◆ KiEspToTrapFrame()

VOID NTAPI KiEspToTrapFrame ( IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Esp 
)

Definition at line 25 of file kdb.c.

27 {
28  KIRQL OldIrql;
29  ULONG Previous;
30 
31  /* Raise to APC_LEVEL if needed */
34 
35  /* Get the old ESP */
36  Previous = KiEspFromTrapFrame(TrapFrame);
37 
38  /* Check if this is user-mode */
39  if ((TrapFrame->SegCs & MODE_MASK))
40  {
41  /* Write it directly */
42  TrapFrame->Rsp = Esp;
43  }
44  else
45  {
46  /* Don't allow ESP to be lowered, this is illegal */
47  if (Esp < Previous) KeBugCheckEx(SET_OF_INVALID_CONTEXT,
48  Esp,
49  Previous,
50  (ULONG_PTR)TrapFrame,
51  0);
52 
53  /* Create an edit frame, check if it was alrady */
54  if (!(TrapFrame->SegCs & FRAME_EDITED))
55  {
56  /* Update the value */
57  TrapFrame->Rsp = Esp;
58  }
59  else
60  {
61  /* Check if ESP changed */
62  if (Previous != Esp)
63  {
64  /* Save CS */
65  TrapFrame->SegCs &= ~FRAME_EDITED;
66 
67  /* Save ESP */
68  TrapFrame->Rsp = Esp;
69  }
70  }
71  }
72 
73  /* Restore IRQL */
75 
76 }
ULONG NTAPI KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
Definition: kdb.c:18
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define MODE_MASK
Definition: orders.h:326
uint32_t ULONG_PTR
Definition: typedefs.h:64
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
unsigned int ULONG
Definition: retypes.h:1
#define FRAME_EDITED
Definition: ke.h:64
#define APC_LEVEL
Definition: env_spec_w32.h:695
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107

Referenced by KdbpKdbTrapFrameToTrapFrame(), KeContextToTrapFrame(), and KiDispatchException().

◆ KiSsFromTrapFrame()

ULONG NTAPI KiSsFromTrapFrame ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 80 of file kdb.c.

81 {
82  if (TrapFrame->SegCs & MODE_MASK)
83  {
84  /* User mode, return the User SS */
85  return TrapFrame->SegSs | RPL_MASK;
86  }
87  else
88  {
89  /* Kernel mode */
90  return KGDT64_SYS_TSS;
91  }
92 }
#define MODE_MASK
Definition: orders.h:326
#define RPL_MASK
Definition: ketypes.h:69
#define KGDT64_SYS_TSS
Definition: ketypes.h:77

Referenced by KdbpTrapFrameToKdbTrapFrame(), and KeTrapFrameToContext().

◆ KiSsToTrapFrame()

VOID NTAPI KiSsToTrapFrame ( IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Ss 
)

Definition at line 96 of file kdb.c.

98 {
99  /* Remove the high-bits */
100  Ss &= 0xFFFF;
101 
102  if (TrapFrame->SegCs & MODE_MASK)
103  {
104  /* Usermode, save the User SS */
105  TrapFrame->SegSs = Ss | RPL_MASK;
106  }
107 
108 }
#define MODE_MASK
Definition: orders.h:326
#define RPL_MASK
Definition: ketypes.h:69

Referenced by KdbpKdbTrapFrameToTrapFrame(), KeContextToTrapFrame(), and KiDispatchException().

Variable Documentation

◆ ExceptionNrToString

const CHAR* ExceptionNrToString[]
static
Initial value:
=
{
"Divide Error",
"Debug Trap",
"NMI",
"Breakpoint",
"Overflow",
"BOUND range exceeded",
"Invalid Opcode",
"No Math Coprocessor",
"Double Fault",
"Unknown(9)",
"Invalid TSS",
"Segment Not Present",
"Stack Segment Fault",
"General Protection",
"Page Fault",
"Reserved(15)",
"Math Fault",
"Alignment Check",
"Machine Check",
"SIMD Fault",
"Assertion Failure"
}

Definition at line 86 of file kdb.c.

Referenced by KdbEnterDebuggerException().

◆ KdbApcState

KAPC_STATE KdbApcState
static

Definition at line 54 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpAttachToThread().

◆ KdbBreakPointCount

ULONG KdbBreakPointCount = 0
static

Definition at line 33 of file kdb.c.

Referenced by KdbpDeleteBreakPoint(), and KdbpInsertBreakPoint().

◆ KdbBreakPoints

◆ KdbBreakPointToReenable

PKDB_BREAKPOINT KdbBreakPointToReenable = NULL
static

Definition at line 39 of file kdb.c.

Referenced by KdbEnterDebuggerException().

◆ KdbCurrentProcess

◆ KdbCurrentThread

PETHREAD KdbCurrentThread = NULL

Definition at line 49 of file kdb.c.

Referenced by KdbEnterDebuggerException(), KdbpAttachToThread(), KdbpCmdProc(), and KdbpCmdThread().

◆ KdbCurrentTrapFrame

◆ KdbDebugState

ULONG KdbDebugState = 0

◆ KdbEnterConditions

◆ KdbEnteredOnSingleStep

BOOLEAN KdbEnteredOnSingleStep = FALSE
static

Definition at line 46 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpCallMainLoop().

◆ KdbEntryCount

LONG KdbEntryCount = 0
static

Definition at line 30 of file kdb.c.

Referenced by KdbEnterDebuggerException().

◆ KdbHwBreakPointCount

ULONG KdbHwBreakPointCount = 0
static

Definition at line 36 of file kdb.c.

Referenced by KdbpDisableBreakPoint(), KdbpEnableBreakPoint(), and KdbpIsBreakPointOurs().

◆ KdbHwBreakPoints

Definition at line 38 of file kdb.c.

Referenced by KdbpDisableBreakPoint(), KdbpEnableBreakPoint(), and KdbpIsBreakPointOurs().

◆ KdbLastBreakPointNr

LONG KdbLastBreakPointNr = -1

Definition at line 42 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpCmdBreakPointList().

◆ KdbNumSingleSteps

ULONG KdbNumSingleSteps = 0

Definition at line 43 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpCmdStep().

◆ KdbOriginalProcess

PEPROCESS KdbOriginalProcess = NULL

Definition at line 48 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpAttachToThread().

◆ KdbOriginalThread

PETHREAD KdbOriginalThread = NULL

Definition at line 50 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpAttachToThread().

◆ KdbpBugCheckRequested

BOOLEAN KdbpBugCheckRequested

Definition at line 125 of file kdb_cli.c.

Referenced by KdbEnterDebuggerException(), and KdbpCmdBugCheck().

◆ KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep

BOOLEAN KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep
static

Definition at line 41 of file kdb.c.

Referenced by KdbEnterDebuggerException().

◆ KdbSingleStepOver

BOOLEAN KdbSingleStepOver = FALSE

Definition at line 44 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpCmdStep().

◆ KdbStack

CHAR KdbStack[KDB_STACK_SIZE]
static

Definition at line 31 of file kdb.c.

Referenced by KdbpInternalEnter().

◆ KdbSwBreakPointCount

ULONG KdbSwBreakPointCount = 0
static

Definition at line 35 of file kdb.c.

Referenced by KdbpDisableBreakPoint(), KdbpEnableBreakPoint(), and KdbpIsBreakPointOurs().

◆ KdbSwBreakPoints

Definition at line 37 of file kdb.c.

Referenced by KdbpDisableBreakPoint(), KdbpEnableBreakPoint(), and KdbpIsBreakPointOurs().

◆ KdbThreadTrapFrame

KDB_KTRAP_FRAME KdbThreadTrapFrame = { { 0 } }
static

Definition at line 53 of file kdb.c.

Referenced by KdbpAttachToThread().

◆ KdbTrapFrame