ReactOS 0.4.16-dev-321-g63bb46a
kdbreak.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for kdbreak.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

ULONG NTAPI KdpAddBreakpoint (IN PVOID Address)
 
VOID NTAPI KdSetOwedBreakpoints (VOID)
 
BOOLEAN NTAPI KdpLowWriteContent (IN ULONG BpIndex)
 
BOOLEAN NTAPI KdpLowRestoreBreakpoint (IN ULONG BpIndex)
 
BOOLEAN NTAPI KdpDeleteBreakpoint (IN ULONG BpEntry)
 
BOOLEAN NTAPI KdpDeleteBreakpointRange (IN PVOID Base, IN PVOID Limit)
 
VOID NTAPI KdpRestoreAllBreakpoints (VOID)
 
VOID NTAPI KdpSuspendBreakPoint (IN ULONG BpEntry)
 
VOID NTAPI KdpSuspendAllBreakPoints (VOID)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file kdbreak.c.

Function Documentation

◆ KdpAddBreakpoint()

ULONG NTAPI KdpAddBreakpoint ( IN PVOID  Address)

Definition at line 20 of file kdbreak.c.

21{
22 KD_BREAKPOINT_TYPE Content;
23 ULONG i;
25
26 /* Check whether we are not setting a breakpoint twice */
27 for (i = 0; i < KD_BREAKPOINT_MAX; i++)
28 {
29 /* Check if the breakpoint is valid */
32 {
33 /* Were we not able to remove it earlier? */
35 {
36 /* Just re-use it! */
37 KdpBreakpointTable[i].Flags &= ~KD_BREAKPOINT_EXPIRED;
38 return i + 1;
39 }
40 else
41 {
42 /* Fail */
43 return 0;
44 }
45 }
46 }
47
48 /* Find a free entry */
49 for (i = 0; i < KD_BREAKPOINT_MAX; i++)
50 {
51 if (KdpBreakpointTable[i].Flags == 0)
52 break;
53 }
54
55 /* Fail if no free entry was found */
56 if (i == KD_BREAKPOINT_MAX) return 0;
57
58 /* Save the breakpoint */
60
61 /* If we are setting the breakpoint in user space, save the active process context */
63 KdpBreakpointTable[i].DirectoryTableBase = KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0];
64
65 /* Try to save the old instruction */
67 &Content,
69 0,
71 NULL);
72 if (NT_SUCCESS(Status))
73 {
74 /* Memory accessible, set the breakpoint */
75 KdpBreakpointTable[i].Content = Content;
77
78 /* Write the breakpoint */
82 0,
84 NULL);
85 if (!NT_SUCCESS(Status))
86 {
87 /* This should never happen */
88 KdpDprintf("Unable to write breakpoint to address 0x%p\n", Address);
89 }
90 }
91 else
92 {
93 /* Memory is inaccessible now, setting breakpoint is deferred */
94 KdpDprintf("Failed to set breakpoint at address 0x%p, adding deferred breakpoint.\n", Address);
97 }
98
99 /* Return the breakpoint handle */
100 return i + 1;
101}
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:25
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 KeGetCurrentThread
Definition: hal.h:55
#define KD_BREAKPOINT_MAX
Definition: kd64.h:28
BREAKPOINT_ENTRY KdpBreakpointTable[KD_BREAKPOINT_MAX]
Definition: kddata.c:95
#define KD_BREAKPOINT_EXPIRED
Definition: kd64.h:48
KD_BREAKPOINT_TYPE KdpBreakpointInstruction
Definition: kddata.c:96
#define KD_BREAKPOINT_ACTIVE
Definition: kd64.h:45
#define KD_BREAKPOINT_PENDING
Definition: kd64.h:46
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:55
#define KD_HIGHEST_USER_BREAKPOINT_ADDRESS
Definition: kd64.h:40
BOOLEAN KdpOweBreakpoint
Definition: kddata.c:97
#define KdpDprintf(...)
Definition: mmdbg.c:19
#define KD_BREAKPOINT_TYPE
Definition: ke.h:121
#define KD_BREAKPOINT_SIZE
Definition: ke.h:122
#define MMDBG_COPY_UNSAFE
Definition: mm.h:77
#define MMDBG_COPY_WRITE
Definition: mm.h:75
static WCHAR Address[46]
Definition: ping.c:68
KD_BREAKPOINT_TYPE Content
Definition: kd64.h:58
ULONG_PTR DirectoryTableBase
Definition: kd64.h:56
ULONG Flags
Definition: kd64.h:55
PVOID Address
Definition: kd64.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by KdpWriteBreakpoint().

◆ KdpDeleteBreakpoint()

BOOLEAN NTAPI KdpDeleteBreakpoint ( IN ULONG  BpEntry)

Definition at line 311 of file kdbreak.c.

