ReactOS 0.4.16-dev-195-g3bb1e64
kdb_cli.c File Reference
#include <ntoskrnl.h>
#include "kdb.h"
#include "../kd/kdterminal.h"
#include "debug.h"
Include dependency graph for kdb_cli.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define KDB_ENTER_CONDITION_TO_STRING(cond)
 
#define KDB_ACCESS_TYPE_TO_STRING(type)
 
#define NPX_STATE_TO_STRING(state)
 
#define Ke386GetGlobalDescriptorTable   __sgdt
 
#define Ke386GetLocalDescriptorTable   __sldt
 
#define KD_DEBUG_PRINT_FILTER(Name)    { #Name, DPFLTR_##Name##_ID }
 

Typedefs

typedef BOOLEAN(NTAPIPKDBG_CLI_ROUTINE) (IN PCHAR Command, IN ULONG Argc, IN PCH Argv[])
 

Functions

static BOOLEAN KdbpCmdEvalExpression (ULONG Argc, PCHAR Argv[])
 Evaluates an expression and displays the result.
 
static BOOLEAN KdbpCmdDisassembleX (ULONG Argc, PCHAR Argv[])
 Disassembles 10 instructions at eip or given address or displays 16 dwords from memory at given address.
 
static BOOLEAN KdbpCmdRegs (ULONG Argc, PCHAR Argv[])
 Displays CPU registers.
 
static BOOLEAN KdbpCmdBackTrace (ULONG Argc, PCHAR Argv[])
 Displays a backtrace.
 
static BOOLEAN KdbpCmdContinue (ULONG Argc, PCHAR Argv[])
 Continues execution of the system/leaves KDB.
 
static BOOLEAN KdbpCmdStep (ULONG Argc, PCHAR Argv[])
 Continues execution of the system/leaves KDB.
 
static BOOLEAN KdbpCmdBreakPointList (ULONG Argc, PCHAR Argv[])
 Lists breakpoints.
 
static BOOLEAN KdbpCmdEnableDisableClearBreakPoint (ULONG Argc, PCHAR Argv[])
 Enables, disables or clears a breakpoint.
 
static BOOLEAN KdbpCmdBreakPoint (ULONG Argc, PCHAR Argv[])
 Sets a software or hardware (memory) breakpoint at the given address.
 
static BOOLEAN KdbpCmdThread (ULONG Argc, PCHAR Argv[])
 Lists threads or switches to another thread context.
 
static BOOLEAN KdbpCmdProc (ULONG Argc, PCHAR Argv[])
 Lists processes or switches to another process context.
 
static BOOLEAN KdbpCmdMod (ULONG Argc, PCHAR Argv[])
 Lists loaded modules or the one containing the specified address.
 
static BOOLEAN KdbpCmdGdtLdtIdt (ULONG Argc, PCHAR Argv[])
 Displays GDT, LDT or IDT.
 
static BOOLEAN KdbpCmdPcr (ULONG Argc, PCHAR Argv[])
 Displays the KPCR.
 
static BOOLEAN KdbpCmdBugCheck (ULONG Argc, PCHAR Argv[])
 Bugchecks the system.
 
static BOOLEAN KdbpCmdReboot (ULONG Argc, PCHAR Argv[])
 
static BOOLEAN KdbpCmdFilter (ULONG Argc, PCHAR Argv[])
 Displays the list of active debug channels, or enable/disable debug channels.
 
static BOOLEAN KdbpCmdSet (ULONG Argc, PCHAR Argv[])
 Sets or displays a config variables value.
 
static BOOLEAN KdbpCmdHelp (ULONG Argc, PCHAR Argv[])
 Displays help screen.
 
static BOOLEAN KdbpCmdDmesg (ULONG Argc, PCHAR Argv[])
 Display debug messages on screen, with paging.
 
BOOLEAN ExpKdbgExtPool (ULONG Argc, PCHAR Argv[])
 
BOOLEAN ExpKdbgExtPoolUsed (ULONG Argc, PCHAR Argv[])
 
BOOLEAN ExpKdbgExtPoolFind (ULONG Argc, PCHAR Argv[])
 
BOOLEAN ExpKdbgExtFileCache (ULONG Argc, PCHAR Argv[])
 
BOOLEAN ExpKdbgExtDefWrites (ULONG Argc, PCHAR Argv[])
 
BOOLEAN ExpKdbgExtIrpFind (ULONG Argc, PCHAR Argv[])
 
BOOLEAN ExpKdbgExtHandle (ULONG Argc, PCHAR Argv[])
 
FORCEINLINE ULONG_PTR strtoulptr (const char *nptr, char **endptr, int base)
 
static BOOLEAN KdbpEvaluateExpression (IN PCHAR Expression, IN LONG ErrOffset, OUT PULONGLONG Result)
 Evaluates an expression...
 
BOOLEAN NTAPI KdbpGetHexNumber (IN PCHAR pszNum, OUT ULONG_PTR *pulValue)
 
static BOOLEAN KdbpGetComponentId (IN PCSTR ComponentName, OUT PULONG ComponentId)
 Retrieves the component ID corresponding to a given component name.
 
voidmemrchr (const void *s, int c, size_t n)
 
static PCHAR CountOnePageUp (_In_ PCCH Buffer, _In_ ULONG BufLength, _In_ PCCH pCurPos, _In_ const SIZE *TermSize)
 Calculate pointer position for N lines above the current position.
 
static VOID KdpFilterEscapes (_Inout_ PSTR String)
 
static VOID KdbpPagerInternal (_In_ PCHAR Buffer, _In_ ULONG BufLength, _In_ BOOLEAN DoPage)
 Prints the given string with, page by page.
 
VOID KdbpPager (_In_ PCHAR Buffer, _In_ ULONG BufLength)
 Prints the given string with, page by page.
 
VOID KdbpPrint (_In_ PSTR Format, _In_ ...)
 Prints the given string with printf-like formatting.
 
VOID KdbpPrintUnicodeString (_In_ PCUNICODE_STRING String)
 
BOOLEAN NTAPI KdbRegisterCliCallback (PVOID Callback, BOOLEAN Deregister)
 
static BOOLEAN KdbpInvokeCliCallbacks (IN PCHAR Command, IN ULONG Argc, IN PCHAR Argv[])
 Invokes registered CLI callbacks until one of them handled the Command.
 
static BOOLEAN KdbpDoCommand (IN PCHAR Command)
 Parses command line and executes command if found.
 
VOID KdbpCliMainLoop (IN BOOLEAN EnteredOnSingleStep)
 KDB Main Loop.
 
VOID KdbpCliInterpretInitFile (VOID)
 Interprets the KDBinit file from the \SystemRoot\System32\drivers\etc directory, that has been loaded by KdbpCliInit().
 
NTSTATUS KdbpCliInit (VOID)
 Called when KDB is initialized.
 
static VOID NTAPI KdbDebugPrint (_In_ PCCH String, _In_ ULONG Length)
 Debug logger function.
 
NTSTATUS NTAPI KdbInitialize (_In_ PKD_DISPATCH_TABLE DispatchTable, _In_ ULONG BootPhase)
 Initializes the KDBG debugger.
 

Variables

char __ImageBase
 
static PKDBG_CLI_ROUTINE KdbCliCallbacks [10]
 
static BOOLEAN KdbUseIntelSyntax = FALSE
 
static BOOLEAN KdbBreakOnModuleLoad = FALSE
 
static ULONG KdbNumberOfRowsPrinted = 0
 
static ULONG KdbNumberOfColsPrinted = 0
 
static BOOLEAN KdbOutputAborted = FALSE
 
static BOOLEAN KdbRepeatLastCommand = FALSE
 
volatile PCHAR KdbInitFileBuffer = NULL
 
BOOLEAN KdbpBugCheckRequested = FALSE
 
static const ULONG KdpDmesgBufferSize = 128 * 1024
 
static PCHAR KdpDmesgBuffer = NULL
 
static volatile ULONG KdpDmesgCurrentPosition = 0
 
static volatile ULONG KdpDmesgFreeBytes = 0
 
static volatile ULONG KdbDmesgTotalWritten = 0
 
static volatile BOOLEAN KdbpIsInDmesgMode = FALSE
 
static KSPIN_LOCK KdpDmesgLogSpinLock
 
const CSTRING KdbPromptStr = RTL_CONSTANT_STRING("kdb:> ")
 
struct {
   PCSTR   Name
 
   ULONG   Id
 
ComponentTable []
 
struct {
   PCHAR   Name
 
   PCHAR   Syntax
 
   PCHAR   Help
 
   BOOLEAN(*   Fn )(ULONG Argc, PCHAR Argv[])
 
KdbDebuggerCommands []
 

Macro Definition Documentation

◆ KD_DEBUG_PRINT_FILTER

#define KD_DEBUG_PRINT_FILTER (   Name)     { #Name, DPFLTR_##Name##_ID }

Definition at line 154 of file kdb_cli.c.

◆ KDB_ACCESS_TYPE_TO_STRING

#define KDB_ACCESS_TYPE_TO_STRING (   type)
Value:
((type) == KdbAccessRead ? "read" : \
((type) == KdbAccessWrite ? "write" : \
((type) == KdbAccessReadWrite ? "rdwr" : "exec")))
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
@ KdbAccessRead
Definition: kdb.h:19
@ KdbAccessReadWrite
Definition: kdb.h:21
@ KdbAccessWrite
Definition: kdb.h:20

Definition at line 46 of file kdb_cli.c.

◆ KDB_ENTER_CONDITION_TO_STRING

#define KDB_ENTER_CONDITION_TO_STRING (   cond)
Value:
((cond) == KdbDoNotEnter ? "never" : \
((cond) == KdbEnterAlways ? "always" : \
((cond) == KdbEnterFromKmode ? "kmode" : "umode")))
@ KdbDoNotEnter
Definition: kdb.h:48
@ KdbEnterAlways
Definition: kdb.h:49
@ KdbEnterFromKmode
Definition: kdb.h:50

Definition at line 41 of file kdb_cli.c.

◆ Ke386GetGlobalDescriptorTable

#define Ke386GetGlobalDescriptorTable   __sgdt

Definition at line 101 of file kdb_cli.c.

◆ Ke386GetLocalDescriptorTable

#define Ke386GetLocalDescriptorTable   __sldt

Definition at line 104 of file kdb_cli.c.

◆ NDEBUG

#define NDEBUG

Definition at line 36 of file kdb_cli.c.

◆ NPX_STATE_TO_STRING

#define NPX_STATE_TO_STRING (   state)
Value:
((state) == NPX_STATE_LOADED ? "Loaded" : \
((state) == NPX_STATE_NOT_LOADED ? "Not loaded" : "Unknown"))
static int state
Definition: maze.c:121
#define NPX_STATE_NOT_LOADED
Definition: asm.h:265
#define NPX_STATE_LOADED
Definition: asm.h:266

Definition at line 51 of file kdb_cli.c.

Typedef Documentation

◆ PKDBG_CLI_ROUTINE

typedef BOOLEAN(NTAPI * PKDBG_CLI_ROUTINE) (IN PCHAR Command, IN ULONG Argc, IN PCH Argv[])

Definition at line 122 of file kdb_cli.c.

Function Documentation

◆ CountOnePageUp()

static PCHAR CountOnePageUp ( _In_ PCCH  Buffer,
_In_ ULONG  BufLength,
_In_ PCCH  pCurPos,
_In_ const SIZE TermSize 
)
static

Calculate pointer position for N lines above the current position.

Calculate pointer position for N lines above the current displaying position within the given buffer. Used by KdbpPager().

Parameters
[in]BufferCharacter buffer to operate on.
[in]BufLengthSize of the buffer.
[in]pCurPosCurrent position within the buffer.
Returns
Beginning of the previous page of text.
Note
N lines count is hardcoded to the terminal's number of rows.

Definition at line 2807 of file kdb_cli.c.

2812{
2813 PCCH p;
2814 // p0 is initial guess of Page Start
2815 ULONG p0len = TermSize->cx * TermSize->cy;
2816 PCCH p0 = pCurPos - p0len;
2817 PCCH prev_p = p0, p1;
2818 ULONG j;
2819
2820 if (pCurPos < Buffer)
2821 pCurPos = Buffer;
2822 ASSERT(pCurPos <= Buffer + BufLength);
2823
2824 p = memrchr(p0, '\n', p0len);
2825 if (!p)
2826 p = p0;
2827 for (j = TermSize->cy; j--; )
2828 {
2829 int linesCnt;
2830 p1 = memrchr(p0, '\n', p-p0);
2831 prev_p = p;
2832 p = p1;
2833 if (!p)
2834 {
2835 p = prev_p;
2836 if (!p)
2837 p = p0;
2838 break;
2839 }
2840 linesCnt = (TermSize->cx+prev_p-p-2) / TermSize->cx;
2841 if (linesCnt > 1)
2842 j -= linesCnt-1;
2843 }
2844
2845 ASSERT(p != NULL);
2846 ++p;
2847 return (PCHAR)p;
2848}
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
GLfloat GLfloat p
Definition: glext.h:8902
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 GLint GLint j
Definition: glfuncs.h:250
void * memrchr(const void *s, int c, size_t n)
Definition: kdb_cli.c:2771
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
CONST CHAR * PCCH
Definition: ntbasedef.h:392
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51

Referenced by KdbpPagerInternal().

◆ ExpKdbgExtDefWrites()

BOOLEAN ExpKdbgExtDefWrites ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ ExpKdbgExtFileCache()

BOOLEAN ExpKdbgExtFileCache ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ ExpKdbgExtHandle()

BOOLEAN ExpKdbgExtHandle ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ ExpKdbgExtIrpFind()

BOOLEAN ExpKdbgExtIrpFind ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ ExpKdbgExtPool()

BOOLEAN ExpKdbgExtPool ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ ExpKdbgExtPoolFind()

BOOLEAN ExpKdbgExtPoolFind ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ ExpKdbgExtPoolUsed()

BOOLEAN ExpKdbgExtPoolUsed ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ KdbDebugPrint()

static VOID NTAPI KdbDebugPrint ( _In_ PCCH  String,
_In_ ULONG  Length 
)
static

Debug logger function.

This function writes text strings into KdpDmesgBuffer, using it as a circular buffer. KdpDmesgBuffer contents can be later (re)viewed using the dmesg command. KdbDebugPrint() protects KdpDmesgBuffer from simultaneous writes by use of KdpDmesgLogSpinLock.

Definition at line 3494 of file kdb_cli.c.

3497{
3498 KIRQL OldIrql;
3499 ULONG beg, end, num;
3500
3501 /* Avoid recursive calling if we already are in Dmesg mode */
3503 return;
3504
3505 if (KdpDmesgBuffer == NULL)
3506 return;
3507
3508 /* Acquire the printing spinlock without waiting at raised IRQL */
3510
3512 /* Invariant: always_true(KdpDmesgFreeBytes == KdpDmesgBufferSize); */
3514 if (num != 0)
3515 {
3516 end = (beg + num) % KdpDmesgBufferSize;
3517 if (end > beg)
3518 {
3520 }
3521 else
3522 {
3525 }
3527
3528 /* Counting the total bytes written */
3530 }
3531
3532 /* Release the spinlock */
3534
3535 /* Optional step(?): find out a way to notify about buffer exhaustion,
3536 * and possibly fall into kbd to use dmesg command: user will read
3537 * debug strings before they will be wiped over by next writes. */
3538}
UCHAR KIRQL
Definition: env_spec_w32.h:591
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint num
Definition: glext.h:9618
VOID NTAPI KdbpReleaseLock(_In_ PKSPIN_LOCK SpinLock, _In_ KIRQL OldIrql)
Definition: kdio.c:91
KIRQL NTAPI KdbpAcquireLock(_In_ PKSPIN_LOCK SpinLock)
Definition: kdio.c:64
static KSPIN_LOCK KdpDmesgLogSpinLock
Definition: kdb_cli.c:147
static const ULONG KdpDmesgBufferSize
Definition: kdb_cli.c:141
static volatile ULONG KdpDmesgCurrentPosition
Definition: kdb_cli.c:143
static volatile ULONG KdpDmesgFreeBytes
Definition: kdb_cli.c:144
static PCHAR KdpDmesgBuffer
Definition: kdb_cli.c:142
static volatile ULONG KdbDmesgTotalWritten
Definition: kdb_cli.c:145
static volatile BOOLEAN KdbpIsInDmesgMode
Definition: kdb_cli.c:146
#define min(a, b)
Definition: monoChain.cc:55
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by KdbInitialize().

◆ KdbInitialize()

NTSTATUS NTAPI KdbInitialize ( _In_ PKD_DISPATCH_TABLE  DispatchTable,
_In_ ULONG  BootPhase 
)

Initializes the KDBG debugger.

Parameters
[in]DispatchTablePointer to the KD dispatch table.
[in]BootPhasePhase of initialization.
Returns
A status value.
Note
Also known as "KdpKdbgInit".

Definition at line 3554 of file kdb_cli.c.

3557{
3558 /* Saves the different symbol-loading status across boot phases */
3559 static ULONG LoadSymbols = 0;
3560
3561 if (BootPhase == 0)
3562 {
3563 /* Write out the functions that we support for now */
3564 DispatchTable->KdpPrintRoutine = KdbDebugPrint;
3565
3566 /* Check if we have a command line */
3568 {
3569 /* Get the KDBG Settings */
3571 }
3572
3573 /* Register for BootPhase 1 initialization and as a Provider */
3574 DispatchTable->KdpInitRoutine = KdbInitialize;
3575 InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
3576 }
3577 else if (BootPhase == 1)
3578 {
3579 /* Register for later BootPhase 2 reinitialization */
3580 DispatchTable->KdpInitRoutine = KdbInitialize;
3581
3582 /* Initialize Dmesg support */
3583
3584 /* Allocate a buffer for Dmesg log buffer. +1 for terminating null,
3585 * see kdbp_cli.c:KdbpCmdDmesg()/2 */
3588 TAG_KDBG);
3589 /* Ignore failure if KdpDmesgBuffer is NULL */
3592
3593 /* Initialize spinlock */
3595 }
3596
3597 /* Initialize symbols support in BootPhase 0 and 1 */
3598 if (BootPhase <= 1)
3599 {
3600 LoadSymbols <<= 1;
3601 LoadSymbols |= KdbSymInit(BootPhase);
3602 }
3603
3604 if (BootPhase == 1)
3605 {
3606 /* Announce ourselves */
3607 CHAR buffer[60];
3609 " KDBG debugger enabled - %s\r\n",
3610 !(LoadSymbols & 0x2) ? "No symbols loaded" :
3611 !(LoadSymbols & 0x1) ? "Kernel symbols loaded"
3612 : "Loading symbols");
3614 }
3615
3616 if (BootPhase >= 2)
3617 {
3618 /* I/O is now set up for disk access: load the KDBinit file */
3620
3621 /* Schedule an I/O reinitialization if needed */
3624 {
3625 DispatchTable->KdpInitRoutine = KdbInitialize;
3626 }
3627 }
3628
3629 return STATUS_SUCCESS;
3630}
LONG NTSTATUS
Definition: precomp.h:26
#define InsertTailList(ListHead, Entry)
#define NonPagedPool
Definition: env_spec_w32.h:307
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
Status
Definition: gdiplustypes.h:25
GLuint buffer
Definition: glext.h:5915
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
LIST_ENTRY KdProviders
Definition: kdio.c:47
VOID KdbpGetCommandLineSettings(_In_ PCSTR p1)
Definition: kdb.c:1635
BOOLEAN KdbSymInit(_In_ ULONG BootPhase)
Initializes the KDB symbols implementation.
Definition: kdb_symbols.c:343
static VOID NTAPI KdbDebugPrint(_In_ PCCH String, _In_ ULONG Length)
Debug logger function.
Definition: kdb_cli.c:3494
NTSTATUS NTAPI KdbInitialize(_In_ PKD_DISPATCH_TABLE DispatchTable, _In_ ULONG BootPhase)
Initializes the KDBG debugger.
Definition: kdb_cli.c:3554
NTSTATUS KdbpCliInit(VOID)
Called when KDB is initialized.
Definition: kdb_cli.c:3403
static BOOLEAN LoadSymbols
Definition: kdb_symbols.c:30
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
FORCEINLINE PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TAG_KDBG
Definition: tag.h:38
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_In_ PWDFDEVICE_INIT _In_ PWDF_PDO_EVENT_CALLBACKS DispatchTable
Definition: wdfpdo.h:248
char CHAR
Definition: xmlstorage.h:175

