ReactOS 0.4.16-dev-838-g27bb510
dbgctrl.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ex/dbgctrl.c
5 * PURPOSE: System debug control
6 * PROGRAMMERS: Alex Ionescu
7 */
8
9/* INCLUDES *****************************************************************/
10
11#include <ntoskrnl.h>
12#define NDEBUG
13#include <debug.h>
14
15/* DATA **********************************************************************/
16
17/*
18 * WinDBG Debugger Worker State Machine data
19 */
21/*
22 * The following global variables must be visible through all the kernel
23 * because WinDBG explicitely search for them inside our symbols.
24 */
29
30/* FUNCTIONS *****************************************************************/
31
32/*
33 * WinDBG Debugger Worker State Machine
34 *
35 * This functionality is used whenever WinDBG wants to attach or kill a user-mode
36 * process from within live kernel-mode session, and/or page-in an address region.
37 * It is implemented as a state machine: when it is in "Ready" state, WinDBG can
38 * initialize the data for the state machine, then switch its state to "Start".
39 * The worker thread balance manager detects this, switches the state to "Initialized"
40 * and queues a worker thread. As long as the state is not "Ready" again, WinDBG
41 * prevents from requeuing a new thread. When the thread is started, it captures
42 * all the data, then resets the machine state to "Ready", thus allowing WinDBG
43 * to requeue another worker thread.
44 *
45 * WinDBG commands:
46 * .process /i <addr> (where <addr> is the address of the EPROCESS block for this process)
47 * .kill <addr> ( " " " " )
48 * .pagein <addr> (where <addr> is the address to page in)
49 */
50VOID
54{
55 PEPROCESS ProcessToAttach, ProcessToKill;
56 ULONG_PTR PageInAddress;
59
61
62 /* Be sure we were started in an initialized state */
63 ASSERTMSG("ExpDebuggerWorker being entered in non-initialized state!\n",
66 {
67 /* An error happened, so get a chance to restart proper */
69 return;
70 }
71
72 /* Get the processes to be attached or killed, and the address to page in */
73 ProcessToAttach = ExpDebuggerProcessAttach;
74 ProcessToKill = ExpDebuggerProcessKill;
75 PageInAddress = ExpDebuggerPageIn;
76
77 /* Reset the state machine to its ready state */
82
83 /* Default to the current process if we don't find the process to be attached or killed */
84 Process = NULL;
85
86 /* Check if we need to attach or kill some process */
87 if (ProcessToAttach || ProcessToKill)
88 {
89 /* Find the process in the list */
91 {
92 /* Is this the process we want to attach to? */
93 if (Process == ProcessToAttach)
94 {
95 /* Yes, attach ourselves to it */
97 break;
98 }
99 /* Or is this the process we want to kill? */
100 else if (Process == ProcessToKill)
101 {
102 /* Yes, kill and dereference it, then return */
105 return;
106 }
107 }
108
109 if (!Process)
110 {
112 "EX debug work: Unable to find process %p\n",
113 ProcessToAttach ? ProcessToAttach : ProcessToKill);
114 }
115
116 /* We either have found a process, or we default to the current one */
117 }
118
119 /* If we have an address to page in... */
120 if (PageInAddress)
121 {
122 /* ... try to do it by attempting to read at this address */
124 {
125 ProbeForReadUchar(PageInAddress);
126 }
128 {
130 "EX page in: Failed to page-in address 0x%p, Status 0x%08lx\n",
131 PageInAddress, _SEH2_GetExceptionCode());
132 }
133 _SEH2_END;
134 }
135
136 /* Break into the process (or the current one if Process == NULL) */
138
139 /* If we are attached to a process, not the current one... */
140 if (Process)
141 {
142 /* ... we can detach from the process */
144 /* Dereference the process referenced by PsGetNextProcess() */
146 }
147}
148
208NTAPI
216{
218 ULONG Length = 0;
220
221 /* Debugger controlling requires the debug privilege */
224
226 {
228 {
233 if (ReturnLength)
235 }
236
237 switch (Command)
238 {
240 /* Removed in WinNT4 */
242 break;
243
244#ifdef _M_IX86
252 break;
253#endif
254
264 case SysDbgReadMsr:
265 case SysDbgWriteMsr:
269 /* Those are implemented in KdSystemDebugControl */
270 if (InitIsWinPEMode)
271 {
276 }
277 else
278 {
280 }
281 break;
282
283 case SysDbgBreakPoint:
285 {
288 }
289 else
290 {
292 }
293 break;
294
297 break;
298
301 break;
302
304 if (OutputBufferLength != sizeof(BOOLEAN))
305 {
307 }
308 else
309 {
312 }
313 break;
314
316 if (InputBufferLength != sizeof(BOOLEAN))
317 {
319 }
320 else if (KdPitchDebugger)
321 {
323 }
324 else
325 {
328 }
329 break;
330
332 if (OutputBufferLength != sizeof(ULONG))
333 {
335 }
336 else
337 {
338 /* Return buffer size only if KD is enabled */
341 }
342 break;
343
347 break;
348
350 if (OutputBufferLength != sizeof(BOOLEAN))
351 {
353 }
354 else
355 {
356 /* Unfortunately, the internal flag says if UM exceptions are disabled */
359 }
360 break;
361
363 if (InputBufferLength != sizeof(BOOLEAN))
364 {
366 }
367 else if (KdPitchDebugger)
368 {
370 }
371 else
372 {
373 /* Unfortunately, the internal flag says if UM exceptions are disabled */
376 }
377 break;
378
382 break;
383
385 if (OutputBufferLength != sizeof(BOOLEAN))
386 {
388 }
389 else
390 {
393 }
394 break;
395
402 &Length);
403 break;
404
405 default:
407 break;
408 }
409
410 if (ReturnLength)
412
413 _SEH2_YIELD(return Status);
414 }
416 {
418 }
419 _SEH2_END;
420}
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG ReturnLength
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
unsigned char BOOLEAN
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
LONG NTSTATUS
Definition: precomp.h:26
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
NTSTATUS NTAPI NtSystemDebugControl(_In_ SYSDBG_COMMAND Command, _In_reads_bytes_(InputBufferLength) PVOID InputBuffer, _In_ ULONG InputBufferLength, _Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer, _In_ ULONG OutputBufferLength, _Out_opt_ PULONG ReturnLength)
Perform various queries to the kernel debugger.
Definition: dbgctrl.c:209
PEPROCESS ExpDebuggerProcessAttach
Definition: dbgctrl.c:26
PEPROCESS ExpDebuggerProcessKill
Definition: dbgctrl.c:27
WINKD_WORKER_STATE ExpDebuggerWork
Definition: dbgctrl.c:25
VOID NTAPI ExpDebuggerWorker(_In_ PVOID Context)
Definition: dbgctrl.c:52
ULONG_PTR ExpDebuggerPageIn
Definition: dbgctrl.c:28
WORK_QUEUE_ITEM ExpDebuggerWorkItem
Definition: dbgctrl.c:20
#define NULL
Definition: types.h:112
@ DPFLTR_SYSTEM_ID
Definition: dpfilter.h:28
#define ULONG_PTR
Definition: config.h:101
enum _WINKD_WORKER_STATE WINKD_WORKER_STATE
@ WinKdWorkerReady
Definition: ex.h:62
@ WinKdWorkerInitialized
Definition: ex.h:64
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
BOOLEAN KdPitchDebugger
Definition: kddata.c:80
ULONG KdPrintBufferSize
Definition: kddata.c:136
BOOLEAN KdBlockEnable
Definition: kddata.c:84
BOOLEAN KdIgnoreUmExceptions
Definition: kddata.c:85
BOOLEAN KdAutoEnableOnEvent
Definition: kddata.c:83
NTSTATUS NTAPI KdChangeOption(IN KD_OPTION Option, IN ULONG InBufferBytes OPTIONAL, IN PVOID InBuffer, IN ULONG OutBufferBytes OPTIONAL, OUT PVOID OutBuffer, OUT PULONG OutBufferNeeded OPTIONAL)
Definition: kdapi.c:2594
NTSTATUS NTAPI KdSystemDebugControl(_In_ SYSDBG_COMMAND Command, _In_reads_bytes_(InputBufferLength) PVOID InputBuffer, _In_ ULONG InputBufferLength, _Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer, _In_ ULONG OutputBufferLength, _Out_opt_ PULONG ReturnLength, _In_ KPROCESSOR_MODE PreviousMode)
Perform various queries to the kernel debugger.
Definition: kdapi.c:2217
NTSTATUS NTAPI KdDisableDebugger(VOID)
Definition: kdapi.c:2169
NTSTATUS NTAPI KdEnableDebugger(VOID)
Definition: kdapi.c:2158
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:82
#define DbgPrintEx(cmpid, lvl, fmt,...)
Definition: kdinit.c:24
#define KeGetPreviousMode()
Definition: ketypes.h:1115
#define KernelMode
Definition: asm.h:38
#define DBG_STATUS_WORKER
Definition: kdtypes.h:45
@ SysDbgCheckLowMemory
Definition: kdtypes.h:82
@ SysDbgQuerySpecialCalls
Definition: kdtypes.h:67
@ SysDbgSetTracepoint
Definition: kdtypes.h:64
@ SysDbgReadPhysical
Definition: kdtypes.h:72
@ SysDbgGetPrintBufferSize
Definition: kdtypes.h:87
@ SysDbgQueryTraceInformation
Definition: kdtypes.h:63
@ SysDbgClearSpecialCalls
Definition: kdtypes.h:66
@ SysDbgReadMsr
Definition: kdtypes.h:78
@ SysDbgWriteControlSpace
Definition: kdtypes.h:75
@ SysDbgGetKdBlockEnable
Definition: kdtypes.h:92
@ SysDbgWriteBusData
Definition: kdtypes.h:81
@ SysDbgEnableKernelDebugger
Definition: kdtypes.h:83
@ SysDbgWriteVirtual
Definition: kdtypes.h:71
@ SysDbgWritePhysical
Definition: kdtypes.h:73
@ SysDbgGetKdUmExceptionEnable
Definition: kdtypes.h:89
@ SysDbgQueryVersion
Definition: kdtypes.h:69
@ SysDbgReadControlSpace
Definition: kdtypes.h:74
@ SysDbgReadBusData
Definition: kdtypes.h:80
@ SysDbgBreakPoint
Definition: kdtypes.h:68
@ SysDbgSetKdUmExceptionEnable
Definition: kdtypes.h:90
@ SysDbgReadIoSpace
Definition: kdtypes.h:76
@ SysDbgGetAutoKdEnable
Definition: kdtypes.h:85
@ SysDbgWriteMsr
Definition: kdtypes.h:79
@ SysDbgReadVirtual
Definition: kdtypes.h:70
@ SysDbgSetPrintBufferSize
Definition: kdtypes.h:88
@ SysDbgQueryModuleInformation
Definition: kdtypes.h:62
@ SysDbgSetAutoKdEnable
Definition: kdtypes.h:86
@ SysDbgGetTriageDump
Definition: kdtypes.h:91
@ SysDbgDisableKernelDebugger
Definition: kdtypes.h:84
@ SysDbgWriteIoSpace
Definition: kdtypes.h:77
@ SysDbgSetSpecialCall
Definition: kdtypes.h:65
@ SysDbgSetKdBlockEnable
Definition: kdtypes.h:93
#define DBG_STATUS_DEBUG_CONTROL
Definition: kdtypes.h:44
enum _SYSDBG_COMMAND SYSDBG_COMMAND
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _Out_opt_
Definition: no_sal2.h:214
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
BOOLEAN InitIsWinPEMode
Definition: init.c:72
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1770
const LUID SeDebugPrivilege
Definition: priv.c:39
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
#define DBG_TERMINATE_PROCESS
Definition: ntstatus.h:51
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
NTSTATUS NTAPI PsTerminateProcess(IN PEPROCESS Process, IN NTSTATUS ExitStatus)
Definition: kill.c:126
PEPROCESS NTAPI PsGetNextProcess(IN PEPROCESS OldProcess OPTIONAL)
Definition: process.c:128
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define ProbeForReadUchar(Ptr)
Definition: probe.h:61
#define ProbeForWriteUlong(Ptr)
Definition: probe.h:36
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: shell.h:41
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
__analysis_noreturn NTSYSAPI VOID NTAPI DbgBreakPointWithStatus(_In_ ULONG Status)
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
KAPC_STATE
Definition: ketypes.h:1409
@ KD_OPTION_SET_BLOCK_ENABLE
Definition: ketypes.h:524
#define ObDereferenceObject
Definition: obfuncs.h:203