312{
313 ULONG BpIndex = BpEntry - 1;
314
315 /* Check for invalid breakpoint entry */
316 if (!BpEntry || (BpEntry > KD_BREAKPOINT_MAX)) return FALSE;
317
318 /* If the specified breakpoint table entry is not valid, then return FALSE. */
319 if (!KdpBreakpointTable[BpIndex].Flags) return FALSE;
320
321 /* Check if the breakpoint is suspended */
323 {
324 /* Check if breakpoint is not being deleted */
326 {
327 /* Invalidate it and return success */
328 KdpBreakpointTable[BpIndex].Flags = 0;
329 return TRUE;
330 }
331 }
332
333 /* Restore original data, then invalidate it and return success */
334 if (KdpLowWriteContent(BpIndex)) KdpBreakpointTable[BpIndex].Flags = 0;
335 return TRUE;
336}
#define FALSE
Definition: types.h:117
#define KD_BREAKPOINT_SUSPENDED
Definition: kd64.h:47
BOOLEAN NTAPI KdpLowWriteContent(IN ULONG BpIndex)
Definition: kdbreak.c:226

Referenced by KdpDeleteBreakpointRange(), and KdpRestoreBreakpoint().

◆ KdpDeleteBreakpointRange()

BOOLEAN NTAPI KdpDeleteBreakpointRange ( IN PVOID  Base,
IN PVOID  Limit 
)

Definition at line 340 of file kdbreak.c.

342{
343 ULONG BpIndex;
344 BOOLEAN DeletedBreakpoints;
345
346 /* Assume no breakpoints will be deleted */
347 DeletedBreakpoints = FALSE;
348
349 /* Loop the breakpoint table */
350 for (BpIndex = 0; BpIndex < KD_BREAKPOINT_MAX; BpIndex++)
351 {
352 /* Make sure that the breakpoint is active and matches the range. */
354 ((KdpBreakpointTable[BpIndex].Address >= Base) &&
355 (KdpBreakpointTable[BpIndex].Address <= Limit)))
356 {
357 /* Delete it, and remember if we succeeded at least once */
358 if (KdpDeleteBreakpoint(BpIndex + 1)) DeletedBreakpoints = TRUE;
359 }
360 }
361
362 /* Return whether we deleted anything */
363 return DeletedBreakpoints;
364}
unsigned char BOOLEAN
BOOLEAN NTAPI KdpDeleteBreakpoint(IN ULONG BpEntry)
Definition: kdbreak.c:311
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2451
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:304

Referenced by KdpSetCommonState().

◆ KdpLowRestoreBreakpoint()

BOOLEAN NTAPI KdpLowRestoreBreakpoint ( IN ULONG  BpIndex)

Definition at line 268 of file kdbreak.c.

269{
271
272 /* Were we not able to remove it earlier? */
274 {
275 /* Just re-use it! */
276 KdpBreakpointTable[BpIndex].Flags &= ~KD_BREAKPOINT_EXPIRED;
277 return TRUE;
278 }
279
280 /* Are we merely writing a breakpoint on top of another breakpoint? */
281 if (KdpBreakpointTable[BpIndex].Content == KdpBreakpointInstruction)
282 {
283 /* Nothing to do */
284 return TRUE;
285 }
286
287 /* Ok, we actually have to overwrite the instruction now */
291 0,
293 NULL);
294 if (!NT_SUCCESS(Status))
295 {
296 /* Memory is inaccessible now, restoring breakpoint is deferred */
297 // KdpDprintf("Failed to restore breakpoint at address 0x%p\n",
298 // KdpBreakpointTable[BpIndex].Address);
301 return FALSE;
302 }
303
304 /* Clear any possible previous pending flag and return success */
305 KdpBreakpointTable[BpIndex].Flags &= ~KD_BREAKPOINT_PENDING;
306 return TRUE;
307}

Referenced by KdpRestoreAllBreakpoints().

◆ KdpLowWriteContent()

BOOLEAN NTAPI KdpLowWriteContent ( IN ULONG  BpIndex)

Definition at line 226 of file kdbreak.c.

227{
229
230 /* Make sure that the breakpoint is actually active */
232 {
233 /* So we have a valid breakpoint, but it hasn't been used yet... */
234 KdpBreakpointTable[BpIndex].Flags &= ~KD_BREAKPOINT_PENDING;
235 return TRUE;
236 }
237
238 /* Is the original instruction a breakpoint anyway? */
239 if (KdpBreakpointTable[BpIndex].Content == KdpBreakpointInstruction)
240 {
241 /* Then leave it that way... */
242 return TRUE;
243 }
244
245 /* We have an active breakpoint with an instruction to bring back. Do it. */
247 &KdpBreakpointTable[BpIndex].Content,
249 0,
251 NULL);
252 if (!NT_SUCCESS(Status))
253 {
254 /* Memory is inaccessible now, restoring original instruction is deferred */
255 // KdpDprintf("Failed to delete breakpoint at address 0x%p\n",
256 // KdpBreakpointTable[BpIndex].Address);
259 return FALSE;
260 }
261
262 /* Everything went fine, return */
263 return TRUE;
264}