Referenced by KdbInitialize().

◆ KdbpCliInit()

NTSTATUS KdbpCliInit ( VOID  )

Called when KDB is initialized.

Loads the KDBinit file from the \SystemRoot\System32\drivers\etc directory and interprets it, by calling back into the debugger.

Definition at line 3403 of file kdb_cli.c.

3404{
3409 FILE_STANDARD_INFORMATION FileStdInfo;
3410 HANDLE hFile = NULL;
3412 PCHAR FileBuffer;
3413
3414 /* Don't load the KDBinit file if its buffer is already lying around */
3416 return STATUS_SUCCESS;
3417
3418 /* Initialize the object attributes */
3419 RtlInitUnicodeString(&FileName, L"\\SystemRoot\\System32\\drivers\\etc\\KDBinit");
3421 &FileName,
3423 NULL,
3424 NULL);
3425
3426 /* Open the file */
3428 &ObjectAttributes, &Iosb, 0,
3431 if (!NT_SUCCESS(Status))
3432 {
3433 DPRINT("Could not open %wZ (Status 0x%lx)\n", &FileName, Status);
3434 return Status;
3435 }
3436
3437 /* Get the size of the file */
3438 Status = ZwQueryInformationFile(hFile, &Iosb,
3439 &FileStdInfo, sizeof(FileStdInfo),
3441 if (!NT_SUCCESS(Status))
3442 {
3443 ZwClose(hFile);
3444 DPRINT1("Could not query size of %wZ (Status 0x%lx)\n", &FileName, Status);
3445 return Status;
3446 }
3447 FileSize = FileStdInfo.EndOfFile.u.LowPart;
3448
3449 /* Allocate memory for the file (add 1 byte for terminating NUL) */
3450 FileBuffer = ExAllocatePool(NonPagedPool, FileSize + 1);
3451 if (!FileBuffer)
3452 {
3453 ZwClose(hFile);
3454 DPRINT1("Could not allocate %lu bytes for KDBinit file\n", FileSize);
3455 return Status;
3456 }
3457
3458 /* Load file into memory */
3459 Status = ZwReadFile(hFile, NULL, NULL, NULL, &Iosb,
3460 FileBuffer, FileSize, NULL, NULL);
3461 ZwClose(hFile);
3462
3464 {
3465 ExFreePool(FileBuffer);
3466 DPRINT1("Could not read KDBinit file into memory (Status 0x%lx)\n", Status);
3467 return Status;
3468 }
3469
3470 FileSize = min(FileSize, (ULONG)Iosb.Information);
3471 FileBuffer[FileSize] = ANSI_NULL;
3472
3473 /* Interpret the KDBinit file by calling back into the debugger */
3477
3478 ExFreePool(FileBuffer);
3479
3480 return STATUS_SUCCESS;
3481}
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define DPRINT1
Definition: precomp.h:8
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
return Iosb
Definition: create.c:4402
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
struct _FileName FileName
Definition: fatprocs.h:897
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
volatile PCHAR KdbInitFileBuffer
Definition: kdb_cli.c:137
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ HANDLE hFile
Definition: mswsock.h:90
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
#define DBG_STATUS_CONTROL_C
Definition: kdtypes.h:39
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_DATA
Definition: nt_native.h:628
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ANSI_NULL
#define L(x)
Definition: ntvdm.h:50
#define FileStandardInformation
Definition: propsheet.cpp:61
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define DPRINT
Definition: sndvol32.h:73
__analysis_noreturn NTSYSAPI VOID NTAPI DbgBreakPointWithStatus(_In_ ULONG Status)
struct _LARGE_INTEGER::@2299 u

Referenced by KdbInitialize().

◆ KdbpCliInterpretInitFile()

VOID KdbpCliInterpretInitFile ( VOID  )

Interprets the KDBinit file from the \SystemRoot\System32\drivers\etc directory, that has been loaded by KdbpCliInit().

This function is used to interpret the init file in the debugger context with a trap frame set up. KdbpCliInit() enters the debugger by calling DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C). In turn, this will call KdbEnterDebuggerException() which will finally call this function if KdbInitFileBuffer is not NULL.

Definition at line 3351 of file kdb_cli.c.

3352{
3353 PCHAR p1, p2;
3354
3356 if (!p1)
3357 return;
3358
3359 /* Execute the commands in the init file */
3360 KdbPuts("KDB: Executing KDBinit file...\n");
3361 while (p1[0] != '\0')
3362 {
3363 size_t i = strcspn(p1, "\r\n");
3364 if (i > 0)
3365 {
3366 CHAR c = p1[i];
3367 p1[i] = '\0';
3368
3369 /* Look for "break" command and comments */
3370 p2 = p1;
3371 while (isspace(p2[0]))
3372 p2++;
3373
3374 if (strncmp(p2, "break", sizeof("break")-1) == 0 &&
3375 (p2[sizeof("break")-1] == '\0' || isspace(p2[sizeof("break")-1])))
3376 {
3377 /* Run the interactive debugger loop */
3379 }
3380 else if (p2[0] != '#' && p2[0] != '\0') /* Ignore empty lines and comments */
3381 {
3382 /* Invoke the command */
3383 KdbpDoCommand(p1);
3384 }
3385
3386 p1[i] = c;
3387 }
3388
3389 p1 += i;
3390 while (p1[0] == '\r' || p1[0] == '\n')
3391 p1++;
3392 }
3393 KdbPuts("KDB: KDBinit executed\n");
3394}
#define isspace(c)
Definition: acclib.h:69
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define FALSE
Definition: types.h:117
const GLubyte * c
Definition: glext.h:8905
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
VOID KdbPuts(_In_ PCSTR String)
Definition: kdb_print.c:152
static BOOLEAN KdbpDoCommand(IN PCHAR Command)
Parses command line and executes command if found.
Definition: kdb_cli.c:3205
VOID KdbpCliMainLoop(IN BOOLEAN EnteredOnSingleStep)
KDB Main Loop.
Definition: kdb_cli.c:3274
#define c
Definition: ke_i.h:80
_Check_return_ _CRTIMP size_t __cdecl strcspn(_In_z_ const char *_Str, _In_z_ const char *_Control)

Referenced by KdbEnterDebuggerException().

◆ KdbpCliMainLoop()

VOID KdbpCliMainLoop ( IN BOOLEAN  EnteredOnSingleStep)

KDB Main Loop.

Parameters
EnteredOnSingleStepTRUE if KDB was entered on single step.

Definition at line 3274 of file kdb_cli.c.

3276{
3277 BOOLEAN Continue = TRUE;
3278 static CHAR Command[1024];
3279 static CHAR LastCommand[1024] = "";
3280
3281// FIXME HACK: SYSREG SUPPORT CORE-19807 -- Emit a backtrace.
3282// TODO: Remove once SYSREG "bt" command emission is fixed!
3283#if 1
3284 KdbpDoCommand("bt");
3285#endif
3286
3287 if (EnteredOnSingleStep)
3288 {
3291
3292 KdbPuts(": ");
3294 KdbPuts("<INVALID>");
3295 KdbPuts("\n");
3296 }
3297 else
3298 {
3299 /* Preceding this message is one of the "Entered debugger..." banners */
3300 // KdbPuts("\nEntered debugger\n");
3301 KdbPuts("\nType \"help\" for a list of commands.\n");
3302 }
3303
3304 /* Main loop */
3305 while (Continue)
3306 {
3307 /*
3308 * Print the prompt and read a command.
3309 * Repeat the last one if the user pressed Enter.
3310 * This reduces the risk of RSI when single-stepping!
3311 */
3312 // TEMP HACK! Issue an empty string instead of duplicating "kdb:>"
3313 SIZE_T CmdLen = KdbPrompt(/*KdbPromptStr.Buffer*/"", Command, sizeof(Command));
3314 if (CmdLen == 0)
3315 {
3316 /* Nothing received but the user didn't press Enter, retry */
3317 continue;
3318 }
3319 else if (CmdLen > 1) // i.e. (*Command != ANSI_NULL)
3320 {
3321 /* Save this new last command */
3323 RtlStringCbCopyA(LastCommand, sizeof(LastCommand), Command);
3324
3325 /* Remember it */
3327 }
3328 else if (KdbRepeatLastCommand)
3329 {
3330 /* The user directly pressed Enter */
3331 RtlStringCbCopyA(Command, sizeof(Command), LastCommand);
3332 }
3333
3334 /* Invoke the command */
3335 Continue = KdbpDoCommand(Command);
3336 }
3337}
unsigned char BOOLEAN
#define TRUE
Definition: types.h:120
LONG KdbpDisassemble(IN ULONG_PTR Address, IN ULONG IntelSyntax)
Definition: i386-dis.c:124
PKDB_KTRAP_FRAME KdbCurrentTrapFrame
Definition: kdb.c:56
BOOLEAN KdbSymPrintAddress(IN PVOID Address, IN PCONTEXT Context)
Print address...
Definition: kdb_symbols.c:149
VOID KdbpCommandHistoryAppend(_In_ PCSTR Command)
Appends a command to the command history.
Definition: kdb_cmdhist.c:37
VOID __cdecl KdbPrintf(_In_ PCSTR Format,...)
Definition: kdb_print.c:160
SIZE_T KdbPrompt(_In_ PCSTR Prompt, _Out_ PCHAR Buffer, _In_ SIZE_T Size)
Definition: kdb_print.c:182
static BOOLEAN KdbRepeatLastCommand
Definition: kdb_cli.c:135
static BOOLEAN KdbUseIntelSyntax
Definition: kdb_cli.c:129
#define KeGetContextPc(Context)
Definition: ke.h:31
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
Definition: shell.h:41
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by KdbpCallMainLoop(), and KdbpCliInterpretInitFile().

◆ KdbpCmdBackTrace()

static BOOLEAN KdbpCmdBackTrace ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Displays a backtrace.

Definition at line 1225 of file kdb_cli.c.

