ReactOS  0.4.13-dev-73-gcfe54aa
debug.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Run-Time Library
4  * FILE: lib/rtl/debug.c
5  * PURPOSE: Debug Print and Prompt routines
6  * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7  * Royce Mitchel III
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include <rtl.h>
13 
14 #include <ndk/kdfuncs.h>
15 
16 #define NDEBUG
17 #include <debug.h>
18 
19 /* PRIVATE FUNCTIONS ********************************************************/
20 
21 ULONG
22 NTAPI
25  IN ULONG Level)
26 {
27  /* Call the Debug Service */
29  DebugString->Buffer,
30  UlongToPtr(DebugString->Length),
32  UlongToPtr(Level));
33 }
34 
35 ULONG
36 NTAPI
39 {
40  /* Call the Debug Service */
42  Output->Buffer,
43  UlongToPtr(Output->Length),
44  Input->Buffer,
45  UlongToPtr(Input->MaximumLength));
46 }
47 
48 /* FUNCTIONS ****************************************************************/
49 
50 ULONG
51 NTAPI
54  IN ULONG Level,
55  IN PCCH Format,
56  IN va_list ap,
57  IN BOOLEAN HandleBreakpoint)
58 {
61  CHAR Buffer[512];
62  SIZE_T Length, PrefixLength;
63  EXCEPTION_RECORD ExceptionRecord;
64 
65  /* Check if we should print it or not */
66  if ((ComponentId != MAXULONG) &&
68  {
69  /* This message is masked */
70  return STATUS_SUCCESS;
71  }
72 
73  /* For user mode, don't recursively DbgPrint */
74  if (RtlpSetInDbgPrint()) return STATUS_SUCCESS;
75 
76  /* Guard against incorrect pointers */
77  _SEH2_TRY
78  {
79  /* Get the length and normalize it */
80  PrefixLength = strlen(Prefix);
81  if (PrefixLength > sizeof(Buffer)) PrefixLength = sizeof(Buffer);
82 
83  /* Copy it */
84  strncpy(Buffer, Prefix, PrefixLength);
85 
86  /* Do the printf */
87  Length = _vsnprintf(Buffer + PrefixLength,
88  sizeof(Buffer) - PrefixLength,
89  Format,
90  ap);
91  }
93  {
94  /* In user-mode, clear the InDbgPrint Flag */
96  /* Fail */
98  }
99  _SEH2_END;
100 
101  /* Check if we went past the buffer */
102  if (Length == MAXULONG)
103  {
104  /* Terminate it if we went over-board */
105  Buffer[sizeof(Buffer) - 1] = '\n';
106 
107  /* Put maximum */
108  Length = sizeof(Buffer);
109  }
110  else
111  {
112  /* Add the prefix */
113  Length += PrefixLength;
114  }
115 
116  /* Build the string */
117  DebugString.Length = (USHORT)Length;
118  DebugString.Buffer = Buffer;
119 
120  /* First, let the debugger know as well */
122  {
123  /* Fill out an exception record */
124  ExceptionRecord.ExceptionCode = DBG_PRINTEXCEPTION_C;
125  ExceptionRecord.ExceptionRecord = NULL;
126  ExceptionRecord.NumberParameters = 2;
127  ExceptionRecord.ExceptionFlags = 0;
128  ExceptionRecord.ExceptionInformation[0] = DebugString.Length + 1;
129  ExceptionRecord.ExceptionInformation[1] = (ULONG_PTR)DebugString.Buffer;
130 
131  /* Raise the exception */
132  RtlRaiseException(&ExceptionRecord);
133 
134  /* In user-mode, clear the InDbgPrint Flag */
136  return STATUS_SUCCESS;
137  }
138 
139  /* Call the Debug Print routine */
141 
142  /* Check if this was with Control-C */
143  if (HandleBreakpoint)
144  {
145  /* Check if we got a breakpoint */
146  if (Status == STATUS_BREAKPOINT)
147  {
148  /* Breakpoint */
151  }
152  }
153 
154  /* In user-mode, clear the InDbgPrint Flag */
156 
157  /* Return */
158  return Status;
159 }
160 
161 /*
162  * @implemented
163  */
164 ULONG
165 NTAPI
168  IN ULONG Level,
169  IN PCCH Format,
170  IN va_list ap)
171 {
172  /* Call the internal routine that also handles ControlC */
174  ComponentId,
175  Level,
176  Format,
177  ap,
178  TRUE);
179 }
180 
181 /*
182  * @implemented
183  */
184 ULONG
185 NTAPI
187  IN ULONG Level,
188  IN PCCH Format,
189  IN va_list ap)
190 {
191  /* Call the internal routine that also handles ControlC */
193  ComponentId,
194  Level,
195  Format,
196  ap,
197  TRUE);
198 }
199 
200 /*
201  * @implemented
202  */
203 ULONG
204 __cdecl
206  ...)
207 {
208  ULONG Status;
209  va_list ap;
210 
211  /* Call the internal routine that also handles ControlC */
212  va_start(ap, Format);
214  -1,
216  Format,
217  ap,
218  TRUE);
219  va_end(ap);
220  return Status;
221 }
222 
223 /*
224  * @implemented
225  */
226 ULONG
227 __cdecl
229  IN ULONG Level,
230  IN PCCH Format,
231  ...)
232 {
233  ULONG Status;
234  va_list ap;
235 
236  /* Call the internal routine that also handles ControlC */
237  va_start(ap, Format);
239  ComponentId,
240  Level,
241  Format,
242  ap,
243  TRUE);
244  va_end(ap);
245  return Status;
246 }
247 
248 /*
249  * @implemented
250  */
251 ULONG
252 __cdecl
254  ...)
255 {
256  ULONG Status;
257  va_list ap;
258 
259  /* Call the internal routine that also handles ControlC */
260  va_start(ap, Format);
262  -1,
264  Format,
265  ap,
266  FALSE);
267  va_end(ap);
268  return Status;
269 }
270 
271 /*
272  * @implemented
273  */
274 ULONG
275 NTAPI
277  OUT PCH Response,
279 {
280  STRING Output;
281  STRING Input;
282 
283  /* Setup the input string */
284  Input.MaximumLength = (USHORT)MaximumResponseLength;
285  Input.Buffer = Response;
286 
287  /* Setup the output string */
288  Output.Length = (USHORT)strlen(Prompt);
289  Output.Buffer = (PCHAR)Prompt;
290 
291  /* Call the system service */
292  return DebugPrompt(&Output, &Input);
293 }
294 
295 /*
296  * @implemented
297  */
298 NTSTATUS
299 NTAPI
301  IN ULONG Level)
302 {
303  /* Call the Nt routine */
305 }
306 
307 /*
308  * @implemented
309  */
310 NTSTATUS
311 NTAPI
313  IN ULONG Level,
314  IN BOOLEAN State)
315 {
316  /* Call the Nt routine */
318 }
319 
320 /*
321  * @implemented
322  */
323 VOID
324 NTAPI
326  IN PVOID Base,
328 {
329  PIMAGE_NT_HEADERS NtHeader;
330  KD_SYMBOLS_INFO SymbolInfo;
331 
332  /* Setup the symbol data */
333  SymbolInfo.BaseOfDll = Base;
334  SymbolInfo.ProcessId = ProcessId;
335 
336  /* Get NT Headers */
337  NtHeader = RtlImageNtHeader(Base);
338  if (NtHeader)
339  {
340  /* Get the rest of the data */
341  SymbolInfo.CheckSum = NtHeader->OptionalHeader.CheckSum;
342  SymbolInfo.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
343  }
344  else
345  {
346  /* No data available */
347  SymbolInfo.CheckSum =
348  SymbolInfo.SizeOfImage = 0;
349  }
350 
351  /* Load the symbols */
353 }
354 
355 /*
356  * @implemented
357  */
358 VOID
359 NTAPI
361  IN PVOID Base,
363 {
364  KD_SYMBOLS_INFO SymbolInfo;
365 
366  /* Setup the symbol data */
367  SymbolInfo.BaseOfDll = Base;
368  SymbolInfo.ProcessId = ProcessId;
369  SymbolInfo.CheckSum = SymbolInfo.SizeOfImage = 0;
370 
371  /* Load the symbols */
373 }
374 
375 /*
376  * @implemented
377  */
378 VOID
379 NTAPI
381  IN PCCH Command)
382 {
383  STRING NameString, CommandString;
384 
385  /* Setup the strings */
386  NameString.Buffer = (PCHAR)Name;
387  NameString.Length = (USHORT)strlen(Name);
388  CommandString.Buffer = (PCHAR)Command;
389  CommandString.Length = (USHORT)strlen(Command);
390 
391  /* Send them to the debugger */
392  DebugService2(&NameString, &CommandString, BREAKPOINT_COMMAND_STRING);
393 }
394 
395 /*
396 * @implemented
397 */
398 VOID
399 NTAPI
401 {
402  /* Restore the previous frame as the active one */
403  NtCurrentTeb()->ActiveFrame = Frame->Previous;
404 }
405 
406 /*
407 * @implemented
408 */
409 VOID
410 NTAPI
412 {
413  /* Save the current frame and set the new one as active */
414  Frame->Previous = NtCurrentTeb()->ActiveFrame;
415  NtCurrentTeb()->ActiveFrame = Frame;
416 }
417 
419 NTAPI
421 {
422  /* Return the frame that's currently active */
423  return NtCurrentTeb()->ActiveFrame;
424 }
ULONG DbgPrint(PCCH Format,...)
Definition: debug.c:420
#define IN
Definition: typedefs.h:38
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2697
#define TRUE
Definition: types.h:120
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1631
PTEB_ACTIVE_FRAME NTAPI RtlGetFrame(VOID)
Definition: debug.c:420
#define __cdecl
Definition: accygwin.h:79
ULONG SizeOfImage
Definition: kdtypes.h:173
NTSTATUS NTAPI DbgQueryDebugFilterState(IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:300
ULONG NTAPI vDbgPrintExWithPrefixInternal(IN PCCH Prefix, IN ULONG ComponentId, IN ULONG Level, IN PCCH Format, IN va_list ap, IN BOOLEAN HandleBreakpoint)
Definition: debug.c:52
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI RtlPushFrame(IN PTEB_ACTIVE_FRAME Frame)
Definition: debug.c:411
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
Definition: arc.h:84
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char UINT32 ComponentId
Definition: acpixf.h:1252
Definition: shell.h:41
NTSYSAPI VOID NTAPI RtlRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord)
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
VOID NTAPI RtlpClearInDbgPrint(VOID)
Definition: libsupp.c:45
DWORD ExceptionCode
Definition: compat.h:196
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define va_end(ap)
Definition: acmsvcex.h:90
#define BREAKPOINT_UNLOAD_SYMBOLS
Definition: kdtypes.h:54
CHAR * PCH
Definition: ntbasedef.h:398
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_BREAKPOINT
Definition: ntstatus.h:172
PVOID BaseOfDll
Definition: kdtypes.h:170
char * va_list
Definition: acmsvcex.h:78
ULONG NTAPI vDbgPrintEx(IN ULONG ComponentId, IN ULONG Level, IN PCCH Format, IN va_list ap)
Definition: debug.c:186
Definition: bufpool.h:45
VOID NTAPI DebugService2(PVOID Arg1, PVOID Arg2, ULONG Service)
Definition: debug.c:39
#define BREAKPOINT_PROMPT
Definition: kdtypes.h:52
VOID NTAPI RtlPopFrame(IN PTEB_ACTIVE_FRAME Frame)
Definition: debug.c:400
#define UlongToPtr(u)
Definition: config.h:106
ULONG NTAPI DebugPrompt(IN PSTRING Output, IN PSTRING Input)
Definition: debug.c:37
#define PCHAR
Definition: match.c:90
VOID NTAPI DbgLoadImageSymbols(IN PSTRING Name, IN PVOID Base, IN ULONG_PTR ProcessId)
Definition: debug.c:325
ULONG NTAPI vDbgPrintExWithPrefix(IN LPCSTR Prefix, IN ULONG ComponentId, IN ULONG Level, IN LPCSTR Format, IN va_list ap)
_In_ ULONG MaximumResponseLength
Definition: kdfuncs.h:11
CONST CHAR * PCCH
Definition: ntbasedef.h:399
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:201
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
Definition: ncftp.h:89
std::wstring STRING
Definition: fontsub.cpp:33
VOID NTAPI DbgCommandString(IN PCCH Name, IN PCCH Command)
Definition: debug.c:380
#define BREAKPOINT_PRINT
Definition: kdtypes.h:51
ULONG NTAPI DbgPrompt(IN PCCH Prompt, OUT PCH Response, IN ULONG MaximumResponseLength)
Definition: debug.c:276
BOOLEAN NTAPI RtlpCheckForActiveDebugger(VOID)
Definition: libsupp.c:25
Definition: arc.h:85
NTSTATUS NTAPI NtQueryDebugFilterState(IN ULONG ComponentId, IN ULONG Level)
Definition: kdmain.c:402
#define DBG_PRINTEXCEPTION_C
Definition: ntstatus.h:53
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
Status
Definition: gdiplustypes.h:24
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:198
#define MAXULONG
Definition: typedefs.h:250
ULONG CheckSum
Definition: kdtypes.h:172
ULONG_PTR SIZE_T
Definition: typedefs.h:78
_SEH2_END
Definition: create.c:4424
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS NTAPI DbgSetDebugFilterState(IN ULONG ComponentId, IN ULONG Level, IN BOOLEAN State)
Definition: debug.c:312
VOID NTAPI DbgUnLoadImageSymbols(IN PSTRING Name, IN PVOID Base, IN ULONG_PTR ProcessId)
Definition: debug.c:360
ULONG NTAPI DebugService(ULONG Service, PVOID Argument1, PVOID Argument1, PVOID Argument3, PVOID Argument4)
Definition: debug.c:15
#define BREAKPOINT_LOAD_SYMBOLS
Definition: kdtypes.h:53
#define va_start(ap, A)
Definition: acmsvcex.h:91
ULONG __cdecl DbgPrintReturnControlC(PCCH Format,...)
Definition: debug.c:253
#define _vsnprintf
Definition: xmlstorage.h:202
#define RtlImageNtHeader
Definition: compat.h:457
BOOLEAN NTAPI RtlpSetInDbgPrint(VOID)
Definition: libsupp.c:33
#define DBG_STATUS_CONTROL_C
Definition: kdtypes.h:39
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define BREAKPOINT_COMMAND_STRING
Definition: kdtypes.h:55
struct Response Response
#define ULONG_PTR
Definition: config.h:101
DWORD ExceptionFlags
Definition: compat.h:197
CCHAR DebugString[256]
Definition: cmdline.c:22
ULONG_PTR ProcessId
Definition: kdtypes.h:171
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
DWORD NumberParameters
Definition: compat.h:200
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2725
NTKERNELAPI VOID DbgBreakPointWithStatus(ULONG Status)
Definition: debug.c:10
NTSTATUS NTAPI NtSetDebugFilterState(IN ULONG ComponentId, IN ULONG Level, IN BOOLEAN State)
Definition: kdmain.c:432
ULONG __cdecl DbgPrintEx(IN ULONG ComponentId, IN ULONG Level, IN PCCH Format,...)
Definition: debug.c:228