Referenced by KdpDeleteBreakpoint(), and KdpSuspendBreakPoint().

◆ KdpRestoreAllBreakpoints()

VOID NTAPI KdpRestoreAllBreakpoints ( VOID  )

Definition at line 368 of file kdbreak.c.

369{
370 ULONG BpIndex;
371
372 /* No more suspended Breakpoints */
374
375 /* Loop the breakpoints */
376 for (BpIndex = 0; BpIndex < KD_BREAKPOINT_MAX; BpIndex++)
377 {
378 /* Check if they are valid, suspended breakpoints */
381 {
382 /* Unsuspend them */
383 KdpBreakpointTable[BpIndex].Flags &= ~KD_BREAKPOINT_SUSPENDED;
385 }
386 }
387}
BOOLEAN BreakpointsSuspended
Definition: kddata.c:98
BOOLEAN NTAPI KdpLowRestoreBreakpoint(IN ULONG BpIndex)
Definition: kdbreak.c:268

Referenced by KdEnableDebuggerWithLock().

◆ KdpSuspendAllBreakPoints()

VOID NTAPI KdpSuspendAllBreakPoints ( VOID  )

Definition at line 407 of file kdbreak.c.

408{
409 ULONG BpEntry;
410
411 /* Breakpoints are suspended */
413
414 /* Loop every breakpoint */
415 for (BpEntry = 1; BpEntry <= KD_BREAKPOINT_MAX; BpEntry++)
416 {
417 /* Suspend it */
418 KdpSuspendBreakPoint(BpEntry);
419 }
420}
VOID NTAPI KdpSuspendBreakPoint(IN ULONG BpEntry)
Definition: kdbreak.c:391

Referenced by KdDisableDebuggerWithLock().

◆ KdpSuspendBreakPoint()

VOID NTAPI KdpSuspendBreakPoint ( IN ULONG  BpEntry)

Definition at line 391 of file kdbreak.c.

392{
393 ULONG BpIndex = BpEntry - 1;
394
395 /* Check if this is a valid, unsuspended breakpoint */
398 {
399 /* Suspend it */
401 KdpLowWriteContent(BpIndex);
402 }
403}

Referenced by KdpSuspendAllBreakPoints().

◆ KdSetOwedBreakpoints()

VOID NTAPI KdSetOwedBreakpoints ( VOID  )

Definition at line 105 of file kdbreak.c.

106{
108 KD_BREAKPOINT_TYPE Content;
109 ULONG i;
111
112 /* If we don't owe any breakpoints, just return */
113 if (!KdpOweBreakpoint) return;
114
115 /* Enter the debugger */
117
118 /*
119 * Suppose we succeed in setting all the breakpoints.
120 * If we fail to do so, the flag will be set again.
121 */
123
124 /* Loop through current breakpoints and try to set or delete the pending ones */
125 for (i = 0; i < KD_BREAKPOINT_MAX; i++)
126 {
128 {
129 /*
130 * Set the breakpoint only if it is in kernel space, or if it is
131 * in user space and the active process context matches.
132 */
134 KdpBreakpointTable[i].DirectoryTableBase != KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0])
135 {
137 continue;
138 }
139
140 /* Try to save the old instruction */
142 &Content,
144 0,
146 NULL);
147 if (!NT_SUCCESS(Status))
148 {
149 /* Memory is still inaccessible, breakpoint setting will be deferred again */
150 // KdpDprintf("Failed to set deferred breakpoint at address 0x%p\n",
151 // KdpBreakpointTable[i].Address);
153 continue;
154 }
155
156 /* Check if we need to write the breakpoint */
158 {
159 /* Memory accessible, set the breakpoint */
160 KdpBreakpointTable[i].Content = Content;
161
162 /* Write the breakpoint */
166 0,
168 NULL);
169 if (!NT_SUCCESS(Status))
170 {
171 /* This should never happen */
172 KdpDprintf("Unable to write deferred breakpoint to address 0x%p\n",
175 }
176 else
177 {
179 }
180
181 continue;
182 }
183
184 /* Check if we need to restore the original instruction */
186 {
187 /* Write it back */
189 &KdpBreakpointTable[i].Content,
191 0,
193 NULL);
194 if (!NT_SUCCESS(Status))
195 {
196 /* This should never happen */
197 KdpDprintf("Unable to delete deferred breakpoint at address 0x%p\n",
200 }
201 else
202 {
203 /* Check if the breakpoint is suspended */
205 {
207 }
208 else
209 {
210 /* Invalidate it */
212 }
213 }
214
215 continue;
216 }
217 }
218 }
219
220 /* Exit the debugger */
222}
BOOLEAN NTAPI KdEnterDebugger(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
Definition: kdapi.c:1902
VOID NTAPI KdExitDebugger(IN BOOLEAN Enable)
Definition: kdapi.c:1955
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1765

Referenced by KiTrap0EHandler().