1228{
1229 ULONG ul;
1230 ULONGLONG Result = 0;
1234
1235 if (Argc >= 2)
1236 {
1237 /* Check for [L count] part */
1238 ul = 0;
1239 if (strcmp(Argv[Argc-2], "L") == 0)
1240 {
1241 ul = strtoul(Argv[Argc-1], NULL, 0);
1242 if (ul > 0)
1243 {
1244 Argc -= 2;
1245 }
1246 }
1247 else if (Argv[Argc-1][0] == 'L')
1248 {
1249 ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
1250 if (ul > 0)
1251 {
1252 Argc--;
1253 }
1254 }
1255
1256 /* Put the remaining arguments back together */
1257 Argc--;
1258 for (ul = 1; ul < Argc; ul++)
1259 {
1260 Argv[ul][strlen(Argv[ul])] = ' ';
1261 }
1262 Argc++;
1263 }
1264
1265 /* Check if a Frame Address or Thread ID is given */
1266 if (Argc > 1)
1267 {
1268 if (Argv[1][0] == '*')
1269 {
1270 Argv[1]++;
1271
1272 /* Evaluate the expression */
1273 if (!KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result))
1274 return TRUE;
1275
1276 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
1277 KdbpPrint("Warning: Address %I64x is beeing truncated\n", Result);
1278
1279 Frame = (ULONG_PTR)Result;
1280 }
1281 else
1282 {
1283 KdbpPrint("Thread backtrace not supported yet!\n");
1284 return TRUE;
1285 }
1286 }
1287
1288#ifdef _M_IX86
1289 KDESCRIPTOR Gdtr;
1290 USHORT TssSelector;
1291 PKTSS Tss;
1292
1293 /* Retrieve the Global Descriptor Table */
1295
1296 /* Retrieve the current (active) TSS */
1297 TssSelector = Ke386GetTr();
1298 Tss = KdbpRetrieveTss(TssSelector, NULL, &Gdtr);
1299 if (KdbpIsNestedTss(TssSelector, Tss))
1300 {
1301 /* Display the active TSS if it is nested */
1302 KdbpPrint("[Active TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
1303 }
1304#endif
1305
1306 /* If no Frame Address or Thread ID was given, try printing the function at EIP */
1307 if (Argc <= 1)
1308 {
1309 KdbpPrint("Eip:\n");
1311 KdbpPrint("<%p>\n", KeGetContextPc(&Context));
1312 else
1313 KdbpPrint("\n");
1314 }
1315
1316 /* Walk through the frames */
1317 KdbpPrint("Frames:\n");
1318 for (;;)
1319 {
1320 BOOLEAN GotNextFrame;
1321
1322 if (Frame == 0)
1323 goto CheckForParentTSS;
1324
1325 Address = 0;
1326 if (!NT_SUCCESS(KdbpSafeReadMemory(&Address, (PVOID)(Frame + sizeof(ULONG_PTR)), sizeof(ULONG_PTR))))
1327 {
1328 KdbpPrint("Couldn't access memory at 0x%p!\n", Frame + sizeof(ULONG_PTR));
1329 goto CheckForParentTSS;
1330 }
1331
1332 if (Address == 0)
1333 goto CheckForParentTSS;
1334
1335 GotNextFrame = NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof(ULONG_PTR)));
1336 if (GotNextFrame)
1337 {
1339 }
1340 // else
1341 // Frame = 0;
1342
1343 /* Print the location of the call instruction (assumed 5 bytes length) */
1344 if (!KdbSymPrintAddress((PVOID)(Address - 5), &Context))
1345 KdbpPrint("<%08x>\n", Address);
1346 else
1347 KdbpPrint("\n");
1348
1349 if (KdbOutputAborted)
1350 break;
1351
1352 if (!GotNextFrame)
1353 {
1354 KdbpPrint("Couldn't access memory at 0x%p!\n", Frame);
1355 goto CheckForParentTSS; // break;
1356 }
1357
1358 continue;
1359
1360CheckForParentTSS:
1361#ifndef _M_IX86
1362 break;
1363#else
1364 /*
1365 * We have ended the stack walking for the current (active) TSS.
1366 * Check whether this TSS was nested, and if so switch to its parent
1367 * and walk its stack.
1368 */
1369 if (!KdbpIsNestedTss(TssSelector, Tss))
1370 break; // The TSS is not nested, we stop there.
1371
1372 GotNextFrame = KdbpContextFromPrevTss(&Context, &TssSelector, &Tss, &Gdtr);
1373 if (!GotNextFrame)
1374 {
1375 KdbpPrint("Couldn't access parent TSS 0x%04x\n", Tss->Backlink);
1376 break; // Cannot retrieve the parent TSS, we stop there.
1377 }
1378
1379
1380 Address = Context.Eip;
1381 Frame = Context.Ebp;
1382
1383 KdbpPrint("[Parent TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
1384
1386 KdbpPrint("<%08x>\n", Address);
1387 else
1388 KdbpPrint("\n");
1389#endif
1390 }
1391
1392 return TRUE;
1393}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ULONG_PTR
Definition: config.h:101
NTSTATUS KdbpSafeReadMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
Definition: kdb.c:1657
static BOOLEAN KdbpEvaluateExpression(IN PCHAR Expression, IN LONG ErrOffset, OUT PULONGLONG Result)
Evaluates an expression...
Definition: kdb_cli.c:423
#define Ke386GetGlobalDescriptorTable
Definition: kdb_cli.c:101
static BOOLEAN KdbOutputAborted
Definition: kdb_cli.c:134
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:3081
const CSTRING KdbPromptStr
Definition: kdb_cli.c:149
FORCEINLINE ULONG_PTR KeGetContextFrameRegister(PCONTEXT Context)
Definition: ke.h:165
FORCEINLINE VOID KeSetContextFrameRegister(PCONTEXT Context, ULONG_PTR Frame)
Definition: ke.h:172
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
USHORT Length
Definition: umtypes.h:157
USHORT Limit
Definition: ketypes.h:559
Definition: ketypes.h:844
USHORT Backlink
Definition: ketypes.h:845
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint64_t ULONGLONG
Definition: typedefs.h:67
_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:409

◆ KdbpCmdBreakPoint()

static BOOLEAN KdbpCmdBreakPoint ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Sets a software or hardware (memory) breakpoint at the given address.

Definition at line 1579 of file kdb_cli.c.

1580{
1581 ULONGLONG Result = 0;
1584 UCHAR Size = 0;
1585 KDB_ACCESS_TYPE AccessType = 0;
1586 ULONG AddressArgIndex, i;
1587 LONG ConditionArgIndex;
1589
1590 if (Argv[0][2] == 'x') /* software breakpoint */
1591 {
1592 if (Argc < 2)
1593 {
1594 KdbpPrint("bpx: Address argument required.\n");
1595 return TRUE;
1596 }
1597
1598 AddressArgIndex = 1;
1600 }
1601 else /* memory breakpoint */
1602 {
1603 ASSERT(Argv[0][2] == 'm');
1604
1605 if (Argc < 2)
1606 {
1607 KdbpPrint("bpm: Access type argument required (one of r, w, rw, x)\n");
1608 return TRUE;
1609 }
1610
1611 if (_stricmp(Argv[1], "x") == 0)
1612 AccessType = KdbAccessExec;
1613 else if (_stricmp(Argv[1], "r") == 0)
1614 AccessType = KdbAccessRead;
1615 else if (_stricmp(Argv[1], "w") == 0)
1616 AccessType = KdbAccessWrite;
1617 else if (_stricmp(Argv[1], "rw") == 0)
1618 AccessType = KdbAccessReadWrite;
1619 else
1620 {
1621 KdbpPrint("bpm: Unknown access type '%s'\n", Argv[1]);
1622 return TRUE;
1623 }
1624
1625 if (Argc < 3)
1626 {
1627 KdbpPrint("bpm: %s argument required.\n", AccessType == KdbAccessExec ? "Address" : "Memory size");
1628 return TRUE;
1629 }
1630
1631 AddressArgIndex = 3;
1632 if (_stricmp(Argv[2], "byte") == 0)
1633 Size = 1;
1634 else if (_stricmp(Argv[2], "word") == 0)
1635 Size = 2;
1636 else if (_stricmp(Argv[2], "dword") == 0)
1637 Size = 4;
1638 else if (AccessType == KdbAccessExec)
1639 {
1640 Size = 1;
1641 AddressArgIndex--;
1642 }
1643 else
1644 {
1645 KdbpPrint("bpm: Unknown memory size '%s'\n", Argv[2]);
1646 return TRUE;
1647 }
1648
1649 if (Argc <= AddressArgIndex)
1650 {
1651 KdbpPrint("bpm: Address argument required.\n");
1652 return TRUE;
1653 }
1654
1656 }
1657
1658 /* Put the arguments back together */
1659 ConditionArgIndex = -1;
1660 for (i = AddressArgIndex; i < (Argc-1); i++)
1661 {
1662 if (strcmp(Argv[i+1], "IF") == 0) /* IF found */
1663 {
1664 ConditionArgIndex = i + 2;
1665 if ((ULONG)ConditionArgIndex >= Argc)
1666 {
1667 KdbpPrint("%s: IF requires condition expression.\n", Argv[0]);
1668 return TRUE;
1669 }
1670
1671 for (i = ConditionArgIndex; i < (Argc-1); i++)
1672 Argv[i][strlen(Argv[i])] = ' ';
1673
1674 break;
1675 }
1676
1677 Argv[i][strlen(Argv[i])] = ' ';
1678 }
1679
1680 /* Evaluate the address expression */
1681 if (!KdbpEvaluateExpression(Argv[AddressArgIndex],
1682 KdbPromptStr.Length + (Argv[AddressArgIndex]-Argv[0]),
1683 &Result))
1684 {
1685 return TRUE;
1686 }
1687
1688 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
1689 KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0],Result);
1690
1692
1693 KdbpInsertBreakPoint(Address, Type, Size, AccessType,
1694 (ConditionArgIndex < 0) ? NULL : Argv[ConditionArgIndex],
1695 Global, NULL);
1696
1697 return TRUE;
1698}
Type
Definition: Type.h:7
#define _stricmp
Definition: cat.c:22
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:478
@ KdbBreakPointSoftware
Definition: kdb.h:12
@ KdbBreakPointHardware
Definition: kdb.h:13
@ KdbAccessExec
Definition: kdb.h:22
enum _KDB_ACCESS_TYPE KDB_ACCESS_TYPE
enum _KDB_BREAKPOINT_TYPE KDB_BREAKPOINT_TYPE
UNICODE_STRING Global
Definition: symlink.c:46
long LONG
Definition: pedump.c:60
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
unsigned char UCHAR
Definition: xmlstorage.h:181

◆ KdbpCmdBreakPointList()

static BOOLEAN KdbpCmdBreakPointList ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Lists breakpoints.

Definition at line 1441 of file kdb_cli.c.

1444{
1445 LONG l;
1446 ULONG_PTR Address = 0;
1448 KDB_ACCESS_TYPE AccessType = 0;
1449 UCHAR Size = 0;
1450 UCHAR DebugReg = 0;
1454 PCHAR str1, str2, ConditionExpr, GlobalOrLocal;
1455 CHAR Buffer[20];
1456
1458 if (l < 0)
1459 {
1460 KdbpPrint("No breakpoints.\n");
1461 return TRUE;
1462 }
1463
1464 KdbpPrint("Breakpoints:\n");
1465 do
1466 {
1467 if (!KdbpGetBreakPointInfo(l, &Address, &Type, &Size, &AccessType, &DebugReg,
1468 &Enabled, &Global, &Process, &ConditionExpr))
1469 {
1470 continue;
1471 }
1472
1473 if (l == KdbLastBreakPointNr)
1474 {
1475 str1 = "\x1b[1m*";
1476 str2 = "\x1b[0m";
1477 }
1478 else
1479 {
1480 str1 = " ";
1481 str2 = "";
1482 }
1483
1484 if (Global)
1485 {
1486 GlobalOrLocal = " global";
1487 }
1488 else
1489 {
1490 GlobalOrLocal = Buffer;
1491 sprintf(Buffer, " PID 0x%Ix",
1492 (ULONG_PTR)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
1493 }
1494
1496 {
1497 KdbpPrint(" %s%03d BPX 0x%08x%s%s%s%s%s\n",
1498 str1, l, Address,
1499 Enabled ? "" : " disabled",
1500 GlobalOrLocal,
1501 ConditionExpr ? " IF " : "",
1502 ConditionExpr ? ConditionExpr : "",
1503 str2);
1504 }
1505 else if (Type == KdbBreakPointHardware)
1506 {
1507 if (!Enabled)
1508 {
1509 KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s disabled%s%s%s%s\n", str1, l, Address,
1510 KDB_ACCESS_TYPE_TO_STRING(AccessType),
1511 Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
1512 GlobalOrLocal,
1513 ConditionExpr ? " IF " : "",
1514 ConditionExpr ? ConditionExpr : "",
1515 str2);
1516 }
1517 else
1518 {
1519 KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s DR%d%s%s%s%s\n", str1, l, Address,
1520 KDB_ACCESS_TYPE_TO_STRING(AccessType),
1521 Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
1522 DebugReg,
1523 GlobalOrLocal,
1524 ConditionExpr ? " IF " : "",
1525 ConditionExpr ? ConditionExpr : "",
1526 str2);
1527 }
1528 }
1529 }
1530 while ((l = KdbpGetNextBreakPointNr(l+1)) >= 0);
1531
1532 return TRUE;
1533}
r l[0]
Definition: byte_order.h:168
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
LONG KdbpGetNextBreakPointNr(IN ULONG Start OPTIONAL)
Gets the number of the next breakpoint >= Start.
Definition: kdb.c:382
LONG KdbLastBreakPointNr
Definition: kdb.c:48
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.
Definition: kdb.c:409
@ KdbBreakPointTemporary
Definition: kdb.h:14
#define KDB_ACCESS_TYPE_TO_STRING(type)
Definition: kdb_cli.c:46
#define sprintf(buf, format,...)
Definition: sprintf.c:55
@ Enabled
Definition: mountmgr.h:179

◆ KdbpCmdBugCheck()

static BOOLEAN KdbpCmdBugCheck ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Bugchecks the system.

Definition at line 2490 of file kdb_cli.c.

2493{
2494 /* Set the flag and quit looping */
2496 return FALSE;
2497}
BOOLEAN KdbpBugCheckRequested
Definition: kdb_cli.c:138

◆ KdbpCmdContinue()

static BOOLEAN KdbpCmdContinue ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Continues execution of the system/leaves KDB.

Definition at line 1400 of file kdb_cli.c.

1403{
1404 /* Exit the main loop */
1405 return FALSE;
1406}

◆ KdbpCmdDisassembleX()

static BOOLEAN KdbpCmdDisassembleX ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Disassembles 10 instructions at eip or given address or displays 16 dwords from memory at given address.

Definition at line 800 of file kdb_cli.c.

