ReactOS  0.4.15-dev-1206-g731eddf
kdmain.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Kernel
4  * FILE: ntoskrnl/kd/kdmain.c
5  * PURPOSE: Kernel Debugger Initialization
6  *
7  * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
8  */
9 
10 #include <ntoskrnl.h>
11 #define NDEBUG
12 #include <debug.h>
13 
14 //
15 // Retrieves the ComponentId and Level for BREAKPOINT_PRINT
16 // and OutputString and OutputStringLength for BREAKPOINT_PROMPT.
17 //
18 #if defined(_X86_)
19 
20 //
21 // EBX/EDI on x86
22 //
23 #define KdpGetParameterThree(Context) ((Context)->Ebx)
24 #define KdpGetParameterFour(Context) ((Context)->Edi)
25 
26 #elif defined(_AMD64_)
27 
28 //
29 // R8/R9 on AMD64
30 //
31 #define KdpGetParameterThree(Context) ((Context)->R8)
32 #define KdpGetParameterFour(Context) ((Context)->R9)
33 
34 #elif defined(_ARM_)
35 
36 //
37 // R3/R4 on ARM
38 //
39 #define KdpGetParameterThree(Context) ((Context)->R3)
40 #define KdpGetParameterFour(Context) ((Context)->R4)
41 
42 #else
43 #error Unsupported Architecture
44 #endif
45 
46 /* VARIABLES ***************************************************************/
47 
54 
55 VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads);
56 
57 #if 0
58 ULONG Kd_DEFAULT_MASK = 1 << DPFLTR_ERROR_LEVEL;
59 #endif
60 
61 /* PRIVATE FUNCTIONS *********************************************************/
62 
63 ULONG
64 NTAPI
66  PVOID Buffer1,
67  ULONG Buffer1Length,
69 {
70  ULONG Result = 0;
71 
72  switch (Service)
73  {
74  case BREAKPOINT_PRINT: /* DbgPrint */
75  {
76  /* Call KDBG */
80  (PCHAR)Buffer1,
81  (USHORT)Buffer1Length,
83  NULL, // TrapFrame,
84  NULL, // ExceptionFrame,
85  &Handled);
86  break;
87  }
88 
89 #if DBG
90  case ' soR': /* ROS-INTERNAL */
91  {
92  switch ((ULONG_PTR)Buffer1)
93  {
94  case DumpAllThreads:
96  break;
97 
98  case DumpUserThreads:
100  break;
101 
102  case KdSpare3:
104  break;
105 
106  default:
107  break;
108  }
109  break;
110  }
111 
112 #if defined(_M_IX86) && !defined(_WINKD_) // See ke/i386/traphdlr.c
113  /* Register a debug callback */
114  case 'CsoR':
115  {
116  switch (Buffer1Length)
117  {
118  case ID_Win32PreServiceHook:
119  KeWin32PreServiceHook = Buffer1;
120  break;
121 
122  case ID_Win32PostServiceHook:
123  KeWin32PostServiceHook = Buffer1;
124  break;
125 
126  }
127  break;
128  }
129 #endif
130 
131  /* Special case for stack frame dumps */
132  case 'DsoR':
133  {
134  KeRosDumpStackFrames((PULONG_PTR)Buffer1, Buffer1Length);
135  break;
136  }
137 
138 #if defined(KDBG)
139  /* Register KDBG CLI callback */
140  case 'RbdK':
141  {
142  Result = KdbRegisterCliCallback(Buffer1, Buffer1Length);
143  break;
144  }
145 #endif /* KDBG */
146 #endif /* DBG */
147  default:
148  DPRINT1("Invalid debug service call!\n");
149  HalDisplayString("Invalid debug service call!\r\n");
150  break;
151  }
152 
153  return Result;
154 }
155 
156 BOOLEAN
157 NTAPI
159  IN PKEXCEPTION_FRAME ExceptionFrame,
160  IN PEXCEPTION_RECORD ExceptionRecord,
163  IN BOOLEAN SecondChance)
164 {
165  KD_CONTINUE_TYPE Return = kdHandleException;
166  ULONG ExceptionCommand = ExceptionRecord->ExceptionInformation[0];
167 
168  /* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */
169  if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
170  (ExceptionRecord->NumberParameters > 0) &&
171  ((ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) ||
172  (ExceptionCommand == BREAKPOINT_UNLOAD_SYMBOLS) ||
173  (ExceptionCommand == BREAKPOINT_COMMAND_STRING) ||
174  (ExceptionCommand == BREAKPOINT_PRINT) ||
175  (ExceptionCommand == BREAKPOINT_PROMPT)))
176  {
177  /* Check if this is a debug print */
178  if (ExceptionCommand == BREAKPOINT_PRINT)
179  {
180  /* Call KDBG */
181  NTSTATUS ReturnStatus;
183  ReturnStatus = KdpPrint((ULONG)KdpGetParameterThree(Context),
184  (ULONG)KdpGetParameterFour(Context),
185  (PCHAR)ExceptionRecord->ExceptionInformation[1],
186  (USHORT)ExceptionRecord->ExceptionInformation[2],
187  PreviousMode,
188  TrapFrame,
189  ExceptionFrame,
190  &Handled);
191 
192  /* Update the return value for the caller */
193  KeSetContextReturnRegister(Context, ReturnStatus);
194  }
195 #ifdef KDBG
196  else if (ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS)
197  {
198  PKD_SYMBOLS_INFO SymbolsInfo;
199  KD_SYMBOLS_INFO CapturedSymbolsInfo;
200  PLDR_DATA_TABLE_ENTRY LdrEntry;
201 
202  SymbolsInfo = (PKD_SYMBOLS_INFO)ExceptionRecord->ExceptionInformation[2];
204  {
205  _SEH2_TRY
206  {
207  ProbeForRead(SymbolsInfo,
208  sizeof(*SymbolsInfo),
209  1);
210  KdpMoveMemory(&CapturedSymbolsInfo,
211  SymbolsInfo,
212  sizeof(*SymbolsInfo));
213  SymbolsInfo = &CapturedSymbolsInfo;
214  }
216  {
217  SymbolsInfo = NULL;
218  }
219  _SEH2_END;
220  }
221 
222  if (SymbolsInfo != NULL)
223  {
224  /* Load symbols. Currently implemented only for KDBG! */
225  if (KdbpSymFindModule(SymbolsInfo->BaseOfDll, NULL, -1, &LdrEntry))
226  {
227  KdbSymProcessSymbols(LdrEntry);
228  }
229  }
230  }
231  else if (ExceptionCommand == BREAKPOINT_PROMPT)
232  {
233  /* Call KDBG */
235  ReturnLength = KdpPrompt((PCHAR)ExceptionRecord->ExceptionInformation[1],
236  (USHORT)ExceptionRecord->ExceptionInformation[2],
237  (PCHAR)KdpGetParameterThree(Context),
238  (USHORT)KdpGetParameterFour(Context),
239  PreviousMode,
240  TrapFrame,
241  ExceptionFrame);
242 
243  /* Update the return value for the caller */
245  }
246 #endif
247 
248  /* This we can handle: simply bump the Program Counter */
250  return TRUE;
251  }
252 
253 #ifdef KDBG
254  /* Check if this is an assertion failure */
255  if (ExceptionRecord->ExceptionCode == STATUS_ASSERTION_FAILURE)
256  {
257  /* Bump EIP to the instruction following the int 2C */
258  Context->Eip += 2;
259  }
260 #endif
261 
262  /* Get out of here if the Debugger isn't connected */
263  if (KdDebuggerNotPresent) return FALSE;
264 
265 #ifdef KDBG
266  /* Call KDBG if available */
267  Return = KdbEnterDebuggerException(ExceptionRecord,
268  PreviousMode,
269  Context,
270  TrapFrame,
271  !SecondChance);
272 #else /* not KDBG */
273  if (WrapperInitRoutine)
274  {
275  /* Call GDB */
276  Return = WrapperTable.KdpExceptionRoutine(ExceptionRecord,
277  Context,
278  TrapFrame);
279  }
280 
281  /* We'll manually dump the stack for the user... */
283 #endif /* not KDBG */
284 
285  /* Debugger didn't handle it, please handle! */
286  if (Return == kdHandleException) return FALSE;
287 
288  /* Debugger handled it */
289  return TRUE;
290 }
291 
292 BOOLEAN
293 NTAPI
297 {
298  /* KDBG has its own mechanism for ignoring user mode exceptions */
299  return FALSE;
300 }
301 
302 /* PUBLIC FUNCTIONS *********************************************************/
303 
304 VOID
305 NTAPI
307 {
308 }
309 
310 BOOLEAN
311 NTAPI
313  IN PKEXCEPTION_FRAME ExceptionFrame)
314 {
315  return FALSE;
316 }
317 
318 VOID
319 NTAPI
321 {
322 }
323 
324 /*
325  * @implemented
326  */
327 BOOLEAN
328 NTAPI
330 {
332 
333  /* Just return whatever was set previously -- FIXME! */
334  return KdDebuggerNotPresent;
335 }
336 
337 /*
338  * @implemented
339  */
340 NTSTATUS
341 NTAPI
343 {
344  KIRQL OldIrql;
345 
346  /* Raise IRQL */
348 
349  /* TODO: Disable any breakpoints */
350 
351  /* Disable the Debugger */
353  SharedUserData->KdDebuggerEnabled = FALSE;
354 
355  /* Lower the IRQL */
357 
358  /* Return success */
359  return STATUS_SUCCESS;
360 }
361 
362 NTSTATUS
363 NTAPI
365 {
366  return STATUS_ACCESS_DENIED;
367 }
368 
369 /*
370  * @implemented
371  */
372 NTSTATUS
373 NTAPI
375 {
376  KIRQL OldIrql;
377 
378  /* Raise IRQL */
380 
381  /* TODO: Re-enable any breakpoints */
382 
383  /* Enable the Debugger */
385  SharedUserData->KdDebuggerEnabled = TRUE;
386 
387  /* Lower the IRQL */
389 
390  /* Return success */
391  return STATUS_SUCCESS;
392 }
393 
394 /*
395  * @implemented
396  */
397 BOOLEAN
398 NTAPI
400 {
401  return FALSE;
402 }
403 
404 /*
405  * @unimplemented
406  */
407 NTSTATUS
408 NTAPI
410 {
412  return STATUS_NOT_IMPLEMENTED;
413 }
414 
415 /*
416  * @unimplemented
417  */
418 NTSTATUS
419 NTAPI
421  IN ULONG InBufferLength OPTIONAL,
422  IN PVOID InBuffer,
425  OUT PULONG OutBufferRequiredLength OPTIONAL)
426 {
428  return STATUS_NOT_IMPLEMENTED;
429 }
430 
431 /*
432  * @unimplemented
433  */
434 NTSTATUS
435 NTAPI
443 {
444  /* HACK */
446  InputBuffer,
448  PreviousMode);
449 }
450 
452 
453  /* EOF */
BOOLEAN KdEnteredDebugger
Definition: kdmain.c:49
NTSTATUS NTAPI KdpPrint(_In_ ULONG ComponentId, _In_ ULONG Level, _In_reads_bytes_(Length) PCHAR String, _In_ USHORT Length, _In_ KPROCESSOR_MODE PreviousMode, _In_ PKTRAP_FRAME TrapFrame, _In_ PKEXCEPTION_FRAME ExceptionFrame, _Out_ PBOOLEAN Handled)
Definition: kdprint.c:331
signed char * PCHAR
Definition: retypes.h:7
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define KeRosDumpStackFrames(Frames, Count)
Definition: gdidebug.h:11
#define IN
Definition: typedefs.h:39
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
_In_ UCHAR _In_ POWER_STATE PowerState
Definition: pofuncs.h:42
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
_In_ UCHAR _In_ ULONG _Out_ PUCHAR _Outptr_result_bytebuffer_ OutBufferLength PVOID * OutBuffer
Definition: scsi.h:4071
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
NTSTATUS NTAPI KdDisableDebugger(VOID)
Definition: kdmain.c:342
#define TRUE
Definition: types.h:120
struct _KD_SYMBOLS_INFO * PKD_SYMBOLS_INFO
VOID NTAPI MmDumpArmPfnDatabase(IN BOOLEAN StatusOnly)
Definition: mminit.c:1474
#define KeSetContextReturnRegister(Context, ReturnValue)
Definition: ke.h:139
VOID NTAPI KdpMoveMemory(_In_ PVOID Destination, _In_ PVOID Source, _In_ SIZE_T Length)
Definition: kdapi.c:22
#define DPFLTR_INFO_LEVEL
Definition: kdtypes.h:33
BOOLEAN NTAPI KdEnterDebugger(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
Definition: kdmain.c:312
LONG NTSTATUS
Definition: precomp.h:26
ULONG NTAPI KdpServiceDispatcher(ULONG Service, PVOID Buffer1, ULONG Buffer1Length, KPROCESSOR_MODE PreviousMode)
Definition: kdmain.c:65
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
VOID NTAPI KdUpdateDataBlock(VOID)
Definition: kdmain.c:306
VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads)
NTSTATUS NTAPI KdEnableDebuggerWithLock(IN BOOLEAN NeedLock)
Definition: kdmain.c:364
Definition: shell.h:41
NTSTATUS NTAPI KdPowerTransition(ULONG PowerState)
Definition: kdmain.c:409
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
UCHAR KIRQL
Definition: env_spec_w32.h:591
BOOLEAN NTAPI KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN KPROCESSOR_MODE PreviousMode)
Definition: kdmain.c:294
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define BREAKPOINT_UNLOAD_SYMBOLS
Definition: kdtypes.h:54
BOOLEAN KdPitchDebugger
Definition: kdmain.c:52
BOOLEAN NTAPI KdPollBreakIn(VOID)
Definition: kdmain.c:399
BOOLEAN NTAPI KdbRegisterCliCallback(PVOID Callback, BOOLEAN Deregister)
Definition: kdb_cli.c:3517
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
enum _SYSDBG_COMMAND SYSDBG_COMMAND
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_BREAKPOINT
Definition: ntstatus.h:184
BOOLEAN KdDebuggerEnabled
Definition: kdmain.c:48
PVOID BaseOfDll
Definition: kdtypes.h:170
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define KeGetContextPc(Context)
Definition: ke.h:124
NTSTATUS NTAPI KdChangeOption(IN KD_OPTION Option, IN ULONG InBufferLength OPTIONAL, IN PVOID InBuffer, IN ULONG OutBufferLength OPTIONAL, OUT PVOID OutBuffer, OUT PULONG OutBufferRequiredLength OPTIONAL)
Definition: kdmain.c:420
BOOLEAN NTAPI KdRefreshDebuggerNotPresent(VOID)
Definition: kdmain.c:329
#define BREAKPOINT_PROMPT
Definition: kdtypes.h:52
NTSTATUS NTAPI KdSystemDebugControl(IN SYSDBG_COMMAND Command, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, IN OUT PULONG ReturnLength, IN KPROCESSOR_MODE PreviousMode)
Definition: kdmain.c:436
VOID NTAPI KdExitDebugger(IN BOOLEAN Enable)
Definition: kdmain.c:320
#define STATUS_ASSERTION_FAILURE
Definition: ntstatus.h:960
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
BOOLEAN NTAPI KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance)
Definition: kdmain.c:158
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t OutputBufferLength
Definition: cdrom.h:1437
if(!(yy_init))
Definition: macro.lex.yy.c:714
_In_ BOOLEAN Handled
Definition: ketypes.h:337
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
CHAR InputBuffer[80]
Definition: conmgr.c:33
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
NTSTATUS NTAPI KdEnableDebugger(VOID)
Definition: kdmain.c:374
#define SharedUserData
#define BREAKPOINT_PRINT
Definition: kdtypes.h:51
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
VOID KdbSymProcessSymbols(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: kdb_symbols.c:426
Definition: btrfs_drv.h:1922
#define MAXULONG
Definition: typedefs.h:251
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_In_ UCHAR _In_ UCHAR OutBufferLength
Definition: scsi.h:4016
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID OutputBuffer
Definition: cdrom.h:1437
PKDP_INIT_ROUTINE WrapperInitRoutine
Definition: kdinit.c:27
_SEH2_END
Definition: create.c:4400
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
unsigned short USHORT
Definition: pedump.c:61
USHORT NTAPI KdpPrompt(_In_reads_bytes_(PromptLength) PCHAR PromptString, _In_ USHORT PromptLength, _Out_writes_bytes_(MaximumResponseLength) PCHAR ResponseString, _In_ USHORT MaximumResponseLength, _In_ KPROCESSOR_MODE PreviousMode, _In_ PKTRAP_FRAME TrapFrame, _In_ PKEXCEPTION_FRAME ExceptionFrame)
Definition: kdprint.c:234
#define BREAKPOINT_LOAD_SYMBOLS
Definition: kdtypes.h:53
unsigned int * PULONG
Definition: retypes.h:1
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
#define DPRINT1
Definition: precomp.h:8
BOOLEAN(NTAPI * PKDEBUG_ROUTINE)(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance)
Definition: kd64.h:61
#define OUT
Definition: typedefs.h:40
KD_DISPATCH_TABLE WrapperTable
Definition: kdinit.c:28
unsigned int ULONG
Definition: retypes.h:1
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t InputBufferLength
Definition: cdrom.h:1437
#define UNIMPLEMENTED
Definition: debug.h:115
#define BREAKPOINT_COMMAND_STRING
Definition: kdtypes.h:55
uint32_t * PULONG_PTR
Definition: typedefs.h:65
PKDEBUG_ROUTINE KiDebugRoutine
Definition: kdmain.c:451
enum _KD_OPTION KD_OPTION
BOOLEAN KdIgnoreUmExceptions
Definition: kdmain.c:53
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define KD_BREAKPOINT_SIZE
Definition: ke.h:118
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.
Definition: kdb.c:1318
#define KeSetContextPc(Context, ProgramCounter)
Definition: ke.h:127
return STATUS_SUCCESS
Definition: btrfs.c:3014
BOOLEAN KdBreakAfterSymbolLoad
Definition: kdmain.c:51
BOOLEAN KdDebuggerNotPresent
Definition: kdmain.c:50
BOOLEAN KdbpSymFindModule(IN PVOID Address OPTIONAL, IN LPCWSTR Name OPTIONAL, IN INT Index OPTIONAL, OUT PLDR_DATA_TABLE_ENTRY *pLdrEntry)
Find a module...
Definition: kdb_symbols.c:76
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68