803{
804 ULONG Count;
805 ULONG ul;
806 INT i;
807 ULONGLONG Result = 0;
809 LONG InstLen;
810
811 if (Argv[0][0] == 'x') /* display memory */
812 Count = 16;
813 else /* disassemble */
814 Count = 10;
815
816 if (Argc >= 2)
817 {
818 /* Check for [L count] part */
819 ul = 0;
820 if (strcmp(Argv[Argc-2], "L") == 0)
821 {
822 ul = strtoul(Argv[Argc-1], NULL, 0);
823 if (ul > 0)
824 {
825 Count = ul;
826 Argc -= 2;
827 }
828 }
829 else if (Argv[Argc-1][0] == 'L')
830 {
831 ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
832 if (ul > 0)
833 {
834 Count = ul;
835 Argc--;
836 }
837 }
838
839 /* Put the remaining arguments back together */
840 Argc--;
841 for (ul = 1; ul < Argc; ul++)
842 {
843 Argv[ul][strlen(Argv[ul])] = ' ';
844 }
845 Argc++;
846 }
847
848 /* Evaluate the expression */
849 if (Argc > 1)
850 {
851 if (!KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result))
852 return TRUE;
853
854 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
855 KdbpPrint("Warning: Address %I64x is beeing truncated\n",Result);
856
858 }
859 else if (Argv[0][0] == 'x')
860 {
861 KdbpPrint("x: Address argument required.\n");
862 return TRUE;
863 }
864
865 if (Argv[0][0] == 'x')
866 {
867 /* Display dwords */
868 ul = 0;
869
870 while (Count > 0)
871 {
873 KdbpPrint("<%p>:", (PVOID)Address);
874 else
875 KdbpPrint(":");
876
877 i = min(4, Count);
878 Count -= i;
879
880 while (--i >= 0)
881 {
882 if (!NT_SUCCESS(KdbpSafeReadMemory(&ul, (PVOID)Address, sizeof(ul))))
883 KdbpPrint(" ????????");
884 else
885 KdbpPrint(" %08x", ul);
886
887 Address += sizeof(ul);
888 }
889
890 KdbpPrint("\n");
891 }
892 }
893 else
894 {
895 /* Disassemble */
896 while (Count-- > 0)
897 {
899 KdbpPrint("<%08x>: ", Address);
900 else
901 KdbpPrint(": ");
902
904 if (InstLen < 0)
905 {
906 KdbpPrint("<INVALID>\n");
907 return TRUE;
908 }
909
910 KdbpPrint("\n");
911 Address += InstLen;
912 }
913 }
914
915 return TRUE;
916}
int Count
Definition: noreturn.cpp:7
int32_t INT
Definition: typedefs.h:58

◆ KdbpCmdDmesg()

static BOOLEAN KdbpCmdDmesg ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Display debug messages on screen, with paging.

Keys for per-page view: Home, End, PageUp, Arrow Up, PageDown, all others are as PageDown.

Definition at line 2515 of file kdb_cli.c.

2518{
2519 ULONG beg, end;
2520
2521 KdbpIsInDmesgMode = TRUE; /* Toggle logging flag */
2522 if (!KdpDmesgBuffer)
2523 {
2524 KdbpPrint("Dmesg: error, buffer is not allocated! /DEBUGPORT=SCREEN kernel param required for dmesg.\n");
2525 return TRUE;
2526 }
2527
2528 KdbpPrint("*** Dmesg *** TotalWritten=%lu, BufferSize=%lu, CurrentPosition=%lu\n",
2530
2531 /* Pass data to the pager */
2534
2535 /* No roll-overs, and overwritten=lost bytes */
2537 {
2538 /* Show buffer (KdpDmesgBuffer + beg, num) */
2540 }
2541 else
2542 {
2543 /* Show 2 buffers: (KdpDmesgBuffer + beg, KdpDmesgBufferSize - beg)
2544 * and: (KdpDmesgBuffer, end) */
2546 KdbpPrint("*** Dmesg: buffer rollup ***\n");
2548 }
2549 KdbpPrint("*** Dmesg: end of output ***\n");
2550
2551 KdbpIsInDmesgMode = FALSE; /* Toggle logging flag */
2552
2553 return TRUE;
2554}
VOID KdbpPager(_In_ PCHAR Buffer, _In_ ULONG BufLength)
Prints the given string with, page by page.
Definition: kdb_cli.c:3063

◆ KdbpCmdEnableDisableClearBreakPoint()

static BOOLEAN KdbpCmdEnableDisableClearBreakPoint ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Enables, disables or clears a breakpoint.

Definition at line 1538 of file kdb_cli.c.

1541{
1542 PCHAR pend;
1543 ULONG BreakPointNr;
1544
1545 if (Argc < 2)
1546 {
1547 KdbpPrint("%s: argument required\n", Argv[0]);
1548 return TRUE;
1549 }
1550
1551 pend = Argv[1];
1552 BreakPointNr = strtoul(Argv[1], &pend, 0);
1553 if (pend == Argv[1] || *pend != '\0')
1554 {
1555 KdbpPrint("%s: integer argument required\n", Argv[0]);
1556 return TRUE;
1557 }
1558
1559 if (Argv[0][1] == 'e') /* enable */
1560 {
1561 KdbpEnableBreakPoint(BreakPointNr, NULL);
1562 }
1563 else if (Argv [0][1] == 'd') /* disable */
1564 {
1565 KdbpDisableBreakPoint(BreakPointNr, NULL);
1566 }
1567 else /* clear */
1568 {
1569 ASSERT(Argv[0][1] == 'c');
1570 KdbpDeleteBreakPoint(BreakPointNr, NULL);
1571 }
1572
1573 return TRUE;
1574}
BOOLEAN KdbpDisableBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Disables a breakpoint.
Definition: kdb.c:868
BOOLEAN KdbpEnableBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Enables a breakpoint.
Definition: kdb.c:702
BOOLEAN KdbpDeleteBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Deletes a breakpoint.
Definition: kdb.c:599

◆ KdbpCmdEvalExpression()

static BOOLEAN KdbpCmdEvalExpression ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Evaluates an expression and displays the result.

Definition at line 469 of file kdb_cli.c.

472{
473 ULONG i;
474 SIZE_T len;
475 ULONGLONG Result = 0;
476 ULONG ul;
477 LONG l = 0;
478 BOOLEAN Ok;
479
480 if (Argc < 2)
481 {
482 KdbpPrint("?: Argument required\n");
483 return TRUE;
484 }
485
486 /* Put the arguments back together */
487 Argc--;
488 for (i = 1; i < Argc; i++)
489 {
490 len = strlen(Argv[i]);
491 Argv[i][len] = ' ';
492 }
493
494 /* Evaluate the expression */
495 Ok = KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result);
496 if (Ok)
497 {
498 if (Result > 0x00000000ffffffffLL)
499 {
500 if (Result & 0x8000000000000000LL)
501 KdbpPrint("0x%016I64x %20I64u %20I64d\n", Result, Result, Result);
502 else
503 KdbpPrint("0x%016I64x %20I64u\n", Result, Result);
504 }
505 else
506 {
507 ul = (ULONG)Result;
508
509 if (ul <= 0xff && ul >= 0x80)
510 l = (LONG)((CHAR)ul);
511 else if (ul <= 0xffff && ul >= 0x8000)
512 l = (LONG)((SHORT)ul);
513 else
514 l = (LONG)ul;
515
516 if (l < 0)
517 KdbpPrint("0x%08lx %10lu %10ld\n", ul, ul, l);
518 else
519 KdbpPrint("0x%08lx %10lu\n", ul, ul);
520 }
521 }
522
523 return TRUE;
524}
@ Ok
Definition: gdiplustypes.h:26
GLenum GLsizei len
Definition: glext.h:6722
short SHORT
Definition: pedump.c:59

◆ KdbpCmdFilter()

static BOOLEAN KdbpCmdFilter ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Displays the list of active debug channels, or enable/disable debug channels.

Definition at line 696 of file kdb_cli.c.

699{
701 ULONG set = DPFLTR_MASK, clear = DPFLTR_MASK;
702 PCHAR pend;
703 PCSTR opt, p;
704
705 static struct
706 {
707 PCSTR Name;
708 ULONG Level;
709 }
710 debug_classes[] =
711 {
712 { "error", 1 << DPFLTR_ERROR_LEVEL },
713 { "warning", 1 << DPFLTR_WARNING_LEVEL },
714 { "trace", 1 << DPFLTR_TRACE_LEVEL },
715 { "info", 1 << DPFLTR_INFO_LEVEL },
716 };
717
718 if (Argc <= 1)
719 {
720 /* Display the list of available debug filter components */
721 KdbpPrint("REMARKS:\n"
722 "- The 'WIN2000' system-wide debug filter component is used for DbgPrint()\n"
723 " messages without Component ID and Level.\n"
724 "- The 'DEFAULT' debug filter component is used for DbgPrint() messages with\n"
725 " an unknown Component ID.\n\n");
726 KdbpPrint("The list of debug filter components currently available on your system is:\n\n");
727 KdbpPrint(" Component Name Component ID\n"
728 " ================== ================\n");
729 for (i = 0; i < RTL_NUMBER_OF(ComponentTable); i++)
730 {
731 KdbpPrint("%20s 0x%08lx\n", ComponentTable[i].Name, ComponentTable[i].Id);
732 }
733 return TRUE;
734 }
735
736 for (i = 1; i < Argc; i++)
737 {
738 opt = Argv[i];
739 p = opt + strcspn(opt, "+-");
740 if (!p[0]) p = opt; /* Assume it's a debug channel name */
741
742 if (p > opt)
743 {
744 for (j = 0; j < RTL_NUMBER_OF(debug_classes); j++)
745 {
747 if (len != (p - opt))
748 continue;
749 if (_strnicmp(opt, debug_classes[j].Name, len) == 0) /* Found it */
750 {
751 if (*p == '+')
752 set |= debug_classes[j].Level;
753 else
754 clear |= debug_classes[j].Level;
755 break;
756 }
757 }
759 {
760 Level = strtoul(opt, &pend, 0);
761 if (pend != p)
762 {
763 KdbpPrint("filter: bad class name '%.*s'\n", p - opt, opt);
764 continue;
765 }
766 if (*p == '+')
767 set |= Level;
768 else
769 clear |= Level;
770 }
771 }
772 else
773 {
774 if (*p == '-')
775 clear = MAXULONG;
776 else
777 set = MAXULONG;
778 }
779 if (*p == '+' || *p == '-')
780 p++;
781
783 {
784 KdbpPrint("filter: '%s' is not a valid component name!\n", p);
785 return TRUE;
786 }
787
788 /* Get current mask value */
791 }
792
793 return TRUE;
794}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
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:1281
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
Definition: _set.h:50
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
NTSTATUS NTAPI NtSetDebugFilterState(_In_ ULONG ComponentId, _In_ ULONG Level, _In_ BOOLEAN State)
Definition: kdapi.c:2437
ULONG Id
Definition: kdb_cli.c:160
PCSTR Name
Definition: kdb_cli.c:159
static struct @1819 ComponentTable[]
static BOOLEAN KdbpGetComponentId(IN PCSTR ComponentName, OUT PULONG ComponentId)
Retrieves the component ID corresponding to a given component name.
Definition: kdb_cli.c:675
#define DPFLTR_WARNING_LEVEL
Definition: kdtypes.h:31
#define DPFLTR_INFO_LEVEL
Definition: kdtypes.h:33
#define DPFLTR_MASK
Definition: kdtypes.h:34
#define DPFLTR_TRACE_LEVEL
Definition: kdtypes.h:32
static const char *const debug_classes[]
Definition: debug.c:51
#define MAXULONG
Definition: typedefs.h:251
const char * PCSTR
Definition: typedefs.h:52
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56

◆ KdbpCmdGdtLdtIdt()

static BOOLEAN KdbpCmdGdtLdtIdt ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Displays GDT, LDT or IDT.

Definition at line 2096 of file kdb_cli.c.

2099{
2100 KDESCRIPTOR Reg;
2101 ULONG SegDesc[2];
2102 ULONG SegBase;
2103 ULONG SegLimit;
2104 PCHAR SegType;
2105 USHORT SegSel;
2106 UCHAR Type, Dpl;
2107 INT i;
2108 ULONG ul;
2109
2110 if (Argv[0][0] == 'i')
2111 {
2112 /* Read IDTR */
2113 __sidt(&Reg.Limit);
2114
2115 if (Reg.Limit < 7)
2116 {
2117 KdbpPrint("Interrupt descriptor table is empty.\n");
2118 return TRUE;
2119 }
2120
2121 KdbpPrint("IDT Base: 0x%08x Limit: 0x%04x\n", Reg.Base, Reg.Limit);
2122 KdbpPrint(" Idx Type Seg. Sel. Offset DPL\n");
2123
2124 for (i = 0; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
2125 {
2126 if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)((ULONG_PTR)Reg.Base + i), sizeof(SegDesc))))
2127 {
2128 KdbpPrint("Couldn't access memory at 0x%p!\n", (PVOID)((ULONG_PTR)Reg.Base + i));
2129 return TRUE;
2130 }
2131
2132 Dpl = ((SegDesc[1] >> 13) & 3);
2133 if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
2134 SegType = "TASKGATE";
2135 else if ((SegDesc[1] & 0x1fe0) == 0x0e00) /* 32 bit Interrupt gate */
2136 SegType = "INTGATE32";
2137 else if ((SegDesc[1] & 0x1fe0) == 0x0600) /* 16 bit Interrupt gate */
2138 SegType = "INTGATE16";
2139 else if ((SegDesc[1] & 0x1fe0) == 0x0f00) /* 32 bit Trap gate */
2140 SegType = "TRAPGATE32";
2141 else if ((SegDesc[1] & 0x1fe0) == 0x0700) /* 16 bit Trap gate */
2142 SegType = "TRAPGATE16";
2143 else
2144 SegType = "UNKNOWN";
2145
2146 if ((SegDesc[1] & (1 << 15)) == 0) /* not present */
2147 {
2148 KdbpPrint(" %03d %-10s [NP] [NP] %02d\n",
2149 i / 8, SegType, Dpl);
2150 }
2151 else if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
2152 {
2153 SegSel = SegDesc[0] >> 16;
2154 KdbpPrint(" %03d %-10s 0x%04x %02d\n",
2155 i / 8, SegType, SegSel, Dpl);
2156 }
2157 else
2158 {
2159 SegSel = SegDesc[0] >> 16;
2160 SegBase = (SegDesc[1] & 0xffff0000) | (SegDesc[0] & 0x0000ffff);
2161 KdbpPrint(" %03d %-10s 0x%04x 0x%08x %02d\n",
2162 i / 8, SegType, SegSel, SegBase, Dpl);
2163 }
2164 }
2165 }
2166 else
2167 {
2168 ul = 0;
2169
2170 if (Argv[0][0] == 'g')
2171 {
2172 /* Read GDTR */
2174 i = 8;
2175 }
2176 else
2177 {
2178 ASSERT(Argv[0][0] == 'l');
2179
2180 /* Read LDTR */
2182 Reg.Base = 0;
2183 i = 0;
2184 ul = 1 << 2;
2185 }
2186
2187 if (Reg.Limit < 7)
2188 {
2189 KdbpPrint("%s descriptor table is empty.\n",
2190 Argv[0][0] == 'g' ? "Global" : "Local");
2191 return TRUE;
2192 }
2193
2194 KdbpPrint("%cDT Base: 0x%08x Limit: 0x%04x\n",
2195 Argv[0][0] == 'g' ? 'G' : 'L', Reg.Base, Reg.Limit);
2196 KdbpPrint(" Idx Sel. Type Base Limit DPL Attribs\n");
2197
2198 for (; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
2199 {
2200 if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)((ULONG_PTR)Reg.Base + i), sizeof(SegDesc))))
2201 {
2202 KdbpPrint("Couldn't access memory at 0x%p!\n", (ULONG_PTR)Reg.Base + i);
2203 return TRUE;
2204 }
2205
2206 Dpl = ((SegDesc[1] >> 13) & 3);
2207 Type = ((SegDesc[1] >> 8) & 0xf);
2208
2209 SegBase = SegDesc[0] >> 16;
2210 SegBase |= (SegDesc[1] & 0xff) << 16;
2211 SegBase |= SegDesc[1] & 0xff000000;
2212 SegLimit = SegDesc[0] & 0x0000ffff;
2213 SegLimit |= (SegDesc[1] >> 16) & 0xf;
2214
2215 if ((SegDesc[1] & (1 << 23)) != 0)
2216 {
2217 SegLimit *= 4096;
2218 SegLimit += 4095;
2219 }
2220 else
2221 {
2222 SegLimit++;
2223 }
2224
2225 if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
2226 {
2227 switch (Type)
2228 {
2229 case 1: SegType = "TSS16(Avl)"; break;
2230 case 2: SegType = "LDT"; break;
2231 case 3: SegType = "TSS16(Busy)"; break;
2232 case 4: SegType = "CALLGATE16"; break;
2233 case 5: SegType = "TASKGATE"; break;
2234 case 6: SegType = "INTGATE16"; break;
2235 case 7: SegType = "TRAPGATE16"; break;
2236 case 9: SegType = "TSS32(Avl)"; break;
2237 case 11: SegType = "TSS32(Busy)"; break;
2238 case 12: SegType = "CALLGATE32"; break;
2239 case 14: SegType = "INTGATE32"; break;
2240 case 15: SegType = "TRAPGATE32"; break;
2241 default: SegType = "UNKNOWN"; break;
2242 }
2243
2244 if (!(Type >= 1 && Type <= 3) &&
2245 Type != 9 && Type != 11)
2246 {
2247 SegBase = 0;
2248 SegLimit = 0;
2249 }
2250 }
2251 else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
2252 {
2253 if ((SegDesc[1] & (1 << 22)) != 0)
2254 SegType = "DATA32";
2255 else
2256 SegType = "DATA16";
2257 }
2258 else /* Code segment */
2259 {
2260 if ((SegDesc[1] & (1 << 22)) != 0)
2261 SegType = "CODE32";
2262 else
2263 SegType = "CODE16";
2264 }
2265
2266 if ((SegDesc[1] & (1 << 15)) == 0) /* Not present */
2267 {
2268 KdbpPrint(" %03d 0x%04x %-11s [NP] [NP] %02d NP\n",
2269 i / 8, i | Dpl | ul, SegType, Dpl);
2270 }
2271 else
2272 {
2273 KdbpPrint(" %03d 0x%04x %-11s 0x%08x 0x%08x %02d ",
2274 i / 8, i | Dpl | ul, SegType, SegBase, SegLimit, Dpl);
2275
2276 if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
2277 {
2278 /* FIXME: Display system segment */
2279 }
2280 else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
2281 {
2282 if ((SegDesc[1] & (1 << 10)) != 0) /* Expand-down */
2283 KdbpPrint(" E");
2284
2285 KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/W" : " R");
2286
2287 if ((SegDesc[1] & (1 << 8)) != 0)
2288 KdbpPrint(" A");
2289 }
2290 else /* Code segment */
2291 {
2292 if ((SegDesc[1] & (1 << 10)) != 0) /* Conforming */
2293 KdbpPrint(" C");
2294
2295 KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/X" : " X");
2296
2297 if ((SegDesc[1] & (1 << 8)) != 0)
2298 KdbpPrint(" A");
2299 }
2300
2301 if ((SegDesc[1] & (1 << 20)) != 0)
2302 KdbpPrint(" AVL");
2303
2304 KdbpPrint("\n");
2305 }
2306 }
2307 }
2308
2309 return TRUE;
2310}
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2023
#define Ke386GetLocalDescriptorTable
Definition: kdb_cli.c:104
PVOID Base
Definition: ketypes.h:560

◆ KdbpCmdHelp()

static BOOLEAN KdbpCmdHelp ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Displays help screen.

Definition at line 2738 of file kdb_cli.c.

2741{
2742 ULONG i;
2743
2744 KdbpPrint("Kernel debugger commands:\n");
2745 for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
2746 {
2747 if (!KdbDebuggerCommands[i].Syntax) /* Command group */
2748 {
2749 if (i > 0)
2750 KdbpPrint("\n");
2751
2752 KdbpPrint("\x1b[7m* %s:\x1b[0m\n", KdbDebuggerCommands[i].Help);
2753 continue;
2754 }
2755
2756 KdbpPrint(" %-20s - %s\n",
2759 }
2760
2761 return TRUE;
2762}
static const struct @1820 KdbDebuggerCommands[]
PCHAR Help
Definition: kdb_cli.c:345
PCHAR Syntax
Definition: kdb_cli.c:344

◆ KdbpCmdMod()

static BOOLEAN KdbpCmdMod ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Lists loaded modules or the one containing the specified address.

Definition at line 2030 of file kdb_cli.c.

2033{
2034 ULONGLONG Result = 0;
2036 PLDR_DATA_TABLE_ENTRY LdrEntry;
2037 BOOLEAN DisplayOnlyOneModule = FALSE;
2038 INT i = 0;
2039
2040 if (Argc >= 2)
2041 {
2042 /* Put the arguments back together */
2043 Argc--;
2044 while (--Argc >= 1)
2045 Argv[Argc][strlen(Argv[Argc])] = ' ';
2046
2047 /* Evaluate the expression */
2048 if (!KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result))
2049 {
2050 return TRUE;
2051 }
2052
2053 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
2054 KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0],Result);
2055
2057
2058 if (!KdbpSymFindModule((PVOID)Address, -1, &LdrEntry))
2059 {
2060 KdbpPrint("No module containing address 0x%p found!\n", Address);
2061 return TRUE;
2062 }
2063
2064 DisplayOnlyOneModule = TRUE;
2065 }
2066 else
2067 {
2068 if (!KdbpSymFindModule(NULL, 0, &LdrEntry))
2069 {
2070 ULONG_PTR ntoskrnlBase = (ULONG_PTR)__ImageBase;
2071 KdbpPrint(" Base Size Name\n");
2072 KdbpPrint(" %p %08x %s\n", (PVOID)ntoskrnlBase, 0, "ntoskrnl.exe");
2073 return TRUE;
2074 }
2075
2076 i = 1;
2077 }
2078
2079 KdbpPrint(" Base Size Name\n");
2080 for (;;)
2081 {
2082 KdbpPrint(" %p %08x ", LdrEntry->DllBase, LdrEntry->SizeOfImage);
2084 KdbpPrint("\n");
2085
2086 if(DisplayOnlyOneModule || !KdbpSymFindModule(NULL, i++, &LdrEntry))
2087 break;
2088 }
2089
2090 return TRUE;
2091}
BOOLEAN KdbpSymFindModule(IN PVOID Address OPTIONAL, IN INT Index OPTIONAL, OUT PLDR_DATA_TABLE_ENTRY *pLdrEntry)
Find a module...
Definition: kdb_symbols.c:76
char __ImageBase
VOID KdbpPrintUnicodeString(_In_ PCUNICODE_STRING String)
Definition: kdb_cli.c:3104
Definition: btrfs_drv.h:1876
ULONG SizeOfImage
Definition: ldrtypes.h:143
PVOID DllBase
Definition: btrfs_drv.h:1880
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145

◆ KdbpCmdPcr()

static BOOLEAN KdbpCmdPcr ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Displays the KPCR.

Definition at line 2315 of file kdb_cli.c.

2318{
2319 PKIPCR Pcr = (PKIPCR)KeGetPcr();
2320
2321 KdbpPrint("Current PCR is at 0x%p.\n", Pcr);
2322#ifdef _M_IX86
2323 KdbpPrint(" Tib.ExceptionList: 0x%08x\n"
2324 " Tib.StackBase: 0x%08x\n"
2325 " Tib.StackLimit: 0x%08x\n"
2326 " Tib.SubSystemTib: 0x%08x\n"
2327 " Tib.FiberData/Version: 0x%08x\n"
2328 " Tib.ArbitraryUserPointer: 0x%08x\n"
2329 " Tib.Self: 0x%08x\n"
2330 " SelfPcr: 0x%08x\n"
2331 " PCRCB: 0x%08x\n"
2332 " Irql: 0x%02x\n"
2333 " IRR: 0x%08x\n"
2334 " IrrActive: 0x%08x\n"
2335 " IDR: 0x%08x\n"
2336 " KdVersionBlock: 0x%08x\n"
2337 " IDT: 0x%08x\n"
2338 " GDT: 0x%08x\n"
2339 " TSS: 0x%08x\n"
2340 " MajorVersion: 0x%04x\n"
2341 " MinorVersion: 0x%04x\n"
2342 " SetMember: 0x%08x\n"
2343 " StallScaleFactor: 0x%08x\n"
2344 " Number: 0x%02x\n"
2345 " L2CacheAssociativity: 0x%02x\n"
2346 " VdmAlert: 0x%08x\n"
2347 " L2CacheSize: 0x%08x\n"
2348 " InterruptMode: 0x%08x\n"
2351 Pcr->NtTib.Self
2352 , Pcr->SelfPcr
2353 , Pcr->Prcb, Pcr->Irql
2354 , Pcr->IRR, Pcr->IrrActive , Pcr->IDR
2355 , Pcr->KdVersionBlock
2356 , Pcr->IDT, Pcr->GDT, Pcr->TSS
2357 , Pcr->MajorVersion, Pcr->MinorVersion
2358 , Pcr->SetMember
2359 , Pcr->StallScaleFactor
2360 , Pcr->Number
2362 , Pcr->VdmAlert
2364 , Pcr->InterruptMode);
2365#else
2366 KdbpPrint(" GdtBase: 0x%p\n", Pcr->GdtBase);
2367 KdbpPrint(" TssBase: 0x%p\n", Pcr->TssBase);
2368 KdbpPrint(" UserRsp: 0x%p\n", (PVOID)Pcr->UserRsp);
2369 KdbpPrint(" Self: 0x%p\n", Pcr->Self);
2370 KdbpPrint(" CurrentPrcb: 0x%p\n", Pcr->CurrentPrcb);
2371 KdbpPrint(" LockArray: 0x%p\n", Pcr->LockArray);
2372 KdbpPrint(" Used_Self: 0x%p\n", Pcr->Used_Self);
2373 KdbpPrint(" IdtBase: 0x%p\n", Pcr->IdtBase);
2374 KdbpPrint(" Irql: %u\n", Pcr->Irql);
2375 KdbpPrint(" SecondLevelCacheAssociativity: 0x%u\n", Pcr->SecondLevelCacheAssociativity);
2376 KdbpPrint(" ObsoleteNumber: %u\n", Pcr->ObsoleteNumber);
2377 KdbpPrint(" MajorVersion: 0x%x\n", Pcr->MajorVersion);
2378 KdbpPrint(" MinorVersion: 0x%x\n", Pcr->MinorVersion);
2379 KdbpPrint(" StallScaleFactor: 0x%lx\n", Pcr->StallScaleFactor);
2380 KdbpPrint(" SecondLevelCacheSize: 0x%lx\n", Pcr->SecondLevelCacheSize);
2381 KdbpPrint(" KdVersionBlock: 0x%p\n", Pcr->KdVersionBlock);
2382#endif
2383
2384 return TRUE;
2385}
struct _KIPCR * PKIPCR
#define KeGetPcr()
Definition: ketypes.h:81
KPRCB Prcb
Definition: ketypes.h:965
USHORT MinorVersion
Definition: ketypes.h:953
ULONG SecondLevelCacheSize
Definition: ketypes.h:957
PKIDTENTRY IDT
Definition: ketypes.h:812
USHORT MajorVersion
Definition: ketypes.h:952
UCHAR SecondLevelCacheAssociativity
Definition: ketypes.h:948
ULONG IrrActive
Definition: ketypes.h:809
KIRQL Irql
Definition: ketypes.h:947
UCHAR Number
Definition: ketypes.h:820
KAFFINITY SetMember
Definition: ketypes.h:817
struct _KPRCB * CurrentPrcb
Definition: ketypes.h:940
ULONG IRR
Definition: ketypes.h:808
union _KGDTENTRY64 * GdtBase
Definition: ketypes.h:936
ULONG InterruptMode
Definition: ketypes.h:827
PKGDTENTRY GDT
Definition: ketypes.h:813
struct _KPCR * SelfPcr
Definition: ketypes.h:805
PKSPIN_LOCK_QUEUE LockArray
Definition: ketypes.h:941
struct _KTSS64 * TssBase
Definition: ketypes.h:937
struct _KTSS * TSS
Definition: ketypes.h:814
UCHAR ObsoleteNumber
Definition: ketypes.h:949
NT_TIB NtTib
Definition: ketypes.h:933
ULONG IDR
Definition: ketypes.h:810
union _KIDTENTRY64 * IdtBase
Definition: ketypes.h:945
struct _KPCR * Self
Definition: ketypes.h:939
ULONG StallScaleFactor
Definition: ketypes.h:954
ULONG VdmAlert
Definition: ketypes.h:823
ULONG64 UserRsp
Definition: ketypes.h:938
PVOID KdVersionBlock
Definition: ketypes.h:961
PVOID Used_Self
Definition: ketypes.h:942
PVOID ArbitraryUserPointer
Definition: compat.h:719
struct _NT_TIB * Self
Definition: compat.h:720
PVOID FiberData
Definition: compat.h:716
PVOID StackLimit
Definition: compat.h:713
PVOID StackBase
Definition: compat.h:712
PVOID SubSystemTib
Definition: compat.h:714
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: compat.h:711

◆ KdbpCmdProc()

static BOOLEAN KdbpCmdProc ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Lists processes or switches to another process context.

Definition at line 1912 of file kdb_cli.c.

1915{
1918 BOOLEAN ReferencedProcess = FALSE;
1919 PCHAR State, pend, str1, str2;
1920 ULONG_PTR ul;
1922
1923 if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
1924 {
1926 if (!Entry || Entry == &PsActiveProcessHead)
1927 {
1928 KdbpPrint("No processes in the system!\n");
1929 return TRUE;
1930 }
1931
1932 KdbpPrint(" PID State Filename\n");
1933 do
1934 {
1935 Process = CONTAINING_RECORD(Entry, EPROCESS, ActiveProcessLinks);
1936
1938 {
1939 str1 = "\x1b[1m*";
1940 str2 = "\x1b[0m";
1941 }
1942 else
1943 {
1944 str1 = " ";
1945 str2 = "";
1946 }
1947
1948 State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
1949 ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
1950
1951 KdbpPrint(" %s0x%08x %-10s %s%s\n",
1952 str1,
1953 Process->UniqueProcessId,
1954 State,
1955 Process->ImageFileName,
1956 str2);
1957
1958 Entry = Entry->Flink;
1959 }
1960 while(Entry != &PsActiveProcessHead);
1961 }
1962 else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
1963 {
1964 if (Argc < 3)
1965 {
1966 KdbpPrint("process attach: process id argument required!\n");
1967 return TRUE;
1968 }
1969
1970 ul = strtoulptr(Argv[2], &pend, 0);
1971 if (Argv[2] == pend)
1972 {
1973 KdbpPrint("process attach: '%s' is not a valid process id!\n", Argv[2]);
1974 return TRUE;
1975 }
1976
1977 if (!KdbpAttachToProcess((PVOID)ul))
1978 {
1979 return TRUE;
1980 }
1981
1982 KdbpPrint("Attached to process 0x%p, thread 0x%p.\n", (PVOID)ul,
1984 }
1985 else
1986 {
1988
1989 if (Argc >= 2)
1990 {
1991 ul = strtoulptr(Argv[1], &pend, 0);
1992 if (Argv[1] == pend)
1993 {
1994 KdbpPrint("proc: '%s' is not a valid process id!\n", Argv[1]);
1995 return TRUE;
1996 }
1997
1999 {
2000 KdbpPrint("proc: Invalid process id!\n");
2001 return TRUE;
2002 }
2003
2004 /* Remember our reference */
2005 ReferencedProcess = TRUE;
2006 }
2007
2008 State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
2009 ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
2010 KdbpPrint("%s"
2011 " PID: 0x%08x\n"
2012 " State: %s (0x%x)\n"
2013 " Image Filename: %s\n",
2014 (Argc < 2) ? "Current process:\n" : "",
2015 Process->UniqueProcessId,
2016 State, Process->Pcb.State,
2017 Process->ImageFileName);
2018
2019 /* Release our reference, if any */
2020 if (ReferencedProcess)
2022 }
2023
2024 return TRUE;
2025}
PEPROCESS KdbCurrentProcess
Definition: kdb.c:52
PETHREAD KdbCurrentThread
Definition: kdb.c:54
BOOLEAN KdbpAttachToProcess(PVOID ProcessId)
Switches to another process/thread context.
Definition: kdb.c:1117
@ ProcessOutOfMemory
Definition: ketypes.h:461
@ ProcessInMemory
Definition: ketypes.h:460
#define strtoulptr
Definition: handle.c:28
NTSTATUS NTAPI PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process)
Definition: process.c:919
LIST_ENTRY PsActiveProcessHead
Definition: process.c:22
base of all file and directory entries
Definition: entries.h:83
HANDLE UniqueThread
Definition: compat.h:826
CLIENT_ID Cid
Definition: pstypes.h:1129
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define ObDereferenceObject
Definition: obfuncs.h:203

◆ KdbpCmdReboot()

static BOOLEAN KdbpCmdReboot ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Definition at line 2500 of file kdb_cli.c.

2503{
2504 /* Reboot immediately (we do not return) */
2506 return FALSE;
2507}
VOID NTAPI HalReturnToFirmware(_In_ FIRMWARE_REENTRY Action)
Definition: reboot.c:21
@ HalRebootRoutine
Definition: haltypes.h:37

◆ KdbpCmdRegs()

static BOOLEAN KdbpCmdRegs ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Displays CPU registers.

Definition at line 921 of file kdb_cli.c.

924{
926 INT i;
927 static const PCHAR EflagsBits[32] = { " CF", NULL, " PF", " BIT3", " AF", " BIT5",
928 " ZF", " SF", " TF", " IF", " DF", " OF",
929 NULL, NULL, " NT", " BIT15", " RF", " VF",
930 " AC", " VIF", " VIP", " ID", " BIT22",
931 " BIT23", " BIT24", " BIT25", " BIT26",
932 " BIT27", " BIT28", " BIT29", " BIT30",
933 " BIT31" };
934
935 if (Argv[0][0] == 'r') /* regs */
936 {
937#ifdef _M_IX86
938 KdbpPrint("CS:EIP 0x%04x:0x%08x\n"
939 "SS:ESP 0x%04x:0x%08x\n"
940 " EAX 0x%08x EBX 0x%08x\n"
941 " ECX 0x%08x EDX 0x%08x\n"
942 " ESI 0x%08x EDI 0x%08x\n"
943 " EBP 0x%08x\n",
944 Context->SegCs & 0xFFFF, Context->Eip,
945 Context->SegSs, Context->Esp,
946 Context->Eax, Context->Ebx,
947 Context->Ecx, Context->Edx,
948 Context->Esi, Context->Edi,
949 Context->Ebp);
950#else
951 KdbpPrint("CS:RIP 0x%04x:0x%p\n"
952 "SS:RSP 0x%04x:0x%p\n"
953 " RAX 0x%p RBX 0x%p\n"
954 " RCX 0x%p RDX 0x%p\n"
955 " RSI 0x%p RDI 0x%p\n"
956 " RBP 0x%p\n",
957 Context->SegCs & 0xFFFF, Context->Rip,
958 Context->SegSs, Context->Rsp,
959 Context->Rax, Context->Rbx,
960 Context->Rcx, Context->Rdx,
961 Context->Rsi, Context->Rdi,
962 Context->Rbp);
963#endif
964 /* Display the EFlags */
965 KdbpPrint("EFLAGS 0x%08x ", Context->EFlags);
966 for (i = 0; i < 32; i++)
967 {
968 if (i == 1)
969 {
970 if ((Context->EFlags & (1 << 1)) == 0)
971 KdbpPrint(" !BIT1");
972 }
973 else if (i == 12)
974 {
975 KdbpPrint(" IOPL%d", (Context->EFlags >> 12) & 3);
976 }
977 else if (i == 13)
978 {
979 }
980 else if ((Context->EFlags & (1 << i)) != 0)
981 {
982 KdbpPrint(EflagsBits[i]);
983 }
984 }
985 KdbpPrint("\n");
986 }
987 else if (Argv[0][0] == 's') /* sregs */
988 {
989 KdbpPrint("CS 0x%04x Index 0x%04x %cDT RPL%d\n",
990 Context->SegCs & 0xffff, (Context->SegCs & 0xffff) >> 3,
991 (Context->SegCs & (1 << 2)) ? 'L' : 'G', Context->SegCs & 3);
992 KdbpPrint("DS 0x%04x Index 0x%04x %cDT RPL%d\n",
993 Context->SegDs, Context->SegDs >> 3, (Context->SegDs & (1 << 2)) ? 'L' : 'G', Context->SegDs & 3);
994 KdbpPrint("ES 0x%04x Index 0x%04x %cDT RPL%d\n",
995 Context->SegEs, Context->SegEs >> 3, (Context->SegEs & (1 << 2)) ? 'L' : 'G', Context->SegEs & 3);
996 KdbpPrint("FS 0x%04x Index 0x%04x %cDT RPL%d\n",
997 Context->SegFs, Context->SegFs >> 3, (Context->SegFs & (1 << 2)) ? 'L' : 'G', Context->SegFs & 3);
998 KdbpPrint("GS 0x%04x Index 0x%04x %cDT RPL%d\n",
999 Context->SegGs, Context->SegGs >> 3, (Context->SegGs & (1 << 2)) ? 'L' : 'G', Context->SegGs & 3);
1000 KdbpPrint("SS 0x%04x Index 0x%04x %cDT RPL%d\n",
1001 Context->SegSs, Context->SegSs >> 3, (Context->SegSs & (1 << 2)) ? 'L' : 'G', Context->SegSs & 3);
1002 }
1003 else /* dregs */
1004 {
1005 ASSERT(Argv[0][0] == 'd');
1006 KdbpPrint("DR0 0x%08x\n"
1007 "DR1 0x%08x\n"
1008 "DR2 0x%08x\n"
1009 "DR3 0x%08x\n"
1010 "DR6 0x%08x\n"
1011 "DR7 0x%08x\n",
1012 Context->Dr0, Context->Dr1, Context->Dr2, Context->Dr3,
1013 Context->Dr6, Context->Dr7);
1014 }
1015
1016 return TRUE;
1017}

◆ KdbpCmdSet()

static BOOLEAN KdbpCmdSet ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Sets or displays a config variables value.

Definition at line 2559 of file kdb_cli.c.

2562{
2563 LONG l;
2564 BOOLEAN First;
2565 PCHAR pend = 0;
2566 KDB_ENTER_CONDITION ConditionFirst = KdbDoNotEnter;
2567 KDB_ENTER_CONDITION ConditionLast = KdbDoNotEnter;
2568
2569 static const PCHAR ExceptionNames[21] =
2570 {
2571 "ZERODEVIDE", "DEBUGTRAP", "NMI", "INT3", "OVERFLOW", "BOUND", "INVALIDOP",
2572 "NOMATHCOP", "DOUBLEFAULT", "RESERVED(9)", "INVALIDTSS", "SEGMENTNOTPRESENT",
2573 "STACKFAULT", "GPF", "PAGEFAULT", "RESERVED(15)", "MATHFAULT", "ALIGNMENTCHECK",
2574 "MACHINECHECK", "SIMDFAULT", "OTHERS"
2575 };
2576
2577 if (Argc == 1)
2578 {
2579 KdbpPrint("Available settings:\n");
2580 KdbpPrint(" syntax [intel|at&t]\n");
2581 KdbpPrint(" condition [exception|*] [first|last] [never|always|kmode|umode]\n");
2582 KdbpPrint(" break_on_module_load [true|false]\n");
2583 }
2584 else if (strcmp(Argv[1], "syntax") == 0)
2585 {
2586 if (Argc == 2)
2587 {
2588 KdbpPrint("syntax = %s\n", KdbUseIntelSyntax ? "intel" : "at&t");
2589 }
2590 else if (Argc >= 3)
2591 {
2592 if (_stricmp(Argv[2], "intel") == 0)
2594 else if (_stricmp(Argv[2], "at&t") == 0)
2596 else
2597 KdbpPrint("Unknown syntax '%s'.\n", Argv[2]);
2598 }
2599 }
2600 else if (strcmp(Argv[1], "condition") == 0)
2601 {
2602 if (Argc == 2)
2603 {
2604 KdbpPrint("Conditions: (First) (Last)\n");
2605 for (l = 0; l < RTL_NUMBER_OF(ExceptionNames) - 1; l++)
2606 {
2607 if (!ExceptionNames[l])
2608 continue;
2609
2610 if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
2611 ASSERT(FALSE);
2612
2613 if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
2614 ASSERT(FALSE);
2615
2616 KdbpPrint(" #%02d %-20s %-8s %-8s\n", l, ExceptionNames[l],
2617 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2618 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2619 }
2620
2621 ASSERT(l == (RTL_NUMBER_OF(ExceptionNames) - 1));
2622 KdbpPrint(" %-20s %-8s %-8s\n", ExceptionNames[l],
2623 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2624 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2625 }
2626 else
2627 {
2628 if (Argc >= 5 && strcmp(Argv[2], "*") == 0) /* Allow * only when setting condition */
2629 {
2630 l = -1;
2631 }
2632 else
2633 {
2634 l = strtoul(Argv[2], &pend, 0);
2635
2636 if (Argv[2] == pend)
2637 {
2638 for (l = 0; l < RTL_NUMBER_OF(ExceptionNames); l++)
2639 {
2640 if (!ExceptionNames[l])
2641 continue;
2642
2643 if (_stricmp(ExceptionNames[l], Argv[2]) == 0)
2644 break;
2645 }
2646 }
2647
2648 if (l >= RTL_NUMBER_OF(ExceptionNames))
2649 {
2650 KdbpPrint("Unknown exception '%s'.\n", Argv[2]);
2651 return TRUE;
2652 }
2653 }
2654
2655 if (Argc > 4)
2656 {
2657 if (_stricmp(Argv[3], "first") == 0)
2658 First = TRUE;
2659 else if (_stricmp(Argv[3], "last") == 0)
2660 First = FALSE;
2661 else
2662 {
2663 KdbpPrint("set condition: second argument must be 'first' or 'last'\n");
2664 return TRUE;
2665 }
2666
2667 if (_stricmp(Argv[4], "never") == 0)
2668 ConditionFirst = KdbDoNotEnter;
2669 else if (_stricmp(Argv[4], "always") == 0)
2670 ConditionFirst = KdbEnterAlways;
2671 else if (_stricmp(Argv[4], "umode") == 0)
2672 ConditionFirst = KdbEnterFromUmode;
2673 else if (_stricmp(Argv[4], "kmode") == 0)
2674 ConditionFirst = KdbEnterFromKmode;
2675 else
2676 {
2677 KdbpPrint("set condition: third argument must be 'never', 'always', 'umode' or 'kmode'\n");
2678 return TRUE;
2679 }
2680
2681 if (!KdbpSetEnterCondition(l, First, ConditionFirst))
2682 {
2683 if (l >= 0)
2684 KdbpPrint("Couldn't change condition for exception #%02d\n", l);
2685 else
2686 KdbpPrint("Couldn't change condition for all exceptions\n", l);
2687 }
2688 }
2689 else /* Argc >= 3 */
2690 {
2691 if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
2692 ASSERT(FALSE);
2693
2694 if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
2695 ASSERT(FALSE);
2696
2697 if (l < (RTL_NUMBER_OF(ExceptionNames) - 1))
2698 {
2699 KdbpPrint("Condition for exception #%02d (%s): FirstChance %s LastChance %s\n",
2700 l, ExceptionNames[l],
2701 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2702 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2703 }
2704 else
2705 {
2706 KdbpPrint("Condition for all other exceptions: FirstChance %s LastChance %s\n",
2707 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2708 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2709 }
2710 }
2711 }
2712 }
2713 else if (strcmp(Argv[1], "break_on_module_load") == 0)
2714 {
2715 if (Argc == 2)
2716 KdbpPrint("break_on_module_load = %s\n", KdbBreakOnModuleLoad ? "enabled" : "disabled");
2717 else if (Argc >= 3)
2718 {
2719 if (_stricmp(Argv[2], "enable") == 0 || _stricmp(Argv[2], "enabled") == 0 || _stricmp(Argv[2], "true") == 0)
2721 else if (_stricmp(Argv[2], "disable") == 0 || _stricmp(Argv[2], "disabled") == 0 || _stricmp(Argv[2], "false") == 0)
2723 else
2724 KdbpPrint("Unknown setting '%s'.\n", Argv[2]);
2725 }
2726 }
2727 else
2728 {
2729 KdbpPrint("Unknown setting '%s'.\n", Argv[1]);
2730 }
2731
2732 return TRUE;
2733}
WCHAR First[]
Definition: FormatMessage.c:11
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:995
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.
Definition: kdb.c:973
enum _KDB_ENTER_CONDITION KDB_ENTER_CONDITION
@ KdbEnterFromUmode
Definition: kdb.h:51
#define KDB_ENTER_CONDITION_TO_STRING(cond)
Definition: kdb_cli.c:41
static BOOLEAN KdbBreakOnModuleLoad
Definition: kdb_cli.c:130

◆ KdbpCmdStep()

static BOOLEAN KdbpCmdStep ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Continues execution of the system/leaves KDB.

Definition at line 1411 of file kdb_cli.c.

1414{
1415 ULONG Count = 1;
1416
1417 if (Argc > 1)
1418 {
1419 Count = strtoul(Argv[1], NULL, 0);
1420 if (Count == 0)
1421 {
1422 KdbpPrint("%s: Integer argument required\n", Argv[0]);
1423 return TRUE;
1424 }
1425 }
1426
1427 if (Argv[0][0] == 'n')
1429 else
1431
1432 /* Set the number of single steps and return to the interrupted code. */
1434
1435 return FALSE;
1436}
BOOLEAN KdbSingleStepOver
Definition: kdb.c:50
ULONG KdbNumSingleSteps
Definition: kdb.c:49

◆ KdbpCmdThread()

static BOOLEAN KdbpCmdThread ( ULONG  Argc,
PCHAR  Argv[] 
)
static

Lists threads or switches to another thread context.

Definition at line 1703 of file kdb_cli.c.

1706{
1710 BOOLEAN ReferencedThread = FALSE, ReferencedProcess = FALSE;
1712 PULONG_PTR Frame;
1713 ULONG_PTR Pc;
1714 ULONG_PTR ul = 0;
1715 PCHAR State, pend, str1, str2;
1716 static const PCHAR ThreadStateToString[DeferredReady+1] =
1717 {
1718 "Initialized", "Ready", "Running",
1719 "Standby", "Terminated", "Waiting",
1720 "Transition", "DeferredReady"
1721 };
1722
1724
1725 if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
1726 {
1728
1729 if (Argc >= 3)
1730 {
1731 ul = strtoulptr(Argv[2], &pend, 0);
1732 if (Argv[2] == pend)
1733 {
1734 KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]);
1735 return TRUE;
1736 }
1737
1739 {
1740 KdbpPrint("thread: Invalid process id!\n");
1741 return TRUE;
1742 }
1743
1744 /* Remember our reference */
1745 ReferencedProcess = TRUE;
1746 }
1747
1748 Entry = Process->ThreadListHead.Flink;
1749 if (Entry == &Process->ThreadListHead)
1750 {
1751 if (Argc >= 3)
1752 KdbpPrint("No threads in process 0x%px!\n", (PVOID)ul);
1753 else
1754 KdbpPrint("No threads in current process!\n");
1755
1756 if (ReferencedProcess)
1758
1759 return TRUE;
1760 }
1761
1762 KdbpPrint(" TID State Prior. Affinity EBP EIP\n");
1763 do
1764 {
1765 Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
1766
1767 if (Thread == KdbCurrentThread)
1768 {
1769 str1 = "\x1b[1m*";
1770 str2 = "\x1b[0m";
1771 }
1772 else
1773 {
1774 str1 = " ";
1775 str2 = "";
1776 }
1777
1778 if (!Thread->Tcb.InitialStack)
1779 {
1780 /* Thread has no kernel stack (probably terminated) */
1781 Stack = Frame = NULL;
1782 Pc = 0;
1783 }
1784 else if (Thread->Tcb.TrapFrame)
1785 {
1789 }
1790 else
1791 {
1793 Frame = (PULONG_PTR)Stack[4];
1794 Pc = 0;
1795
1796 if (Frame) /* FIXME: Should we attach to the process to read Ebp[1]? */
1797 KdbpSafeReadMemory(&Pc, Frame + 1, sizeof(Pc));
1798 }
1799
1800 if (Thread->Tcb.State < (DeferredReady + 1))
1801 State = ThreadStateToString[Thread->Tcb.State];
1802 else
1803 State = "Unknown";
1804
1805 KdbpPrint(" %s0x%08x %-11s %3d 0x%08x 0x%08x 0x%08x%s\n",
1806 str1,
1808 State,
1811 Frame,
1812 Pc,
1813 str2);
1814
1815 Entry = Entry->Flink;
1816 }
1817 while (Entry != &Process->ThreadListHead);
1818
1819 /* Release our reference, if any */
1820 if (ReferencedProcess)
1822 }
1823 else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
1824 {
1825 if (Argc < 3)
1826 {
1827 KdbpPrint("thread attach: thread id argument required!\n");
1828 return TRUE;
1829 }
1830
1831 ul = strtoulptr(Argv[2], &pend, 0);
1832 if (Argv[2] == pend)
1833 {
1834 KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]);
1835 return TRUE;
1836 }
1837
1838 if (!KdbpAttachToThread((PVOID)ul))
1839 {
1840 return TRUE;
1841 }
1842
1843 KdbpPrint("Attached to thread 0x%08x.\n", ul);
1844 }
1845 else
1846 {
1848
1849 if (Argc >= 2)
1850 {
1851 ul = strtoulptr(Argv[1], &pend, 0);
1852 if (Argv[1] == pend)
1853 {
1854 KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]);
1855 return TRUE;
1856 }
1857
1859 {
1860 KdbpPrint("thread: Invalid thread id!\n");
1861 return TRUE;
1862 }
1863
1864 /* Remember our reference */
1865 ReferencedThread = TRUE;
1866 }
1867
1868 if (Thread->Tcb.State < (DeferredReady + 1))
1869 State = ThreadStateToString[Thread->Tcb.State];
1870 else
1871 State = "Unknown";
1872
1873 KdbpPrint("%s"
1874 " TID: 0x%08x\n"
1875 " State: %s (0x%x)\n"
1876 " Priority: %d\n"
1877 " Affinity: 0x%08x\n"
1878 " Initial Stack: 0x%08x\n"
1879 " Stack Limit: 0x%08x\n"
1880 " Stack Base: 0x%08x\n"
1881 " Kernel Stack: 0x%08x\n"
1882 " Trap Frame: 0x%08x\n"
1883#ifndef _M_AMD64
1884 " NPX State: %s (0x%x)\n"
1885#endif
1886 , (Argc < 2) ? "Current Thread:\n" : ""
1888 , State, Thread->Tcb.State
1896#ifndef _M_AMD64
1898#endif
1899 );
1900
1901 /* Release our reference if we had one */
1902 if (ReferencedThread)
1904 }
1905
1906 return TRUE;
1907}
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
BOOLEAN KdbpAttachToThread(PVOID ThreadId)
Switches to another thread context.
Definition: kdb.c:1036
#define NPX_STATE_TO_STRING(state)
Definition: kdb_cli.c:51
@ DeferredReady
Definition: ketypes.h:395
FORCEINLINE ULONG_PTR KeGetTrapFrameFrameRegister(PKTRAP_FRAME TrapFrame)
Definition: ke.h:200
FORCEINLINE ULONG_PTR KeGetTrapFrameStackRegister(PKTRAP_FRAME TrapFrame)
Definition: ke.h:193
#define KeGetTrapFramePc(TrapFrame)
Definition: ke.h:37
NTSTATUS NTAPI PsLookupThreadByThreadId(IN HANDLE ThreadId, OUT PETHREAD *Thread)
Definition: thread.c:643
KTHREAD Tcb
Definition: pstypes.h:1104
PKTRAP_FRAME TrapFrame
Definition: ketypes.h:1774
PVOID InitialStack
Definition: ketypes.h:1664
GROUP_AFFINITY Affinity
Definition: ketypes.h:1938
SCHAR Priority
Definition: ketypes.h:1782
ULONG64 NpxState
Definition: ketypes.h:2068
PVOID KernelStack
Definition: ketypes.h:1675
PVOID StackBase
Definition: ketypes.h:1666
volatile VOID * StackLimit
Definition: ketypes.h:1665
volatile UCHAR State
Definition: ketypes.h:1789
uint32_t * PULONG_PTR
Definition: typedefs.h:65
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639

◆ KdbpDoCommand()

static BOOLEAN KdbpDoCommand ( IN PCHAR  Command)
static

Parses command line and executes command if found.

Parameters
CommandCommand line to parse and execute if possible.
Return values
TRUEDon't continue execution.
FALSEContinue execution (leave KDB)

Definition at line 3205 of file kdb_cli.c.

3207{
3208 BOOLEAN Continue = TRUE;
3209 SIZE_T i;
3210 PCHAR p;
3211 ULONG Argc;
3212 // FIXME: for what do we need a 1024 characters command line and 256 tokens?
3213 static PCHAR Argv[256];
3214 static CHAR OrigCommand[1024];
3215
3216 RtlStringCbCopyA(OrigCommand, sizeof(OrigCommand), Command);
3217
3218 Argc = 0;
3219 p = Command;
3220
3221 for (;;)
3222 {
3223 while (*p == '\t' || *p == ' ')
3224 p++;
3225
3226 if (*p == '\0')
3227 break;
3228
3229 i = strcspn(p, "\t ");
3230 Argv[Argc++] = p;
3231 p += i;
3232 if (*p == '\0')
3233 break;
3234
3235 *p = '\0';
3236 p++;
3237 }
3238
3239 if (Argc < 1)
3240 return TRUE;
3241
3242 /* Reset the pager state: number of printed rows/cols and aborted output flag */
3245
3246 for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
3247 {
3249 continue;
3250
3251 if (strcmp(KdbDebuggerCommands[i].Name, Argv[0]) == 0)
3252 {
3253 Continue = KdbDebuggerCommands[i].Fn(Argc, Argv);
3254 goto Done;
3255 }
3256 }
3257
3258 /* Now invoke the registered callbacks */
3259 if (KdbpInvokeCliCallbacks(Command, Argc, Argv))
3260 goto Done;
3261
3262 KdbPrintf("Command '%s' is unknown.\n", OrigCommand);
3263
3264Done:
3266 return Continue;
3267}
static ULONG KdbNumberOfRowsPrinted
Definition: kdb_cli.c:132
static BOOLEAN KdbpInvokeCliCallbacks(IN PCHAR Command, IN ULONG Argc, IN PCHAR Argv[])
Invokes registered CLI callbacks until one of them handled the Command.
Definition: kdb_cli.c:3171
static ULONG KdbNumberOfColsPrinted
Definition: kdb_cli.c:133

Referenced by KdbpCliInterpretInitFile(), and KdbpCliMainLoop().

◆ KdbpEvaluateExpression()

static BOOLEAN KdbpEvaluateExpression ( IN PCHAR  Expression,
IN LONG  ErrOffset,
OUT PULONGLONG  Result 
)
static

Evaluates an expression...

Much like KdbpRpnEvaluateExpression, but prints the error message (if any) at the given offset.

Parameters
ExpressionExpression to evaluate.
ErrOffsetOffset (in characters) to print the error message at.
ResultReceives the result on success.
Return values
TRUESuccess.
FALSEFailure.

Definition at line 423 of file kdb_cli.c.

427{
428 static CHAR ErrMsgBuffer[130] = "^ ";
429 LONG ExpressionErrOffset = -1;
430 PCHAR ErrMsg = ErrMsgBuffer;
431 BOOLEAN Ok;
432
434 &ExpressionErrOffset, ErrMsgBuffer + 2);
435 if (!Ok)
436 {
437 if (ExpressionErrOffset >= 0)
438 ExpressionErrOffset += ErrOffset;
439 else
440 ErrMsg += 2;
441
442 KdbpPrint("%*s%s\n", ExpressionErrOffset, "", ErrMsg);
443 }
444
445 return Ok;
446}
PCWSTR Expression
BOOLEAN KdbpRpnEvaluateExpression(IN PCHAR Expression, IN PKDB_KTRAP_FRAME TrapFrame, OUT PULONGLONG Result, OUT PLONG ErrOffset OPTIONAL, OUT PCHAR ErrMsg OPTIONAL)
Evaluates the given expression.
Definition: kdb_expr.c:1106
static int ErrMsg(int Error)
Definition: shlextdbg.cpp:71

Referenced by KdbpCmdBackTrace(), KdbpCmdBreakPoint(), KdbpCmdDisassembleX(), KdbpCmdEvalExpression(), and KdbpCmdMod().

◆ KdbpGetComponentId()

static BOOLEAN KdbpGetComponentId ( IN PCSTR  ComponentName,
OUT PULONG  ComponentId 
)
static

Retrieves the component ID corresponding to a given component name.

Parameters
ComponentNameThe name of the component.
ComponentIdReceives the component id on success.
Return values
TRUESuccess.
FALSEFailure.

Definition at line 675 of file kdb_cli.c.

678{
679 ULONG i;
680
681 for (i = 0; i < RTL_NUMBER_OF(ComponentTable); i++)
682 {
683 if (_stricmp(ComponentName, ComponentTable[i].Name) == 0)
684 {
686 return TRUE;
687 }
688 }
689
690 return FALSE;
691}

Referenced by KdbpCmdFilter().

◆ KdbpGetHexNumber()

BOOLEAN NTAPI KdbpGetHexNumber ( IN PCHAR  pszNum,
OUT ULONG_PTR pulValue 
)

Definition at line 450 of file kdb_cli.c.

453{
454 char *endptr;
455
456 /* Skip optional '0x' prefix */
457 if ((pszNum[0] == '0') && ((pszNum[1] == 'x') || (pszNum[1] == 'X')))
458 pszNum += 2;
459
460 /* Make a number from the string (hex) */
461 *pulValue = strtoul(pszNum, &endptr, 16);
462
463 return (*endptr == '\0');
464}

◆ KdbpInvokeCliCallbacks()

static BOOLEAN KdbpInvokeCliCallbacks ( IN PCHAR  Command,
IN ULONG  Argc,
IN PCHAR  Argv[] 
)
static

Invokes registered CLI callbacks until one of them handled the Command.

Parameters
Command- Command line to parse and execute if possible.
Argc- Number of arguments in Argv
Argv- Array of strings, each of them containing one argument.
Returns
TRUE, if the command was handled, FALSE if it was not handled.

Definition at line 3171 of file kdb_cli.c.

3175{
3176 ULONG i;
3177
3178 /* Loop all entries */
3179 for (i = 0; i < _countof(KdbCliCallbacks); i++)
3180 {
3181 /* Check if this entry is registered */
3182 if (KdbCliCallbacks[i])
3183 {
3184 /* Invoke the callback and check if it handled the command */
3185 if (KdbCliCallbacks[i](Command, Argc, Argv))
3186 {
3187 return TRUE;
3188 }
3189 }
3190 }
3191
3192 /* None of the callbacks handled the command */
3193 return FALSE;
3194}
static PKDBG_CLI_ROUTINE KdbCliCallbacks[10]
Definition: kdb_cli.c:128
#define _countof(array)
Definition: sndvol32.h:70

Referenced by KdbpDoCommand().

◆ KdbpPager()

VOID KdbpPager ( _In_ PCHAR  Buffer,
_In_ ULONG  BufLength 
)

Prints the given string with, page by page.

Parameters
BufferCharacters buffer to print.
BufferLenBuffer size.
Note
Doesn't correctly handle \t and terminal escape sequences when calculating the number of lines required to print a single line from the Buffer in the terminal. Maximum length of buffer is limited only by memory size. Uses KdbPrintf internally.

Note: BufLength should be greater than (KdTermSize.cx * KdTermSize.cy).

Definition at line 3063 of file kdb_cli.c.

3066{
3067 /* Call the internal function */
3068 KdbpPagerInternal(Buffer, BufLength, TRUE);
3069}
static VOID KdbpPagerInternal(_In_ PCHAR Buffer, _In_ ULONG BufLength, _In_ BOOLEAN DoPage)
Prints the given string with, page by page.
Definition: kdb_cli.c:2887

Referenced by KdbpCmdDmesg().

◆ KdbpPagerInternal()

static VOID KdbpPagerInternal ( _In_ PCHAR  Buffer,
_In_ ULONG  BufLength,
_In_ BOOLEAN  DoPage 
)
static

Prints the given string with, page by page.

Parameters
BufferCharacters buffer to print.
BufferLenBuffer size.
Note
Doesn't correctly handle \t and terminal escape sequences when calculating the number of lines required to print a single line from the Buffer in the terminal. Maximum length of buffer is limited only by memory size. Uses KdbPrintf internally.

Note: BufLength should be greater than (KdTermSize.cx * KdTermSize.cy).

Definition at line 2887 of file kdb_cli.c.

2891{
2892 static BOOLEAN TerminalInitialized = FALSE;
2893 CHAR c;
2895 PCHAR p;
2896 SIZE_T i;
2897 LONG RowsPrintedByTerminal;
2898
2899 if (BufLength == 0)
2900 return;
2901
2902 /* Check if the user has aborted output of the current command */
2903 if (KdbOutputAborted)
2904 return;
2905
2906 /* Initialize the terminal */
2907 if (!TerminalInitialized)
2908 {
2909 TerminalInitialized = TRUE;
2911 }
2912
2913 /* Refresh terminal size each time when number of printed rows is 0 */
2914 if (KdbNumberOfRowsPrinted == 0)
2915 {
2917 }
2918
2919 /* Loop through the strings */
2920 p = Buffer;
2921 while (p[0] != '\0')
2922 {
2923 if (DoPage)
2924 {
2925 if (p > Buffer + BufLength)
2926 {
2927 KdbPrintf("Dmesg: error, p > Buffer+BufLength,d=%d", p - (Buffer + BufLength));
2928 return;
2929 }
2930 }
2931 i = strcspn(p, "\n");
2932
2933 if (DoPage)
2934 {
2935 /* Are we out of buffer? */
2936 if (p + i > Buffer + BufLength)
2937 break; // Leaving pager function
2938 }
2939
2940 /* Calculate the number of lines which will be printed in
2941 * the terminal when outputting the current line. */
2942 if (i > 0)
2943 RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) / KdTermSize.cx;
2944 else
2945 RowsPrintedByTerminal = 0;
2946
2947 if (p[i] == '\n')
2948 RowsPrintedByTerminal++;
2949
2950 //KdbPrintf("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);
2951
2952 /* Display a prompt if we printed one screen full of text */
2953 if (KdTermSize.cy > 0 &&
2954 (LONG)(KdbNumberOfRowsPrinted + RowsPrintedByTerminal) >= KdTermSize.cy)
2955 {
2956 PCSTR Prompt;
2957
2958 /* Disable the repetition of previous command with long many-page output */
2960
2961 if (KdbNumberOfColsPrinted > 0)
2962 KdbPuts("\n");
2963
2964 if (DoPage)
2965 Prompt = "--- Press q to abort, e/End,h/Home,u/PgUp, other key/PgDn ---";
2966 else
2967 Prompt = "--- Press q to abort, any other key to continue ---";
2968
2969 KdbPuts(Prompt);
2971 if (DoPage) // Show pressed key
2972 KdbPrintf(" '%c'/scan=%04x\n", c, ScanCode);
2973 else
2974 KdbPuts("\n");
2975
2976 RowsPrintedByTerminal++;
2977
2978 if (c == 'q')
2979 {
2981 return;
2982 }
2983
2984 if (DoPage)
2985 {
2986 if (ScanCode == KEYSC_END || c == 'e')
2987 {
2988 PCHAR pBufEnd = Buffer + BufLength;
2989 p = CountOnePageUp(Buffer, BufLength, pBufEnd, &KdTermSize);
2990 i = strcspn(p, "\n");
2991 }
2992 else if (ScanCode == KEYSC_PAGEUP ||
2993 ScanCode == KEYSC_ARROWUP || c == 'u')
2994 {
2995 p = CountOnePageUp(Buffer, BufLength, p, &KdTermSize);
2996 i = strcspn(p, "\n");
2997 }
2998 else if (ScanCode == KEYSC_HOME || c == 'h')
2999 {
3000 p = Buffer;
3001 i = strcspn(p, "\n");
3002 }
3003 }
3004
3007 }
3008
3009 /* Insert a NUL after the line and print only the current line */
3010 if (p[i] == '\n' && p[i + 1] != '\0')
3011 {
3012 c = p[i + 1];
3013 p[i + 1] = '\0';
3014 }
3015 else
3016 {
3017 c = '\0';
3018 }
3019
3020 /* Remove escape sequences from the line if there is no terminal connected */
3021 // FIXME: Dangerous operation since we modify the source string!!
3022 if (!KdTermConnected)
3024
3025 /* Print the current line */
3026 KdbPuts(p);
3027
3028 /* Restore not null char with saved */
3029 if (c != '\0')
3030 p[i + 1] = c;
3031
3032 /* Set p to the start of the next line and
3033 * remember the number of printed rows/cols */
3034 p += i;
3035 if (p[0] == '\n')
3036 {
3037 p++;
3039 }
3040 else
3041 {
3042 ASSERT(p[0] == '\0');
3044 }
3045
3046 KdbNumberOfRowsPrinted += RowsPrintedByTerminal;
3047 }
3048}
UINT ScanCode
Definition: VirtualKey.c:24
static VOID KdpFilterEscapes(_Inout_ PSTR String)
Definition: kdb_cli.c:2851
static PCHAR CountOnePageUp(_In_ PCCH Buffer, _In_ ULONG BufLength, _In_ PCCH pCurPos, _In_ const SIZE *TermSize)
Calculate pointer position for N lines above the current position.
Definition: kdb_cli.c:2807
BOOLEAN KdTermConnected
Definition: kdterminal.c:34
BOOLEAN KdpUpdateTerminalSize(_Out_ PSIZE TermSize)
Definition: kdterminal.c:108
SIZE KdTermSize
Definition: kdterminal.c:33
BOOLEAN KdpInitTerminal(VOID)
Initializes the controlling terminal.
Definition: kdterminal.c:51
CHAR KdpReadTermKey(_Out_ PULONG ScanCode)
Reads one character from the terminal. This function returns a scan code even when reading is done fr...
Definition: kdterminal.c:217
#define KEYSC_END
Definition: kdterminal.h:18
#define KEYSC_ARROWUP
Definition: kdterminal.h:22
#define KEYSC_HOME
Definition: kdterminal.h:21
#define KEYSC_PAGEUP
Definition: kdterminal.h:19
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28

Referenced by KdbpPager(), and KdbpPrint().

◆ KdbpPrint()

VOID KdbpPrint ( _In_ PSTR  Format,
_In_ ...   
)

Prints the given string with printf-like formatting.

Parameters
FormatFormat of the string/arguments.
...Variable number of arguments matching the format specified in Format.
Note
Doesn't correctly handle \t and terminal escape sequences when calculating the number of lines required to print a single line from the Buffer in the terminal. Prints maximum 4096 chars, because of its buffer size.

Definition at line 3081 of file kdb_cli.c.

3084{
3085 static CHAR Buffer[4096];
3086 ULONG Length;
3087 va_list ap;
3088
3089 /* Check if the user has aborted output of the current command */
3090 if (KdbOutputAborted)
3091 return;
3092
3093 /* Build the string */
3094 va_start(ap, Format);
3095 Length = _vsnprintf(Buffer, sizeof(Buffer) - 1, Format, ap);
3096 Buffer[Length] = '\0';
3097 va_end(ap);
3098
3099 /* Actually print it */
3101}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
#define _vsnprintf
Definition: xmlstorage.h:202

Referenced by KdbpAttachToProcess(), KdbpAttachToThread(), KdbpCmdBackTrace(), KdbpCmdBreakPoint(), KdbpCmdBreakPointList(), KdbpCmdDisassembleX(), KdbpCmdDmesg(), KdbpCmdEnableDisableClearBreakPoint(), KdbpCmdEvalExpression(), KdbpCmdFilter(), KdbpCmdGdtLdtIdt(), KdbpCmdHelp(), KdbpCmdMod(), KdbpCmdPcr(), KdbpCmdProc(), KdbpCmdRegs(), KdbpCmdSet(), KdbpCmdStep(), KdbpCmdThread(), KdbpEvaluateExpression(), and KdbpPrintUnicodeString().

◆ KdbpPrintUnicodeString()

VOID KdbpPrintUnicodeString ( _In_ PCUNICODE_STRING  String)

Definition at line 3104 of file kdb_cli.c.

3106{
3107 ULONG i;
3108
3109 if ((String == NULL) || (String->Buffer == NULL))
3110 {
3111 KdbpPrint("<NULL>");
3112 return;
3113 }
3114
3115 for (i = 0; i < String->Length / sizeof(WCHAR); i++)
3116 {
3117 KdbpPrint("%c", (CHAR)String->Buffer[i]);
3118 }
3119}
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by KdbpCmdMod().

◆ KdbRegisterCliCallback()

BOOLEAN NTAPI KdbRegisterCliCallback ( PVOID  Callback,
BOOLEAN  Deregister 
)

Definition at line 3124 of file kdb_cli.c.

3127{
3128 ULONG i;
3129
3130 /* Loop all entries */
3131 for (i = 0; i < _countof(KdbCliCallbacks); i++)
3132 {
3133 /* Check if deregistering was requested */
3134 if (Deregister)
3135 {
3136 /* Check if this entry is the one that was registered */
3137 if (KdbCliCallbacks[i] == Callback)
3138 {
3139 /* Delete it and report success */
3141 return TRUE;
3142 }
3143 }
3144 else
3145 {
3146 /* Check if this entry is free */
3147 if (KdbCliCallbacks[i] == NULL)
3148 {
3149 /* Set it and and report success */
3151 return TRUE;
3152 }
3153 }
3154 }
3155
3156 /* Unsuccessful */
3157 return FALSE;
3158}
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458

Referenced by KdSystemDebugControl().

◆ KdpFilterEscapes()

static VOID KdpFilterEscapes ( _Inout_ PSTR  String)
static

Definition at line 2851 of file kdb_cli.c.

2853{
2854 PCHAR p;
2855 SIZE_T i;
2856 size_t len;
2857
2858 while ((p = strrchr(String, '\x1b'))) /* Look for escape character */
2859 {
2860 len = strlen(p);
2861 if (p[1] == '[')
2862 {
2863 i = 2;
2864 while (!isalpha(p[i++]));
2865 memmove(p, p + i, len + 1 - i);
2866 }
2867 else
2868 {
2869 memmove(p, p + 1, len);
2870 }
2871 }
2872}
#define isalpha(c)
Definition: acclib.h:74
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)

Referenced by KdbpPagerInternal().

◆ memrchr()

void * memrchr ( const void s,
int  c,
size_t  n 
)

Definition at line 2771 of file kdb_cli.c.

2772{
2773 const unsigned char *cp;
2774
2775 if (n != 0)
2776 {
2777 cp = (unsigned char *)s + n;
2778 do
2779 {
2780 if (*(--cp) == (unsigned char)c)
2781 return (void *)cp;
2782 } while (--n != 0);
2783 }
2784 return NULL;
2785}
unsigned char
Definition: typeof.h:29
GLdouble s
Definition: gl.h:2039
GLdouble n
Definition: glext.h:7729
POINT cp
Definition: magnifier.c:59

Referenced by CountOnePageUp().

◆ strtoulptr()

FORCEINLINE ULONG_PTR strtoulptr ( const char nptr,
char **  endptr,
int  base 
)

Definition at line 110 of file kdb_cli.c.

111{
112#ifdef _M_IX86
113 return strtoul(nptr, endptr, base);
114#else
115 return strtoull(nptr, endptr, base);
116#endif
117}
#define strtoull
Definition: stabs.c:58

Variable Documentation

◆ __ImageBase

char __ImageBase
extern

Referenced by KdbpCmdMod().

◆ 

struct { ... } ComponentTable[]

◆ Fn

BOOLEAN(* Fn) (ULONG Argc, PCHAR Argv[]) ( ULONG  Argc,
PCHAR  Argv[] 
)

Definition at line 346 of file kdb_cli.c.

Referenced by UhciGet32BitFrameNumber().

◆ Help

int Help

Definition at line 345 of file kdb_cli.c.

Referenced by create_system_dirid(), and KdbpCmdHelp().

◆ Id

ULONG Id

Definition at line 160 of file kdb_cli.c.

Referenced by KdbpCmdFilter().

◆ KdbBreakOnModuleLoad

BOOLEAN KdbBreakOnModuleLoad = FALSE
static

Definition at line 130 of file kdb_cli.c.

Referenced by KdbpCmdSet().

◆ KdbCliCallbacks

PKDBG_CLI_ROUTINE KdbCliCallbacks[10]
static

Definition at line 128 of file kdb_cli.c.

Referenced by KdbpInvokeCliCallbacks(), and KdbRegisterCliCallback().

◆ 

const struct { ... } KdbDebuggerCommands[]

Referenced by KdbpCmdHelp(), and KdbpDoCommand().

◆ KdbDmesgTotalWritten

volatile ULONG KdbDmesgTotalWritten = 0
static

Definition at line 145 of file kdb_cli.c.

Referenced by KdbDebugPrint(), KdbInitialize(), and KdbpCmdDmesg().

◆ KdbInitFileBuffer

volatile PCHAR KdbInitFileBuffer = NULL

Definition at line 137 of file kdb_cli.c.

Referenced by KdbEnterDebuggerException(), KdbpCliInit(), and KdbpCliInterpretInitFile().

◆ KdbNumberOfColsPrinted

ULONG KdbNumberOfColsPrinted = 0
static

Definition at line 133 of file kdb_cli.c.

Referenced by KdbpDoCommand(), and KdbpPagerInternal().

◆ KdbNumberOfRowsPrinted

ULONG KdbNumberOfRowsPrinted = 0
static

Definition at line 132 of file kdb_cli.c.

Referenced by KdbpDoCommand(), and KdbpPagerInternal().

◆ KdbOutputAborted

BOOLEAN KdbOutputAborted = FALSE
static

Definition at line 134 of file kdb_cli.c.

Referenced by KdbpCmdBackTrace(), KdbpDoCommand(), KdbpPagerInternal(), and KdbpPrint().

◆ KdbpBugCheckRequested

BOOLEAN KdbpBugCheckRequested = FALSE

Definition at line 138 of file kdb_cli.c.

Referenced by KdbEnterDebuggerException(), and KdbpCmdBugCheck().

◆ KdbpIsInDmesgMode

volatile BOOLEAN KdbpIsInDmesgMode = FALSE
static

Definition at line 146 of file kdb_cli.c.

Referenced by KdbDebugPrint(), and KdbpCmdDmesg().

◆ KdbPromptStr

◆ KdbRepeatLastCommand

BOOLEAN KdbRepeatLastCommand = FALSE
static

Definition at line 135 of file kdb_cli.c.

Referenced by KdbpCliMainLoop(), and KdbpPagerInternal().

◆ KdbUseIntelSyntax

BOOLEAN KdbUseIntelSyntax = FALSE
static

Definition at line 129 of file kdb_cli.c.

Referenced by KdbpCliMainLoop(), KdbpCmdDisassembleX(), and KdbpCmdSet().

◆ KdpDmesgBuffer

PCHAR KdpDmesgBuffer = NULL
static

Definition at line 142 of file kdb_cli.c.

Referenced by KdbDebugPrint(), KdbInitialize(), and KdbpCmdDmesg().

◆ KdpDmesgBufferSize

const ULONG KdpDmesgBufferSize = 128 * 1024
static

Definition at line 141 of file kdb_cli.c.

Referenced by KdbDebugPrint(), KdbInitialize(), and KdbpCmdDmesg().

◆ KdpDmesgCurrentPosition

volatile ULONG KdpDmesgCurrentPosition = 0
static

Definition at line 143 of file kdb_cli.c.

Referenced by KdbDebugPrint(), and KdbpCmdDmesg().

◆ KdpDmesgFreeBytes

volatile ULONG KdpDmesgFreeBytes = 0
static

Definition at line 144 of file kdb_cli.c.

Referenced by KdbDebugPrint(), KdbInitialize(), and KdbpCmdDmesg().

◆ KdpDmesgLogSpinLock

KSPIN_LOCK KdpDmesgLogSpinLock
static

Definition at line 147 of file kdb_cli.c.

Referenced by KdbDebugPrint(), and KdbInitialize().

◆ Name

Definition at line 159 of file kdb_cli.c.

Referenced by KdbpCmdFilter().

◆ Syntax

PCHAR Syntax

Definition at line 344 of file kdb_cli.c.

Referenced by KdbpCmdHelp().