ReactOS 0.4.16-dev-753-g705a985
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 2886 of file kdb_cli.c.

2891{
2892 PCCH p;
2893 // p0 is initial guess of Page Start
2894 ULONG p0len = TermSize->cx * TermSize->cy;
2895 PCCH p0 = pCurPos - p0len;
2896 PCCH prev_p = p0, p1;
2897 ULONG j;
2898
2899 if (pCurPos < Buffer)
2900 pCurPos = Buffer;
2901 ASSERT(pCurPos <= Buffer + BufLength);
2902
2903 p = memrchr(p0, '\n', p0len);
2904 if (!p)
2905 p = p0;
2906 for (j = TermSize->cy; j--; )
2907 {
2908 int linesCnt;
2909 p1 = memrchr(p0, '\n', p-p0);
2910 prev_p = p;
2911 p = p1;
2912 if (!p)
2913 {
2914 p = prev_p;
2915 if (!p)
2916 p = p0;
2917 break;
2918 }
2919 linesCnt = (TermSize->cx+prev_p-p-2) / TermSize->cx;
2920 if (linesCnt > 1)
2921 j -= linesCnt-1;
2922 }
2923
2924 ASSERT(p != NULL);
2925 ++p;
2926 return (PCHAR)p;
2927}
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:2850
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
CONST CHAR * PCCH
Definition: ntbasedef.h:400
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 3573 of file kdb_cli.c.

3576{
3577 KIRQL OldIrql;
3578 ULONG beg, end, num;
3579
3580 /* Avoid recursive calling if we already are in Dmesg mode */
3582 return;
3583
3584 if (KdpDmesgBuffer == NULL)
3585 return;
3586
3587 /* Acquire the printing spinlock without waiting at raised IRQL */
3589
3591 /* Invariant: always_true(KdpDmesgFreeBytes == KdpDmesgBufferSize); */
3593 if (num != 0)
3594 {
3595 end = (beg + num) % KdpDmesgBufferSize;
3596 if (end > beg)
3597 {
3599 }
3600 else
3601 {
3604 }
3606
3607 /* Counting the total bytes written */
3609 }
3610
3611 /* Release the spinlock */
3613
3614 /* Optional step(?): find out a way to notify about buffer exhaustion,
3615 * and possibly fall into kbd to use dmesg command: user will read
3616 * debug strings before they will be wiped over by next writes. */
3617}
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 3633 of file kdb_cli.c.

3636{
3637 /* Saves the different symbol-loading status across boot phases */
3638 static ULONG LoadSymbols = 0;
3639
3640 if (BootPhase == 0)
3641 {
3642 /* Write out the functions that we support for now */
3643 DispatchTable->KdpPrintRoutine = KdbDebugPrint;
3644
3645 /* Check if we have a command line */
3647 {
3648 /* Get the KDBG Settings */
3650 }
3651
3652 /* Register for BootPhase 1 initialization and as a Provider */
3653 DispatchTable->KdpInitRoutine = KdbInitialize;
3654 InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
3655 }
3656 else if (BootPhase == 1)
3657 {
3658 /* Register for later BootPhase 2 reinitialization */
3659 DispatchTable->KdpInitRoutine = KdbInitialize;
3660
3661 /* Initialize Dmesg support */
3662
3663 /* Allocate a buffer for Dmesg log buffer. +1 for terminating null,
3664 * see kdbp_cli.c:KdbpCmdDmesg()/2 */
3667 TAG_KDBG);
3668 /* Ignore failure if KdpDmesgBuffer is NULL */
3671
3672 /* Initialize spinlock */
3674 }
3675
3676 /* Initialize symbols support in BootPhase 0 and 1 */
3677 if (BootPhase <= 1)
3678 {
3679 LoadSymbols <<= 1;
3680 LoadSymbols |= KdbSymInit(BootPhase);
3681 }
3682
3683 if (BootPhase == 1)
3684 {
3685 /* Announce ourselves */
3686 CHAR buffer[60];
3688 " KDBG debugger enabled - %s\r\n",
3689 !(LoadSymbols & 0x2) ? "No symbols loaded" :
3690 !(LoadSymbols & 0x1) ? "Kernel symbols loaded"
3691 : "Loading symbols");
3693 }
3694
3695 if (BootPhase >= 2)
3696 {
3697 /* I/O is now set up for disk access: load the KDBinit file */
3699
3700 /* Schedule an I/O reinitialization if needed */
3703 {
3704 DispatchTable->KdpInitRoutine = KdbInitialize;
3705 }
3706 }
3707
3708 return STATUS_SUCCESS;
3709}
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:3573
NTSTATUS NTAPI KdbInitialize(_In_ PKD_DISPATCH_TABLE DispatchTable, _In_ ULONG BootPhase)
Initializes the KDBG debugger.
Definition: kdb_cli.c:3633
NTSTATUS KdbpCliInit(VOID)
Called when KDB is initialized.
Definition: kdb_cli.c:3482
static BOOLEAN LoadSymbols
Definition: kdb_symbols.c:30
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:28
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 3482 of file kdb_cli.c.

3483{
3488 FILE_STANDARD_INFORMATION FileStdInfo;
3489 HANDLE hFile = NULL;
3491 PCHAR FileBuffer;
3492
3493 /* Don't load the KDBinit file if its buffer is already lying around */
3495 return STATUS_SUCCESS;
3496
3497 /* Initialize the object attributes */
3498 RtlInitUnicodeString(&FileName, L"\\SystemRoot\\System32\\drivers\\etc\\KDBinit");
3500 &FileName,
3502 NULL,
3503 NULL);
3504
3505 /* Open the file */
3507 &ObjectAttributes, &Iosb, 0,
3510 if (!NT_SUCCESS(Status))
3511 {
3512 DPRINT("Could not open %wZ (Status 0x%lx)\n", &FileName, Status);
3513 return Status;
3514 }
3515
3516 /* Get the size of the file */
3517 Status = ZwQueryInformationFile(hFile, &Iosb,
3518 &FileStdInfo, sizeof(FileStdInfo),
3520 if (!NT_SUCCESS(Status))
3521 {
3522 ZwClose(hFile);
3523 DPRINT1("Could not query size of %wZ (Status 0x%lx)\n", &FileName, Status);
3524 return Status;
3525 }
3526 FileSize = FileStdInfo.EndOfFile.u.LowPart;
3527
3528 /* Allocate memory for the file (add 1 byte for terminating NUL) */
3529 FileBuffer = ExAllocatePool(NonPagedPool, FileSize + 1);
3530 if (!FileBuffer)
3531 {
3532 ZwClose(hFile);
3533 DPRINT1("Could not allocate %lu bytes for KDBinit file\n", FileSize);
3534 return Status;
3535 }
3536
3537 /* Load file into memory */
3538 Status = ZwReadFile(hFile, NULL, NULL, NULL, &Iosb,
3539 FileBuffer, FileSize, NULL, NULL);
3540 ZwClose(hFile);
3541
3543 {
3544 ExFreePool(FileBuffer);
3545 DPRINT1("Could not read KDBinit file into memory (Status 0x%lx)\n", Status);
3546 return Status;
3547 }
3548
3549 FileSize = min(FileSize, (ULONG)Iosb.Information);
3550 FileBuffer[FileSize] = ANSI_NULL;
3551
3552 /* Interpret the KDBinit file by calling back into the debugger */
3556
3557 ExFreePool(FileBuffer);
3558
3559 return STATUS_SUCCESS;
3560}
#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:4403
#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::@2307 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 3430 of file kdb_cli.c.

3431{
3432 PCHAR p1, p2;
3433
3435 if (!p1)
3436 return;
3437
3438 /* Execute the commands in the init file */
3439 KdbPuts("KDB: Executing KDBinit file...\n");
3440 while (p1[0] != '\0')
3441 {
3442 size_t i = strcspn(p1, "\r\n");
3443 if (i > 0)
3444 {
3445 CHAR c = p1[i];
3446 p1[i] = '\0';
3447
3448 /* Look for "break" command and comments */
3449 p2 = p1;
3450 while (isspace(p2[0]))
3451 p2++;
3452
3453 if (strncmp(p2, "break", sizeof("break")-1) == 0 &&
3454 (p2[sizeof("break")-1] == '\0' || isspace(p2[sizeof("break")-1])))
3455 {
3456 /* Run the interactive debugger loop */
3458 }
3459 else if (p2[0] != '#' && p2[0] != '\0') /* Ignore empty lines and comments */
3460 {
3461 /* Invoke the command */
3462 KdbpDoCommand(p1);
3463 }
3464
3465 p1[i] = c;
3466 }
3467
3468 p1 += i;
3469 while (p1[0] == '\r' || p1[0] == '\n')
3470 p1++;
3471 }
3472 KdbPuts("KDB: KDBinit executed\n");
3473}
#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:3284
VOID KdbpCliMainLoop(IN BOOLEAN EnteredOnSingleStep)
KDB Main Loop.
Definition: kdb_cli.c:3353
#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 3353 of file kdb_cli.c.

3355{
3356 BOOLEAN Continue = TRUE;
3357 static CHAR Command[1024];
3358 static CHAR LastCommand[1024] = "";
3359
3360// FIXME HACK: SYSREG SUPPORT CORE-19807 -- Emit a backtrace.
3361// TODO: Remove once SYSREG "bt" command emission is fixed!
3362#if 1
3363 KdbpDoCommand("bt");
3364#endif
3365
3366 if (EnteredOnSingleStep)
3367 {
3370
3371 KdbPuts(": ");
3373 KdbPuts("<INVALID>");
3374 KdbPuts("\n");
3375 }
3376 else
3377 {
3378 /* Preceding this message is one of the "Entered debugger..." banners */
3379 // KdbPuts("\nEntered debugger\n");
3380 KdbPuts("\nType \"help\" for a list of commands.\n");
3381 }
3382
3383 /* Main loop */
3384 while (Continue)
3385 {
3386 /*
3387 * Print the prompt and read a command.
3388 * Repeat the last one if the user pressed Enter.
3389 * This reduces the risk of RSI when single-stepping!
3390 */
3391 // TEMP HACK! Issue an empty string instead of duplicating "kdb:>"
3392 SIZE_T CmdLen = KdbPrompt(/*KdbPromptStr.Buffer*/"", Command, sizeof(Command));
3393 if (CmdLen == 0)
3394 {
3395 /* Nothing received but the user didn't press Enter, retry */
3396 continue;
3397 }
3398 else if (CmdLen > 1) // i.e. (*Command != ANSI_NULL)
3399 {
3400 /* Save this new last command */
3402 RtlStringCbCopyA(LastCommand, sizeof(LastCommand), Command);
3403
3404 /* Remember it */
3406 }
3407 else if (KdbRepeatLastCommand)
3408 {
3409 /* The user directly pressed Enter */
3410 RtlStringCbCopyA(Command, sizeof(Command), LastCommand);
3411 }
3412
3413 /* Invoke the command */
3414 Continue = KdbpDoCommand(Command);
3415 }
3416}
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 1304 of file kdb_cli.c.

1307{
1308 ULONG ul;
1309 ULONGLONG Result = 0;
1313
1314 if (Argc >= 2)
1315 {
1316 /* Check for [L count] part */
1317 ul = 0;
1318 if (strcmp(Argv[Argc-2], "L") == 0)
1319 {
1320 ul = strtoul(Argv[Argc-1], NULL, 0);
1321 if (ul > 0)
1322 {
1323 Argc -= 2;
1324 }
1325 }
1326 else if (Argv[Argc-1][0] == 'L')
1327 {
1328 ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
1329 if (ul > 0)
1330 {
1331 Argc--;
1332 }
1333 }
1334
1335 /* Put the remaining arguments back together */
1336 Argc--;
1337 for (ul = 1; ul < Argc; ul++)
1338 {
1339 Argv[ul][strlen(Argv[ul])] = ' ';
1340 }
1341 Argc++;
1342 }
1343
1344 /* Check if a Frame Address or Thread ID is given */
1345 if (Argc > 1)
1346 {
1347 if (Argv[1][0] == '*')
1348 {
1349 Argv[1]++;
1350
1351 /* Evaluate the expression */
1352 if (!KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result))
1353 return TRUE;
1354
1355 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
1356 KdbpPrint("Warning: Address %I64x is beeing truncated\n", Result);
1357
1358 Frame = (ULONG_PTR)Result;
1359 }
1360 else
1361 {
1362 KdbpPrint("Thread backtrace not supported yet!\n");
1363 return TRUE;
1364 }
1365 }
1366
1367#ifdef _M_IX86
1368 KDESCRIPTOR Gdtr;
1369 USHORT TssSelector;
1370 PKTSS Tss;
1371
1372 /* Retrieve the Global Descriptor Table */
1374
1375 /* Retrieve the current (active) TSS */
1376 TssSelector = Ke386GetTr();
1377 Tss = KdbpRetrieveTss(TssSelector, NULL, &Gdtr);
1378 if (KdbpIsNestedTss(TssSelector, Tss))
1379 {
1380 /* Display the active TSS if it is nested */
1381 KdbpPrint("[Active TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
1382 }
1383#endif
1384
1385 /* If no Frame Address or Thread ID was given, try printing the function at EIP */
1386 if (Argc <= 1)
1387 {
1388 KdbpPrint("Eip:\n");
1390 KdbpPrint("<%p>\n", KeGetContextPc(&Context));
1391 else
1392 KdbpPrint("\n");
1393 }
1394
1395 /* Walk through the frames */
1396 KdbpPrint("Frames:\n");
1397 for (;;)
1398 {
1399 BOOLEAN GotNextFrame;
1400
1401 if (Frame == 0)
1402 goto CheckForParentTSS;
1403
1404 Address = 0;
1405 if (!NT_SUCCESS(KdbpSafeReadMemory(&Address, (PVOID)(Frame + sizeof(ULONG_PTR)), sizeof(ULONG_PTR))))
1406 {
1407 KdbpPrint("Couldn't access memory at 0x%p!\n", Frame + sizeof(ULONG_PTR));
1408 goto CheckForParentTSS;
1409 }
1410
1411 if (Address == 0)
1412 goto CheckForParentTSS;
1413
1414 GotNextFrame = NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof(ULONG_PTR)));
1415 if (GotNextFrame)
1416 {
1418 }
1419 // else
1420 // Frame = 0;
1421
1422 /* Print the location of the call instruction (assumed 5 bytes length) */
1423 if (!KdbSymPrintAddress((PVOID)(Address - 5), &Context))
1424 KdbpPrint("<%08x>\n", Address);
1425 else
1426 KdbpPrint("\n");
1427
1428 if (KdbOutputAborted)
1429 break;
1430
1431 if (!GotNextFrame)
1432 {
1433 KdbpPrint("Couldn't access memory at 0x%p!\n", Frame);
1434 goto CheckForParentTSS; // break;
1435 }
1436
1437 continue;
1438
1439CheckForParentTSS:
1440#ifndef _M_IX86
1441 break;
1442#else
1443 /*
1444 * We have ended the stack walking for the current (active) TSS.
1445 * Check whether this TSS was nested, and if so switch to its parent
1446 * and walk its stack.
1447 */
1448 if (!KdbpIsNestedTss(TssSelector, Tss))
1449 break; // The TSS is not nested, we stop there.
1450
1451 GotNextFrame = KdbpContextFromPrevTss(&Context, &TssSelector, &Tss, &Gdtr);
1452 if (!GotNextFrame)
1453 {
1454 KdbpPrint("Couldn't access parent TSS 0x%04x\n", Tss->Backlink);
1455 break; // Cannot retrieve the parent TSS, we stop there.
1456 }
1457
1458
1459 Address = Context.Eip;
1460 Frame = Context.Ebp;
1461
1462 KdbpPrint("[Parent TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
1463
1465 KdbpPrint("<%08x>\n", Address);
1466 else
1467 KdbpPrint("\n");
1468#endif
1469 }
1470
1471 return TRUE;
1472}
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:424
#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:3160
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:579
Definition: ketypes.h:850
USHORT Backlink
Definition: ketypes.h:851
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 1658 of file kdb_cli.c.

1659{
1660 ULONGLONG Result = 0;
1663 UCHAR Size = 0;
1664 KDB_ACCESS_TYPE AccessType = 0;
1665 ULONG AddressArgIndex, i;
1666 LONG ConditionArgIndex;
1668
1669 if (Argv[0][2] == 'x') /* software breakpoint */
1670 {
1671 if (Argc < 2)
1672 {
1673 KdbpPrint("bpx: Address argument required.\n");
1674 return TRUE;
1675 }
1676
1677 AddressArgIndex = 1;
1679 }
1680 else /* memory breakpoint */
1681 {
1682 ASSERT(Argv[0][2] == 'm');
1683
1684 if (Argc < 2)
1685 {
1686 KdbpPrint("bpm: Access type argument required (one of r, w, rw, x)\n");
1687 return TRUE;
1688 }
1689
1690 if (_stricmp(Argv[1], "x") == 0)
1691 AccessType = KdbAccessExec;
1692 else if (_stricmp(Argv[1], "r") == 0)
1693 AccessType = KdbAccessRead;
1694 else if (_stricmp(Argv[1], "w") == 0)
1695 AccessType = KdbAccessWrite;
1696 else if (_stricmp(Argv[1], "rw") == 0)
1697 AccessType = KdbAccessReadWrite;
1698 else
1699 {
1700 KdbpPrint("bpm: Unknown access type '%s'\n", Argv[1]);
1701 return TRUE;
1702 }
1703
1704 if (Argc < 3)
1705 {
1706 KdbpPrint("bpm: %s argument required.\n", AccessType == KdbAccessExec ? "Address" : "Memory size");
1707 return TRUE;
1708 }
1709
1710 AddressArgIndex = 3;
1711 if (_stricmp(Argv[2], "byte") == 0)
1712 Size = 1;
1713 else if (_stricmp(Argv[2], "word") == 0)
1714 Size = 2;
1715 else if (_stricmp(Argv[2], "dword") == 0)
1716 Size = 4;
1717 else if (AccessType == KdbAccessExec)
1718 {
1719 Size = 1;
1720 AddressArgIndex--;
1721 }
1722 else
1723 {
1724 KdbpPrint("bpm: Unknown memory size '%s'\n", Argv[2]);
1725 return TRUE;
1726 }
1727
1728 if (Argc <= AddressArgIndex)
1729 {
1730 KdbpPrint("bpm: Address argument required.\n");
1731 return TRUE;
1732 }
1733
1735 }
1736
1737 /* Put the arguments back together */
1738 ConditionArgIndex = -1;
1739 for (i = AddressArgIndex; i < (Argc-1); i++)
1740 {
1741 if (strcmp(Argv[i+1], "IF") == 0) /* IF found */
1742 {
1743 ConditionArgIndex = i + 2;
1744 if ((ULONG)ConditionArgIndex >= Argc)
1745 {
1746 KdbpPrint("%s: IF requires condition expression.\n", Argv[0]);
1747 return TRUE;
1748 }
1749
1750 for (i = ConditionArgIndex; i < (Argc-1); i++)
1751 Argv[i][strlen(Argv[i])] = ' ';
1752
1753 break;
1754 }
1755
1756 Argv[i][strlen(Argv[i])] = ' ';
1757 }
1758
1759 /* Evaluate the address expression */
1760 if (!KdbpEvaluateExpression(Argv[AddressArgIndex],
1761 KdbPromptStr.Length + (Argv[AddressArgIndex]-Argv[0]),
1762 &Result))
1763 {
1764 return TRUE;
1765 }
1766
1767 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
1768 KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0],Result);
1769
1771
1772 KdbpInsertBreakPoint(Address, Type, Size, AccessType,
1773 (ConditionArgIndex < 0) ? NULL : Argv[ConditionArgIndex],
1774 Global, NULL);
1775
1776 return TRUE;
1777}
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 1520 of file kdb_cli.c.

1523{
1524 LONG l;
1525 ULONG_PTR Address = 0;
1527 KDB_ACCESS_TYPE AccessType = 0;
1528 UCHAR Size = 0;
1529 UCHAR DebugReg = 0;
1533 PCHAR str1, str2, ConditionExpr, GlobalOrLocal;
1534 CHAR Buffer[20];
1535
1537 if (l < 0)
1538 {
1539 KdbpPrint("No breakpoints.\n");
1540 return TRUE;
1541 }
1542
1543 KdbpPrint("Breakpoints:\n");
1544 do
1545 {
1546 if (!KdbpGetBreakPointInfo(l, &Address, &Type, &Size, &AccessType, &DebugReg,
1547 &Enabled, &Global, &Process, &ConditionExpr))
1548 {
1549 continue;
1550 }
1551
1552 if (l == KdbLastBreakPointNr)
1553 {
1554 str1 = "\x1b[1m*";
1555 str2 = "\x1b[0m";
1556 }
1557 else
1558 {
1559 str1 = " ";
1560 str2 = "";
1561 }
1562
1563 if (Global)
1564 {
1565 GlobalOrLocal = " global";
1566 }
1567 else
1568 {
1569 GlobalOrLocal = Buffer;
1570 sprintf(Buffer, " PID 0x%Ix",
1571 (ULONG_PTR)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
1572 }
1573
1575 {
1576 KdbpPrint(" %s%03d BPX 0x%08x%s%s%s%s%s\n",
1577 str1, l, Address,
1578 Enabled ? "" : " disabled",
1579 GlobalOrLocal,
1580 ConditionExpr ? " IF " : "",
1581 ConditionExpr ? ConditionExpr : "",
1582 str2);
1583 }
1584 else if (Type == KdbBreakPointHardware)
1585 {
1586 if (!Enabled)
1587 {
1588 KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s disabled%s%s%s%s\n", str1, l, Address,
1589 KDB_ACCESS_TYPE_TO_STRING(AccessType),
1590 Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
1591 GlobalOrLocal,
1592 ConditionExpr ? " IF " : "",
1593 ConditionExpr ? ConditionExpr : "",
1594 str2);
1595 }
1596 else
1597 {
1598 KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s DR%d%s%s%s%s\n", str1, l, Address,
1599 KDB_ACCESS_TYPE_TO_STRING(AccessType),
1600 Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
1601 DebugReg,
1602 GlobalOrLocal,
1603 ConditionExpr ? " IF " : "",
1604 ConditionExpr ? ConditionExpr : "",
1605 str2);
1606 }
1607 }
1608 }
1609 while ((l = KdbpGetNextBreakPointNr(l+1)) >= 0);
1610
1611 return TRUE;
1612}
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 2569 of file kdb_cli.c.

2572{
2573 /* Set the flag and quit looping */
2575 return FALSE;
2576}
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 1479 of file kdb_cli.c.

1482{
1483 /* Exit the main loop */
1484 return FALSE;
1485}

◆ 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 801 of file kdb_cli.c.

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

2597{
2598 ULONG beg, end;
2599
2600 KdbpIsInDmesgMode = TRUE; /* Toggle logging flag */
2601 if (!KdpDmesgBuffer)
2602 {
2603 KdbpPrint("Dmesg: error, buffer is not allocated! /DEBUGPORT=SCREEN kernel param required for dmesg.\n");
2604 return TRUE;
2605 }
2606
2607 KdbpPrint("*** Dmesg *** TotalWritten=%lu, BufferSize=%lu, CurrentPosition=%lu\n",
2609
2610 /* Pass data to the pager */
2613
2614 /* No roll-overs, and overwritten=lost bytes */
2616 {
2617 /* Show buffer (KdpDmesgBuffer + beg, num) */
2619 }
2620 else
2621 {
2622 /* Show 2 buffers: (KdpDmesgBuffer + beg, KdpDmesgBufferSize - beg)
2623 * and: (KdpDmesgBuffer, end) */
2625 KdbpPrint("*** Dmesg: buffer rollup ***\n");
2627 }
2628 KdbpPrint("*** Dmesg: end of output ***\n");
2629
2630 KdbpIsInDmesgMode = FALSE; /* Toggle logging flag */
2631
2632 return TRUE;
2633}
VOID KdbpPager(_In_ PCHAR Buffer, _In_ ULONG BufLength)
Prints the given string with, page by page.
Definition: kdb_cli.c:3142

◆ KdbpCmdEnableDisableClearBreakPoint()

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

Enables, disables or clears a breakpoint.

Definition at line 1617 of file kdb_cli.c.

1620{
1621 PCHAR pend;
1622 ULONG BreakPointNr;
1623
1624 if (Argc < 2)
1625 {
1626 KdbpPrint("%s: argument required\n", Argv[0]);
1627 return TRUE;
1628 }
1629
1630 pend = Argv[1];
1631 BreakPointNr = strtoul(Argv[1], &pend, 0);
1632 if (pend == Argv[1] || *pend != '\0')
1633 {
1634 KdbpPrint("%s: integer argument required\n", Argv[0]);
1635 return TRUE;
1636 }
1637
1638 if (Argv[0][1] == 'e') /* enable */
1639 {
1640 KdbpEnableBreakPoint(BreakPointNr, NULL);
1641 }
1642 else if (Argv [0][1] == 'd') /* disable */
1643 {
1644 KdbpDisableBreakPoint(BreakPointNr, NULL);
1645 }
1646 else /* clear */
1647 {
1648 ASSERT(Argv[0][1] == 'c');
1649 KdbpDeleteBreakPoint(BreakPointNr, NULL);
1650 }
1651
1652 return TRUE;
1653}
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 470 of file kdb_cli.c.

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

700{
702 ULONG set = DPFLTR_MASK, clear = DPFLTR_MASK;
703 PCHAR pend;
704 PCSTR opt, p;
705
706 static struct
707 {
708 PCSTR Name;
709 ULONG Level;
710 }
711 debug_classes[] =
712 {
713 { "error", 1 << DPFLTR_ERROR_LEVEL },
714 { "warning", 1 << DPFLTR_WARNING_LEVEL },
715 { "trace", 1 << DPFLTR_TRACE_LEVEL },
716 { "info", 1 << DPFLTR_INFO_LEVEL },
717 };
718
719 if (Argc <= 1)
720 {
721 /* Display the list of available debug filter components */
722 KdbpPrint("REMARKS:\n"
723 "- The 'WIN2000' system-wide debug filter component is used for DbgPrint()\n"
724 " messages without Component ID and Level.\n"
725 "- The 'DEFAULT' debug filter component is used for DbgPrint() messages with\n"
726 " an unknown Component ID.\n\n");
727 KdbpPrint("The list of debug filter components currently available on your system is:\n\n");
728 KdbpPrint(" Component Name Component ID\n"
729 " ================== ================\n");
730 for (i = 0; i < RTL_NUMBER_OF(ComponentTable); i++)
731 {
732 KdbpPrint("%20s 0x%08lx\n", ComponentTable[i].Name, ComponentTable[i].Id);
733 }
734 return TRUE;
735 }
736
737 for (i = 1; i < Argc; i++)
738 {
739 opt = Argv[i];
740 p = opt + strcspn(opt, "+-");
741 if (!p[0]) p = opt; /* Assume it's a debug channel name */
742
743 if (p > opt)
744 {
745 for (j = 0; j < RTL_NUMBER_OF(debug_classes); j++)
746 {
748 if (len != (p - opt))
749 continue;
750 if (_strnicmp(opt, debug_classes[j].Name, len) == 0) /* Found it */
751 {
752 if (*p == '+')
753 set |= debug_classes[j].Level;
754 else
755 clear |= debug_classes[j].Level;
756 break;
757 }
758 }
760 {
761 Level = strtoul(opt, &pend, 0);
762 if (pend != p)
763 {
764 KdbpPrint("filter: bad class name '%.*s'\n", p - opt, opt);
765 continue;
766 }
767 if (*p == '+')
768 set |= Level;
769 else
770 clear |= Level;
771 }
772 }
773 else
774 {
775 if (*p == '-')
776 clear = MAXULONG;
777 else
778 set = MAXULONG;
779 }
780 if (*p == '+' || *p == '-')
781 p++;
782
784 {
785 KdbpPrint("filter: '%s' is not a valid component name!\n", p);
786 return TRUE;
787 }
788
789 /* Get current mask value */
792 }
793
794 return TRUE;
795}
#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:2766
ULONG Id
Definition: kdb_cli.c:160
PCSTR Name
Definition: kdb_cli.c:159
static BOOLEAN KdbpGetComponentId(IN PCSTR ComponentName, OUT PULONG ComponentId)
Retrieves the component ID corresponding to a given component name.
Definition: kdb_cli.c:676
static struct @1828 ComponentTable[]
#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 2175 of file kdb_cli.c.

2178{
2179 KDESCRIPTOR Reg;
2180 ULONG SegDesc[2];
2181 ULONG SegBase;
2182 ULONG SegLimit;
2183 PCHAR SegType;
2184 USHORT SegSel;
2185 UCHAR Type, Dpl;
2186 INT i;
2187 ULONG ul;
2188
2189 if (Argv[0][0] == 'i')
2190 {
2191 /* Read IDTR */
2192 __sidt(&Reg.Limit);
2193
2194 if (Reg.Limit < 7)
2195 {
2196 KdbpPrint("Interrupt descriptor table is empty.\n");
2197 return TRUE;
2198 }
2199
2200 KdbpPrint("IDT Base: 0x%08x Limit: 0x%04x\n", Reg.Base, Reg.Limit);
2201 KdbpPrint(" Idx Type Seg. Sel. Offset DPL\n");
2202
2203 for (i = 0; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
2204 {
2205 if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)((ULONG_PTR)Reg.Base + i), sizeof(SegDesc))))
2206 {
2207 KdbpPrint("Couldn't access memory at 0x%p!\n", (PVOID)((ULONG_PTR)Reg.Base + i));
2208 return TRUE;
2209 }
2210
2211 Dpl = ((SegDesc[1] >> 13) & 3);
2212 if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
2213 SegType = "TASKGATE";
2214 else if ((SegDesc[1] & 0x1fe0) == 0x0e00) /* 32 bit Interrupt gate */
2215 SegType = "INTGATE32";
2216 else if ((SegDesc[1] & 0x1fe0) == 0x0600) /* 16 bit Interrupt gate */
2217 SegType = "INTGATE16";
2218 else if ((SegDesc[1] & 0x1fe0) == 0x0f00) /* 32 bit Trap gate */
2219 SegType = "TRAPGATE32";
2220 else if ((SegDesc[1] & 0x1fe0) == 0x0700) /* 16 bit Trap gate */
2221 SegType = "TRAPGATE16";
2222 else
2223 SegType = "UNKNOWN";
2224
2225 if ((SegDesc[1] & (1 << 15)) == 0) /* not present */
2226 {
2227 KdbpPrint(" %03d %-10s [NP] [NP] %02d\n",
2228 i / 8, SegType, Dpl);
2229 }
2230 else if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
2231 {
2232 SegSel = SegDesc[0] >> 16;
2233 KdbpPrint(" %03d %-10s 0x%04x %02d\n",
2234 i / 8, SegType, SegSel, Dpl);
2235 }
2236 else
2237 {
2238 SegSel = SegDesc[0] >> 16;
2239 SegBase = (SegDesc[1] & 0xffff0000) | (SegDesc[0] & 0x0000ffff);
2240 KdbpPrint(" %03d %-10s 0x%04x 0x%08x %02d\n",
2241 i / 8, SegType, SegSel, SegBase, Dpl);
2242 }
2243 }
2244 }
2245 else
2246 {
2247 ul = 0;
2248
2249 if (Argv[0][0] == 'g')
2250 {
2251 /* Read GDTR */
2253 i = 8;
2254 }
2255 else
2256 {
2257 ASSERT(Argv[0][0] == 'l');
2258
2259 /* Read LDTR */
2261 Reg.Base = 0;
2262 i = 0;
2263 ul = 1 << 2;
2264 }
2265
2266 if (Reg.Limit < 7)
2267 {
2268 KdbpPrint("%s descriptor table is empty.\n",
2269 Argv[0][0] == 'g' ? "Global" : "Local");
2270 return TRUE;
2271 }
2272
2273 KdbpPrint("%cDT Base: 0x%08x Limit: 0x%04x\n",
2274 Argv[0][0] == 'g' ? 'G' : 'L', Reg.Base, Reg.Limit);
2275 KdbpPrint(" Idx Sel. Type Base Limit DPL Attribs\n");
2276
2277 for (; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
2278 {
2279 if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)((ULONG_PTR)Reg.Base + i), sizeof(SegDesc))))
2280 {
2281 KdbpPrint("Couldn't access memory at 0x%p!\n", (ULONG_PTR)Reg.Base + i);
2282 return TRUE;
2283 }
2284
2285 Dpl = ((SegDesc[1] >> 13) & 3);
2286 Type = ((SegDesc[1] >> 8) & 0xf);
2287
2288 SegBase = SegDesc[0] >> 16;
2289 SegBase |= (SegDesc[1] & 0xff) << 16;
2290 SegBase |= SegDesc[1] & 0xff000000;
2291 SegLimit = SegDesc[0] & 0x0000ffff;
2292 SegLimit |= (SegDesc[1] >> 16) & 0xf;
2293
2294 if ((SegDesc[1] & (1 << 23)) != 0)
2295 {
2296 SegLimit *= 4096;
2297 SegLimit += 4095;
2298 }
2299 else
2300 {
2301 SegLimit++;
2302 }
2303
2304 if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
2305 {
2306 switch (Type)
2307 {
2308 case 1: SegType = "TSS16(Avl)"; break;
2309 case 2: SegType = "LDT"; break;
2310 case 3: SegType = "TSS16(Busy)"; break;
2311 case 4: SegType = "CALLGATE16"; break;
2312 case 5: SegType = "TASKGATE"; break;
2313 case 6: SegType = "INTGATE16"; break;
2314 case 7: SegType = "TRAPGATE16"; break;
2315 case 9: SegType = "TSS32(Avl)"; break;
2316 case 11: SegType = "TSS32(Busy)"; break;
2317 case 12: SegType = "CALLGATE32"; break;
2318 case 14: SegType = "INTGATE32"; break;
2319 case 15: SegType = "TRAPGATE32"; break;
2320 default: SegType = "UNKNOWN"; break;
2321 }
2322
2323 if (!(Type >= 1 && Type <= 3) &&
2324 Type != 9 && Type != 11)
2325 {
2326 SegBase = 0;
2327 SegLimit = 0;
2328 }
2329 }
2330 else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
2331 {
2332 if ((SegDesc[1] & (1 << 22)) != 0)
2333 SegType = "DATA32";
2334 else
2335 SegType = "DATA16";
2336 }
2337 else /* Code segment */
2338 {
2339 if ((SegDesc[1] & (1 << 22)) != 0)
2340 SegType = "CODE32";
2341 else
2342 SegType = "CODE16";
2343 }
2344
2345 if ((SegDesc[1] & (1 << 15)) == 0) /* Not present */
2346 {
2347 KdbpPrint(" %03d 0x%04x %-11s [NP] [NP] %02d NP\n",
2348 i / 8, i | Dpl | ul, SegType, Dpl);
2349 }
2350 else
2351 {
2352 KdbpPrint(" %03d 0x%04x %-11s 0x%08x 0x%08x %02d ",
2353 i / 8, i | Dpl | ul, SegType, SegBase, SegLimit, Dpl);
2354
2355 if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
2356 {
2357 /* FIXME: Display system segment */
2358 }
2359 else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
2360 {
2361 if ((SegDesc[1] & (1 << 10)) != 0) /* Expand-down */
2362 KdbpPrint(" E");
2363
2364 KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/W" : " R");
2365
2366 if ((SegDesc[1] & (1 << 8)) != 0)
2367 KdbpPrint(" A");
2368 }
2369 else /* Code segment */
2370 {
2371 if ((SegDesc[1] & (1 << 10)) != 0) /* Conforming */
2372 KdbpPrint(" C");
2373
2374 KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/X" : " X");
2375
2376 if ((SegDesc[1] & (1 << 8)) != 0)
2377 KdbpPrint(" A");
2378 }
2379
2380 if ((SegDesc[1] & (1 << 20)) != 0)
2381 KdbpPrint(" AVL");
2382
2383 KdbpPrint("\n");
2384 }
2385 }
2386 }
2387
2388 return TRUE;
2389}
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2046
#define Ke386GetLocalDescriptorTable
Definition: kdb_cli.c:104
PVOID Base
Definition: ketypes.h:580

◆ KdbpCmdHelp()

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

Displays help screen.

Definition at line 2817 of file kdb_cli.c.

2820{
2821 ULONG i;
2822
2823 KdbpPrint("Kernel debugger commands:\n");
2824 for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
2825 {
2826 if (!KdbDebuggerCommands[i].Syntax) /* Command group */
2827 {
2828 if (i > 0)
2829 KdbpPrint("\n");
2830
2831 KdbpPrint("\x1b[7m* %s:\x1b[0m\n", KdbDebuggerCommands[i].Help);
2832 continue;
2833 }
2834
2835 KdbpPrint(" %-20s - %s\n",
2838 }
2839
2840 return TRUE;
2841}
PCHAR Help
Definition: kdb_cli.c:345
PCHAR Syntax
Definition: kdb_cli.c:344
static const struct @1829 KdbDebuggerCommands[]

◆ KdbpCmdMod()

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

Lists loaded modules or the one containing the specified address.

Definition at line 2109 of file kdb_cli.c.

2112{
2113 ULONGLONG Result = 0;
2115 PLDR_DATA_TABLE_ENTRY LdrEntry;
2116 BOOLEAN DisplayOnlyOneModule = FALSE;
2117 INT i = 0;
2118
2119 if (Argc >= 2)
2120 {
2121 /* Put the arguments back together */
2122 Argc--;
2123 while (--Argc >= 1)
2124 Argv[Argc][strlen(Argv[Argc])] = ' ';
2125
2126 /* Evaluate the expression */
2127 if (!KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result))
2128 {
2129 return TRUE;
2130 }
2131
2132 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
2133 KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0],Result);
2134
2136
2137 if (!KdbpSymFindModule((PVOID)Address, -1, &LdrEntry))
2138 {
2139 KdbpPrint("No module containing address 0x%p found!\n", Address);
2140 return TRUE;
2141 }
2142
2143 DisplayOnlyOneModule = TRUE;
2144 }
2145 else
2146 {
2147 if (!KdbpSymFindModule(NULL, 0, &LdrEntry))
2148 {
2149 ULONG_PTR ntoskrnlBase = (ULONG_PTR)__ImageBase;
2150 KdbpPrint(" Base Size Name\n");
2151 KdbpPrint(" %p %08x %s\n", (PVOID)ntoskrnlBase, 0, "ntoskrnl.exe");
2152 return TRUE;
2153 }
2154
2155 i = 1;
2156 }
2157
2158 KdbpPrint(" Base Size Name\n");
2159 for (;;)
2160 {
2161 KdbpPrint(" %p %08x ", LdrEntry->DllBase, LdrEntry->SizeOfImage);
2163 KdbpPrint("\n");
2164
2165 if(DisplayOnlyOneModule || !KdbpSymFindModule(NULL, i++, &LdrEntry))
2166 break;
2167 }
2168
2169 return TRUE;
2170}
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:3183
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 2394 of file kdb_cli.c.

2397{
2398 PKIPCR Pcr = (PKIPCR)KeGetPcr();
2399
2400 KdbpPrint("Current PCR is at 0x%p.\n", Pcr);
2401#ifdef _M_IX86
2402 KdbpPrint(" Tib.ExceptionList: 0x%08x\n"
2403 " Tib.StackBase: 0x%08x\n"
2404 " Tib.StackLimit: 0x%08x\n"
2405 " Tib.SubSystemTib: 0x%08x\n"
2406 " Tib.FiberData/Version: 0x%08x\n"
2407 " Tib.ArbitraryUserPointer: 0x%08x\n"
2408 " Tib.Self: 0x%08x\n"
2409 " SelfPcr: 0x%08x\n"
2410 " PCRCB: 0x%08x\n"
2411 " Irql: 0x%02x\n"
2412 " IRR: 0x%08x\n"
2413 " IrrActive: 0x%08x\n"
2414 " IDR: 0x%08x\n"
2415 " KdVersionBlock: 0x%08x\n"
2416 " IDT: 0x%08x\n"
2417 " GDT: 0x%08x\n"
2418 " TSS: 0x%08x\n"
2419 " MajorVersion: 0x%04x\n"
2420 " MinorVersion: 0x%04x\n"
2421 " SetMember: 0x%08x\n"
2422 " StallScaleFactor: 0x%08x\n"
2423 " Number: 0x%02x\n"
2424 " L2CacheAssociativity: 0x%02x\n"
2425 " VdmAlert: 0x%08x\n"
2426 " L2CacheSize: 0x%08x\n"
2427 " InterruptMode: 0x%08x\n"
2430 Pcr->NtTib.Self
2431 , Pcr->SelfPcr
2432 , Pcr->Prcb, Pcr->Irql
2433 , Pcr->IRR, Pcr->IrrActive , Pcr->IDR
2434 , Pcr->KdVersionBlock
2435 , Pcr->IDT, Pcr->GDT, Pcr->TSS
2436 , Pcr->MajorVersion, Pcr->MinorVersion
2437 , Pcr->SetMember
2438 , Pcr->StallScaleFactor
2439 , Pcr->Number
2441 , Pcr->VdmAlert
2443 , Pcr->InterruptMode);
2444#else
2445 KdbpPrint(" GdtBase: 0x%p\n", Pcr->GdtBase);
2446 KdbpPrint(" TssBase: 0x%p\n", Pcr->TssBase);
2447 KdbpPrint(" UserRsp: 0x%p\n", (PVOID)Pcr->UserRsp);
2448 KdbpPrint(" Self: 0x%p\n", Pcr->Self);
2449 KdbpPrint(" CurrentPrcb: 0x%p\n", Pcr->CurrentPrcb);
2450 KdbpPrint(" LockArray: 0x%p\n", Pcr->LockArray);
2451 KdbpPrint(" Used_Self: 0x%p\n", Pcr->Used_Self);
2452 KdbpPrint(" IdtBase: 0x%p\n", Pcr->IdtBase);
2453 KdbpPrint(" Irql: %u\n", Pcr->Irql);
2454 KdbpPrint(" SecondLevelCacheAssociativity: 0x%u\n", Pcr->SecondLevelCacheAssociativity);
2455 KdbpPrint(" ObsoleteNumber: %u\n", Pcr->ObsoleteNumber);
2456 KdbpPrint(" MajorVersion: 0x%x\n", Pcr->MajorVersion);
2457 KdbpPrint(" MinorVersion: 0x%x\n", Pcr->MinorVersion);
2458 KdbpPrint(" StallScaleFactor: 0x%lx\n", Pcr->StallScaleFactor);
2459 KdbpPrint(" SecondLevelCacheSize: 0x%lx\n", Pcr->SecondLevelCacheSize);
2460 KdbpPrint(" KdVersionBlock: 0x%p\n", Pcr->KdVersionBlock);
2461#endif
2462
2463 return TRUE;
2464}
struct _KIPCR * PKIPCR
#define KeGetPcr()
Definition: ketypes.h:81
KPRCB Prcb
Definition: ketypes.h:988
USHORT MinorVersion
Definition: ketypes.h:976
ULONG SecondLevelCacheSize
Definition: ketypes.h:980
PKIDTENTRY IDT
Definition: ketypes.h:818
USHORT MajorVersion
Definition: ketypes.h:975
UCHAR SecondLevelCacheAssociativity
Definition: ketypes.h:971
ULONG IrrActive
Definition: ketypes.h:815
KIRQL Irql
Definition: ketypes.h:970
UCHAR Number
Definition: ketypes.h:826
KAFFINITY SetMember
Definition: ketypes.h:823
struct _KPRCB * CurrentPrcb
Definition: ketypes.h:963
ULONG IRR
Definition: ketypes.h:814
union _KGDTENTRY64 * GdtBase
Definition: ketypes.h:959
ULONG InterruptMode
Definition: ketypes.h:833
PKGDTENTRY GDT
Definition: ketypes.h:819
struct _KPCR * SelfPcr
Definition: ketypes.h:811
PKSPIN_LOCK_QUEUE LockArray
Definition: ketypes.h:964
struct _KTSS64 * TssBase
Definition: ketypes.h:960
struct _KTSS * TSS
Definition: ketypes.h:820
UCHAR ObsoleteNumber
Definition: ketypes.h:972
NT_TIB NtTib
Definition: ketypes.h:956
ULONG IDR
Definition: ketypes.h:816
union _KIDTENTRY64 * IdtBase
Definition: ketypes.h:968
struct _KPCR * Self
Definition: ketypes.h:962
ULONG StallScaleFactor
Definition: ketypes.h:977
ULONG VdmAlert
Definition: ketypes.h:829
ULONG64 UserRsp
Definition: ketypes.h:961
PVOID KdVersionBlock
Definition: ketypes.h:984
PVOID Used_Self
Definition: ketypes.h:965
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 1991 of file kdb_cli.c.

1994{
1997 BOOLEAN ReferencedProcess = FALSE;
1998 PCHAR State, pend, str1, str2;
1999 ULONG_PTR ul;
2001
2002 if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
2003 {
2005 if (!Entry || Entry == &PsActiveProcessHead)
2006 {
2007 KdbpPrint("No processes in the system!\n");
2008 return TRUE;
2009 }
2010
2011 KdbpPrint(" PID State Filename\n");
2012 do
2013 {
2014 Process = CONTAINING_RECORD(Entry, EPROCESS, ActiveProcessLinks);
2015
2017 {
2018 str1 = "\x1b[1m*";
2019 str2 = "\x1b[0m";
2020 }
2021 else
2022 {
2023 str1 = " ";
2024 str2 = "";
2025 }
2026
2027 State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
2028 ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
2029
2030 KdbpPrint(" %s0x%08x %-10s %s%s\n",
2031 str1,
2032 Process->UniqueProcessId,
2033 State,
2034 Process->ImageFileName,
2035 str2);
2036
2037 Entry = Entry->Flink;
2038 }
2039 while(Entry != &PsActiveProcessHead);
2040 }
2041 else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
2042 {
2043 if (Argc < 3)
2044 {
2045 KdbpPrint("process attach: process id argument required!\n");
2046 return TRUE;
2047 }
2048
2049 ul = strtoulptr(Argv[2], &pend, 0);
2050 if (Argv[2] == pend)
2051 {
2052 KdbpPrint("process attach: '%s' is not a valid process id!\n", Argv[2]);
2053 return TRUE;
2054 }
2055
2056 if (!KdbpAttachToProcess((PVOID)ul))
2057 {
2058 return TRUE;
2059 }
2060
2061 KdbpPrint("Attached to process 0x%p, thread 0x%p.\n", (PVOID)ul,
2063 }
2064 else
2065 {
2067
2068 if (Argc >= 2)
2069 {
2070 ul = strtoulptr(Argv[1], &pend, 0);
2071 if (Argv[1] == pend)
2072 {
2073 KdbpPrint("proc: '%s' is not a valid process id!\n", Argv[1]);
2074 return TRUE;
2075 }
2076
2078 {
2079 KdbpPrint("proc: Invalid process id!\n");
2080 return TRUE;
2081 }
2082
2083 /* Remember our reference */
2084 ReferencedProcess = TRUE;
2085 }
2086
2087 State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
2088 ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
2089 KdbpPrint("%s"
2090 " PID: 0x%08x\n"
2091 " State: %s (0x%x)\n"
2092 " Image Filename: %s\n",
2093 (Argc < 2) ? "Current process:\n" : "",
2094 Process->UniqueProcessId,
2095 State, Process->Pcb.State,
2096 Process->ImageFileName);
2097
2098 /* Release our reference, if any */
2099 if (ReferencedProcess)
2101 }
2102
2103 return TRUE;
2104}
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 2579 of file kdb_cli.c.

2582{
2583 /* Reboot immediately (we do not return) */
2585 return FALSE;
2586}
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 922 of file kdb_cli.c.

925{
927 INT i;
928 static const PCHAR EflagsBits[32] = { " CF", NULL, " PF", " BIT3", " AF", " BIT5",
929 " ZF", " SF", " TF", " IF", " DF", " OF",
930 NULL, NULL, " NT", " BIT15", " RF", " VF",
931 " AC", " VIF", " VIP", " ID", " BIT22",
932 " BIT23", " BIT24", " BIT25", " BIT26",
933 " BIT27", " BIT28", " BIT29", " BIT30",
934 " BIT31" };
935
936 if (Argv[0][0] == 'r') /* regs */
937 {
938#ifdef _M_IX86
939 KdbpPrint("CS:EIP 0x%04x:0x%08x\n"
940 "SS:ESP 0x%04x:0x%08x\n"
941 " EAX 0x%08x EBX 0x%08x\n"
942 " ECX 0x%08x EDX 0x%08x\n"
943 " ESI 0x%08x EDI 0x%08x\n"
944 " EBP 0x%08x\n",
945 Context->SegCs & 0xFFFF, Context->Eip,
946 Context->SegSs, Context->Esp,
947 Context->Eax, Context->Ebx,
948 Context->Ecx, Context->Edx,
949 Context->Esi, Context->Edi,
950 Context->Ebp);
951#else
952 KdbpPrint("CS:RIP 0x%04x:0x%p\n"
953 "SS:RSP 0x%04x:0x%p\n"
954 " RAX 0x%p RBX 0x%p\n"
955 " RCX 0x%p RDX 0x%p\n"
956 " RSI 0x%p RDI 0x%p\n"
957 " RBP 0x%p\n",
958 Context->SegCs & 0xFFFF, Context->Rip,
959 Context->SegSs, Context->Rsp,
960 Context->Rax, Context->Rbx,
961 Context->Rcx, Context->Rdx,
962 Context->Rsi, Context->Rdi,
963 Context->Rbp);
964#endif
965 /* Display the EFlags */
966 KdbpPrint("EFLAGS 0x%08x ", Context->EFlags);
967 for (i = 0; i < 32; i++)
968 {
969 if (i == 1)
970 {
971 if ((Context->EFlags & (1 << 1)) == 0)
972 KdbpPrint(" !BIT1");
973 }
974 else if (i == 12)
975 {
976 KdbpPrint(" IOPL%d", (Context->EFlags >> 12) & 3);
977 }
978 else if (i == 13)
979 {
980 }
981 else if ((Context->EFlags & (1 << i)) != 0)
982 {
983 KdbpPrint(EflagsBits[i]);
984 }
985 }
986 KdbpPrint("\n");
987 }
988 else if (Argv[0][0] == 'c') /* cregs */
989 {
990 ULONG Cr0, Cr2, Cr3, Cr4;
991 KDESCRIPTOR Gdtr = {0, 0, 0}, Idtr = {0, 0, 0};
992 USHORT Ldtr, Tr;
993 static const PCHAR Cr0Bits[32] = { " PE", " MP", " EM", " TS", " ET", " NE", NULL, NULL,
995 " WP", NULL, " AM", NULL, NULL, NULL, NULL, NULL,
996 NULL, NULL, NULL, NULL, NULL, " NW", " CD", " PG" };
997 static const PCHAR Cr4Bits[32] = { " VME", " PVI", " TSD", " DE", " PSE", " PAE", " MCE", " PGE",
998 " PCE", " OSFXSR", " OSXMMEXCPT", NULL, NULL, NULL, NULL, NULL,
1000 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
1002 KSPECIAL_REGISTERS SpecialRegisters;
1004
1005 /* Retrieve the control registers */
1006 RtlZeroMemory(&Input, sizeof(Input));
1007 Input.Buffer = &SpecialRegisters;
1008 Input.Request = sizeof(SpecialRegisters);
1009#ifdef _M_IX86
1010 Input.Address = sizeof(CONTEXT);
1011#else
1013#endif
1015 &Input, sizeof(Input),
1016 NULL, 0,
1017 NULL, KernelMode);
1018 if (!NT_SUCCESS(Status))
1019 {
1020 KdbpPrint("Failed to get registers: status 0x%08x\n", Status);
1021 return TRUE;
1022 }
1023 Cr0 = SpecialRegisters.Cr0;
1024 Cr2 = SpecialRegisters.Cr2;
1025 Cr3 = SpecialRegisters.Cr3;
1026 Cr4 = SpecialRegisters.Cr4;
1027
1028 /* Retrieve the descriptor table and task segment registers */
1029 Gdtr = SpecialRegisters.Gdtr;
1030 Ldtr = SpecialRegisters.Ldtr;
1031 Idtr = SpecialRegisters.Idtr;
1032 Tr = SpecialRegisters.Tr;
1033
1034 /* Display the control registers */
1035 KdbpPrint("CR0 0x%08x ", Cr0);
1036 for (i = 0; i < 32; i++)
1037 {
1038 if (!Cr0Bits[i])
1039 continue;
1040
1041 if ((Cr0 & (1 << i)) != 0)
1042 KdbpPrint(Cr0Bits[i]);
1043 }
1044 KdbpPrint("\n");
1045
1046 KdbpPrint("CR2 0x%08x\n", Cr2);
1047 KdbpPrint("CR3 0x%08x Pagedir-Base 0x%08x %s%s\n", Cr3, (Cr3 & 0xfffff000),
1048 (Cr3 & (1 << 3)) ? " PWT" : "", (Cr3 & (1 << 4)) ? " PCD" : "" );
1049 KdbpPrint("CR4 0x%08x ", Cr4);
1050 for (i = 0; i < 32; i++)
1051 {
1052 if (!Cr4Bits[i])
1053 continue;
1054
1055 if ((Cr4 & (1 << i)) != 0)
1056 KdbpPrint(Cr4Bits[i]);
1057 }
1058 KdbpPrint("\n");
1059
1060 /* Display the descriptor table and task segment registers */
1061 KdbpPrint("GDTR Base 0x%08x Size 0x%04x\n", Gdtr.Base, Gdtr.Limit);
1062 KdbpPrint("LDTR 0x%04x\n", Ldtr);
1063 KdbpPrint("IDTR Base 0x%08x Size 0x%04x\n", Idtr.Base, Idtr.Limit);
1064 KdbpPrint("TR 0x%04x\n", Tr);
1065 }
1066 else if (Argv[0][0] == 's') /* sregs */
1067 {
1068 KdbpPrint("CS 0x%04x Index 0x%04x %cDT RPL%d\n",
1069 Context->SegCs & 0xffff, (Context->SegCs & 0xffff) >> 3,
1070 (Context->SegCs & (1 << 2)) ? 'L' : 'G', Context->SegCs & 3);
1071 KdbpPrint("DS 0x%04x Index 0x%04x %cDT RPL%d\n",
1072 Context->SegDs, Context->SegDs >> 3, (Context->SegDs & (1 << 2)) ? 'L' : 'G', Context->SegDs & 3);
1073 KdbpPrint("ES 0x%04x Index 0x%04x %cDT RPL%d\n",
1074 Context->SegEs, Context->SegEs >> 3, (Context->SegEs & (1 << 2)) ? 'L' : 'G', Context->SegEs & 3);
1075 KdbpPrint("FS 0x%04x Index 0x%04x %cDT RPL%d\n",
1076 Context->SegFs, Context->SegFs >> 3, (Context->SegFs & (1 << 2)) ? 'L' : 'G', Context->SegFs & 3);
1077 KdbpPrint("GS 0x%04x Index 0x%04x %cDT RPL%d\n",
1078 Context->SegGs, Context->SegGs >> 3, (Context->SegGs & (1 << 2)) ? 'L' : 'G', Context->SegGs & 3);
1079 KdbpPrint("SS 0x%04x Index 0x%04x %cDT RPL%d\n",
1080 Context->SegSs, Context->SegSs >> 3, (Context->SegSs & (1 << 2)) ? 'L' : 'G', Context->SegSs & 3);
1081 }
1082 else /* dregs */
1083 {
1084 ASSERT(Argv[0][0] == 'd');
1085 KdbpPrint("DR0 0x%08x\n"
1086 "DR1 0x%08x\n"
1087 "DR2 0x%08x\n"
1088 "DR3 0x%08x\n"
1089 "DR6 0x%08x\n"
1090 "DR7 0x%08x\n",
1091 Context->Dr0, Context->Dr1, Context->Dr2, Context->Dr3,
1092 Context->Dr6, Context->Dr7);
1093 }
1094
1095 return TRUE;
1096}
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
NTSTATUS NTAPI KdSystemDebugControl(_In_ SYSDBG_COMMAND Command, _In_reads_bytes_(InputBufferLength) PVOID InputBuffer, _In_ ULONG InputBufferLength, _Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer, _In_ ULONG OutputBufferLength, _Out_opt_ PULONG ReturnLength, _In_ KPROCESSOR_MODE PreviousMode)
Perform various queries to the kernel debugger.
Definition: kdapi.c:2217
#define KernelMode
Definition: asm.h:38
@ SysDbgReadControlSpace
Definition: kdtypes.h:74
struct _CONTEXT CONTEXT
@ Input
Definition: arc.h:84
KDESCRIPTOR Gdtr
Definition: ketypes.h:600
KDESCRIPTOR Idtr
Definition: ketypes.h:601
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define AMD64_DEBUG_CONTROL_SPACE_KSPECIAL
Definition: windbgkd.h:205

◆ KdbpCmdSet()

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

Sets or displays a config variables value.

Definition at line 2638 of file kdb_cli.c.

2641{
2642 LONG l;
2643 BOOLEAN First;
2644 PCHAR pend = 0;
2645 KDB_ENTER_CONDITION ConditionFirst = KdbDoNotEnter;
2646 KDB_ENTER_CONDITION ConditionLast = KdbDoNotEnter;
2647
2648 static const PCHAR ExceptionNames[21] =
2649 {
2650 "ZERODEVIDE", "DEBUGTRAP", "NMI", "INT3", "OVERFLOW", "BOUND", "INVALIDOP",
2651 "NOMATHCOP", "DOUBLEFAULT", "RESERVED(9)", "INVALIDTSS", "SEGMENTNOTPRESENT",
2652 "STACKFAULT", "GPF", "PAGEFAULT", "RESERVED(15)", "MATHFAULT", "ALIGNMENTCHECK",
2653 "MACHINECHECK", "SIMDFAULT", "OTHERS"
2654 };
2655
2656 if (Argc == 1)
2657 {
2658 KdbpPrint("Available settings:\n");
2659 KdbpPrint(" syntax [intel|at&t]\n");
2660 KdbpPrint(" condition [exception|*] [first|last] [never|always|kmode|umode]\n");
2661 KdbpPrint(" break_on_module_load [true|false]\n");
2662 }
2663 else if (strcmp(Argv[1], "syntax") == 0)
2664 {
2665 if (Argc == 2)
2666 {
2667 KdbpPrint("syntax = %s\n", KdbUseIntelSyntax ? "intel" : "at&t");
2668 }
2669 else if (Argc >= 3)
2670 {
2671 if (_stricmp(Argv[2], "intel") == 0)
2673 else if (_stricmp(Argv[2], "at&t") == 0)
2675 else
2676 KdbpPrint("Unknown syntax '%s'.\n", Argv[2]);
2677 }
2678 }
2679 else if (strcmp(Argv[1], "condition") == 0)
2680 {
2681 if (Argc == 2)
2682 {
2683 KdbpPrint("Conditions: (First) (Last)\n");
2684 for (l = 0; l < RTL_NUMBER_OF(ExceptionNames) - 1; l++)
2685 {
2686 if (!ExceptionNames[l])
2687 continue;
2688
2689 if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
2690 ASSERT(FALSE);
2691
2692 if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
2693 ASSERT(FALSE);
2694
2695 KdbpPrint(" #%02d %-20s %-8s %-8s\n", l, ExceptionNames[l],
2696 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2697 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2698 }
2699
2700 ASSERT(l == (RTL_NUMBER_OF(ExceptionNames) - 1));
2701 KdbpPrint(" %-20s %-8s %-8s\n", ExceptionNames[l],
2702 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2703 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2704 }
2705 else
2706 {
2707 if (Argc >= 5 && strcmp(Argv[2], "*") == 0) /* Allow * only when setting condition */
2708 {
2709 l = -1;
2710 }
2711 else
2712 {
2713 l = strtoul(Argv[2], &pend, 0);
2714
2715 if (Argv[2] == pend)
2716 {
2717 for (l = 0; l < RTL_NUMBER_OF(ExceptionNames); l++)
2718 {
2719 if (!ExceptionNames[l])
2720 continue;
2721
2722 if (_stricmp(ExceptionNames[l], Argv[2]) == 0)
2723 break;
2724 }
2725 }
2726
2727 if (l >= RTL_NUMBER_OF(ExceptionNames))
2728 {
2729 KdbpPrint("Unknown exception '%s'.\n", Argv[2]);
2730 return TRUE;
2731 }
2732 }
2733
2734 if (Argc > 4)
2735 {
2736 if (_stricmp(Argv[3], "first") == 0)
2737 First = TRUE;
2738 else if (_stricmp(Argv[3], "last") == 0)
2739 First = FALSE;
2740 else
2741 {
2742 KdbpPrint("set condition: second argument must be 'first' or 'last'\n");
2743 return TRUE;
2744 }
2745
2746 if (_stricmp(Argv[4], "never") == 0)
2747 ConditionFirst = KdbDoNotEnter;
2748 else if (_stricmp(Argv[4], "always") == 0)
2749 ConditionFirst = KdbEnterAlways;
2750 else if (_stricmp(Argv[4], "umode") == 0)
2751 ConditionFirst = KdbEnterFromUmode;
2752 else if (_stricmp(Argv[4], "kmode") == 0)
2753 ConditionFirst = KdbEnterFromKmode;
2754 else
2755 {
2756 KdbpPrint("set condition: third argument must be 'never', 'always', 'umode' or 'kmode'\n");
2757 return TRUE;
2758 }
2759
2760 if (!KdbpSetEnterCondition(l, First, ConditionFirst))
2761 {
2762 if (l >= 0)
2763 KdbpPrint("Couldn't change condition for exception #%02d\n", l);
2764 else
2765 KdbpPrint("Couldn't change condition for all exceptions\n", l);
2766 }
2767 }
2768 else /* Argc >= 3 */
2769 {
2770 if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
2771 ASSERT(FALSE);
2772
2773 if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
2774 ASSERT(FALSE);
2775
2776 if (l < (RTL_NUMBER_OF(ExceptionNames) - 1))
2777 {
2778 KdbpPrint("Condition for exception #%02d (%s): FirstChance %s LastChance %s\n",
2779 l, ExceptionNames[l],
2780 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2781 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2782 }
2783 else
2784 {
2785 KdbpPrint("Condition for all other exceptions: FirstChance %s LastChance %s\n",
2786 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2787 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2788 }
2789 }
2790 }
2791 }
2792 else if (strcmp(Argv[1], "break_on_module_load") == 0)
2793 {
2794 if (Argc == 2)
2795 KdbpPrint("break_on_module_load = %s\n", KdbBreakOnModuleLoad ? "enabled" : "disabled");
2796 else if (Argc >= 3)
2797 {
2798 if (_stricmp(Argv[2], "enable") == 0 || _stricmp(Argv[2], "enabled") == 0 || _stricmp(Argv[2], "true") == 0)
2800 else if (_stricmp(Argv[2], "disable") == 0 || _stricmp(Argv[2], "disabled") == 0 || _stricmp(Argv[2], "false") == 0)
2802 else
2803 KdbpPrint("Unknown setting '%s'.\n", Argv[2]);
2804 }
2805 }
2806 else
2807 {
2808 KdbpPrint("Unknown setting '%s'.\n", Argv[1]);
2809 }
2810
2811 return TRUE;
2812}
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 1490 of file kdb_cli.c.

1493{
1494 ULONG Count = 1;
1495
1496 if (Argc > 1)
1497 {
1498 Count = strtoul(Argv[1], NULL, 0);
1499 if (Count == 0)
1500 {
1501 KdbpPrint("%s: Integer argument required\n", Argv[0]);
1502 return TRUE;
1503 }
1504 }
1505
1506 if (Argv[0][0] == 'n')
1508 else
1510
1511 /* Set the number of single steps and return to the interrupted code. */
1513
1514 return FALSE;
1515}
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 1782 of file kdb_cli.c.

1785{
1789 BOOLEAN ReferencedThread = FALSE, ReferencedProcess = FALSE;
1791 PULONG_PTR Frame;
1792 ULONG_PTR Pc;
1793 ULONG_PTR ul = 0;
1794 PCHAR State, pend, str1, str2;
1795 static const PCHAR ThreadStateToString[DeferredReady+1] =
1796 {
1797 "Initialized", "Ready", "Running",
1798 "Standby", "Terminated", "Waiting",
1799 "Transition", "DeferredReady"
1800 };
1801
1803
1804 if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
1805 {
1807
1808 if (Argc >= 3)
1809 {
1810 ul = strtoulptr(Argv[2], &pend, 0);
1811 if (Argv[2] == pend)
1812 {
1813 KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]);
1814 return TRUE;
1815 }
1816
1818 {
1819 KdbpPrint("thread: Invalid process id!\n");
1820 return TRUE;
1821 }
1822
1823 /* Remember our reference */
1824 ReferencedProcess = TRUE;
1825 }
1826
1827 Entry = Process->ThreadListHead.Flink;
1828 if (Entry == &Process->ThreadListHead)
1829 {
1830 if (Argc >= 3)
1831 KdbpPrint("No threads in process 0x%px!\n", (PVOID)ul);
1832 else
1833 KdbpPrint("No threads in current process!\n");
1834
1835 if (ReferencedProcess)
1837
1838 return TRUE;
1839 }
1840
1841 KdbpPrint(" TID State Prior. Affinity EBP EIP\n");
1842 do
1843 {
1844 Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
1845
1846 if (Thread == KdbCurrentThread)
1847 {
1848 str1 = "\x1b[1m*";
1849 str2 = "\x1b[0m";
1850 }
1851 else
1852 {
1853 str1 = " ";
1854 str2 = "";
1855 }
1856
1857 if (!Thread->Tcb.InitialStack)
1858 {
1859 /* Thread has no kernel stack (probably terminated) */
1860 Stack = Frame = NULL;
1861 Pc = 0;
1862 }
1863 else if (Thread->Tcb.TrapFrame)
1864 {
1868 }
1869 else
1870 {
1872 Frame = (PULONG_PTR)Stack[4];
1873 Pc = 0;
1874
1875 if (Frame) /* FIXME: Should we attach to the process to read Ebp[1]? */
1876 KdbpSafeReadMemory(&Pc, Frame + 1, sizeof(Pc));
1877 }
1878
1879 if (Thread->Tcb.State < (DeferredReady + 1))
1880 State = ThreadStateToString[Thread->Tcb.State];
1881 else
1882 State = "Unknown";
1883
1884 KdbpPrint(" %s0x%08x %-11s %3d 0x%08x 0x%08x 0x%08x%s\n",
1885 str1,
1887 State,
1890 Frame,
1891 Pc,
1892 str2);
1893
1894 Entry = Entry->Flink;
1895 }
1896 while (Entry != &Process->ThreadListHead);
1897
1898 /* Release our reference, if any */
1899 if (ReferencedProcess)
1901 }
1902 else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
1903 {
1904 if (Argc < 3)
1905 {
1906 KdbpPrint("thread attach: thread id argument required!\n");
1907 return TRUE;
1908 }
1909
1910 ul = strtoulptr(Argv[2], &pend, 0);
1911 if (Argv[2] == pend)
1912 {
1913 KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]);
1914 return TRUE;
1915 }
1916
1917 if (!KdbpAttachToThread((PVOID)ul))
1918 {
1919 return TRUE;
1920 }
1921
1922 KdbpPrint("Attached to thread 0x%08x.\n", ul);
1923 }
1924 else
1925 {
1927
1928 if (Argc >= 2)
1929 {
1930 ul = strtoulptr(Argv[1], &pend, 0);
1931 if (Argv[1] == pend)
1932 {
1933 KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]);
1934 return TRUE;
1935 }
1936
1938 {
1939 KdbpPrint("thread: Invalid thread id!\n");
1940 return TRUE;
1941 }
1942
1943 /* Remember our reference */
1944 ReferencedThread = TRUE;
1945 }
1946
1947 if (Thread->Tcb.State < (DeferredReady + 1))
1948 State = ThreadStateToString[Thread->Tcb.State];
1949 else
1950 State = "Unknown";
1951
1952 KdbpPrint("%s"
1953 " TID: 0x%08x\n"
1954 " State: %s (0x%x)\n"
1955 " Priority: %d\n"
1956 " Affinity: 0x%08x\n"
1957 " Initial Stack: 0x%08x\n"
1958 " Stack Limit: 0x%08x\n"
1959 " Stack Base: 0x%08x\n"
1960 " Kernel Stack: 0x%08x\n"
1961 " Trap Frame: 0x%08x\n"
1962#ifndef _M_AMD64
1963 " NPX State: %s (0x%x)\n"
1964#endif
1965 , (Argc < 2) ? "Current Thread:\n" : ""
1967 , State, Thread->Tcb.State
1975#ifndef _M_AMD64
1977#endif
1978 );
1979
1980 /* Release our reference if we had one */
1981 if (ReferencedThread)
1983 }
1984
1985 return TRUE;
1986}
_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 3284 of file kdb_cli.c.

3286{
3287 BOOLEAN Continue = TRUE;
3288 SIZE_T i;
3289 PCHAR p;
3290 ULONG Argc;
3291 // FIXME: for what do we need a 1024 characters command line and 256 tokens?
3292 static PCHAR Argv[256];
3293 static CHAR OrigCommand[1024];
3294
3295 RtlStringCbCopyA(OrigCommand, sizeof(OrigCommand), Command);
3296
3297 Argc = 0;
3298 p = Command;
3299
3300 for (;;)
3301 {
3302 while (*p == '\t' || *p == ' ')
3303 p++;
3304
3305 if (*p == '\0')
3306 break;
3307
3308 i = strcspn(p, "\t ");
3309 Argv[Argc++] = p;
3310 p += i;
3311 if (*p == '\0')
3312 break;
3313
3314 *p = '\0';
3315 p++;
3316 }
3317
3318 if (Argc < 1)
3319 return TRUE;
3320
3321 /* Reset the pager state: number of printed rows/cols and aborted output flag */
3324
3325 for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
3326 {
3328 continue;
3329
3330 if (strcmp(KdbDebuggerCommands[i].Name, Argv[0]) == 0)
3331 {
3332 Continue = KdbDebuggerCommands[i].Fn(Argc, Argv);
3333 goto Done;
3334 }
3335 }
3336
3337 /* Now invoke the registered callbacks */
3338 if (KdbpInvokeCliCallbacks(Command, Argc, Argv))
3339 goto Done;
3340
3341 KdbPrintf("Command '%s' is unknown.\n", OrigCommand);
3342
3343Done:
3345 return Continue;
3346}
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:3250
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 424 of file kdb_cli.c.

428{
429 static CHAR ErrMsgBuffer[130] = "^ ";
430 LONG ExpressionErrOffset = -1;
431 PCHAR ErrMsg = ErrMsgBuffer;
432 BOOLEAN Ok;
433
435 &ExpressionErrOffset, ErrMsgBuffer + 2);
436 if (!Ok)
437 {
438 if (ExpressionErrOffset >= 0)
439 ExpressionErrOffset += ErrOffset;
440 else
441 ErrMsg += 2;
442
443 KdbpPrint("%*s%s\n", ExpressionErrOffset, "", ErrMsg);
444 }
445
446 return Ok;
447}
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 676 of file kdb_cli.c.

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

Referenced by KdbpCmdFilter().

◆ KdbpGetHexNumber()

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

Definition at line 451 of file kdb_cli.c.

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

◆ 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 3250 of file kdb_cli.c.

3254{
3255 ULONG i;
3256
3257 /* Loop all entries */
3258 for (i = 0; i < _countof(KdbCliCallbacks); i++)
3259 {
3260 /* Check if this entry is registered */
3261 if (KdbCliCallbacks[i])
3262 {
3263 /* Invoke the callback and check if it handled the command */
3264 if (KdbCliCallbacks[i](Command, Argc, Argv))
3265 {
3266 return TRUE;
3267 }
3268 }
3269 }
3270
3271 /* None of the callbacks handled the command */
3272 return FALSE;
3273}
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 3142 of file kdb_cli.c.

3145{
3146 /* Call the internal function */
3147 KdbpPagerInternal(Buffer, BufLength, TRUE);
3148}
static VOID KdbpPagerInternal(_In_ PCHAR Buffer, _In_ ULONG BufLength, _In_ BOOLEAN DoPage)
Prints the given string with, page by page.
Definition: kdb_cli.c:2966

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 2966 of file kdb_cli.c.

2970{
2971 static BOOLEAN TerminalInitialized = FALSE;
2972 CHAR c;
2974 PCHAR p;
2975 SIZE_T i;
2976 LONG RowsPrintedByTerminal;
2977
2978 if (BufLength == 0)
2979 return;
2980
2981 /* Check if the user has aborted output of the current command */
2982 if (KdbOutputAborted)
2983 return;
2984
2985 /* Initialize the terminal */
2986 if (!TerminalInitialized)
2987 {
2988 TerminalInitialized = TRUE;
2990 }
2991
2992 /* Refresh terminal size each time when number of printed rows is 0 */
2993 if (KdbNumberOfRowsPrinted == 0)
2994 {
2996 }
2997
2998 /* Loop through the strings */
2999 p = Buffer;
3000 while (p[0] != '\0')
3001 {
3002 if (DoPage)
3003 {
3004 if (p > Buffer + BufLength)
3005 {
3006 KdbPrintf("Dmesg: error, p > Buffer+BufLength,d=%d", p - (Buffer + BufLength));
3007 return;
3008 }
3009 }
3010 i = strcspn(p, "\n");
3011
3012 if (DoPage)
3013 {
3014 /* Are we out of buffer? */
3015 if (p + i > Buffer + BufLength)
3016 break; // Leaving pager function
3017 }
3018
3019 /* Calculate the number of lines which will be printed in
3020 * the terminal when outputting the current line. */
3021 if (i > 0)
3022 RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) / KdTermSize.cx;
3023 else
3024 RowsPrintedByTerminal = 0;
3025
3026 if (p[i] == '\n')
3027 RowsPrintedByTerminal++;
3028
3029 //KdbPrintf("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);
3030
3031 /* Display a prompt if we printed one screen full of text */
3032 if (KdTermSize.cy > 0 &&
3033 (LONG)(KdbNumberOfRowsPrinted + RowsPrintedByTerminal) >= KdTermSize.cy)
3034 {
3035 PCSTR Prompt;
3036
3037 /* Disable the repetition of previous command with long many-page output */
3039
3040 if (KdbNumberOfColsPrinted > 0)
3041 KdbPuts("\n");
3042
3043 if (DoPage)
3044 Prompt = "--- Press q to abort, e/End,h/Home,u/PgUp, other key/PgDn ---";
3045 else
3046 Prompt = "--- Press q to abort, any other key to continue ---";
3047
3048 KdbPuts(Prompt);
3050 if (DoPage) // Show pressed key
3051 KdbPrintf(" '%c'/scan=%04x\n", c, ScanCode);
3052 else
3053 KdbPuts("\n");
3054
3055 RowsPrintedByTerminal++;
3056
3057 if (c == 'q')
3058 {
3060 return;
3061 }
3062
3063 if (DoPage)
3064 {
3065 if (ScanCode == KEYSC_END || c == 'e')
3066 {
3067 PCHAR pBufEnd = Buffer + BufLength;
3068 p = CountOnePageUp(Buffer, BufLength, pBufEnd, &KdTermSize);
3069 i = strcspn(p, "\n");
3070 }
3071 else if (ScanCode == KEYSC_PAGEUP ||
3072 ScanCode == KEYSC_ARROWUP || c == 'u')
3073 {
3074 p = CountOnePageUp(Buffer, BufLength, p, &KdTermSize);
3075 i = strcspn(p, "\n");
3076 }
3077 else if (ScanCode == KEYSC_HOME || c == 'h')
3078 {
3079 p = Buffer;
3080 i = strcspn(p, "\n");
3081 }
3082 }
3083
3086 }
3087
3088 /* Insert a NUL after the line and print only the current line */
3089 if (p[i] == '\n' && p[i + 1] != '\0')
3090 {
3091 c = p[i + 1];
3092 p[i + 1] = '\0';
3093 }
3094 else
3095 {
3096 c = '\0';
3097 }
3098
3099 /* Remove escape sequences from the line if there is no terminal connected */
3100 // FIXME: Dangerous operation since we modify the source string!!
3101 if (!KdTermConnected)
3103
3104 /* Print the current line */
3105 KdbPuts(p);
3106
3107 /* Restore not null char with saved */
3108 if (c != '\0')
3109 p[i + 1] = c;
3110
3111 /* Set p to the start of the next line and
3112 * remember the number of printed rows/cols */
3113 p += i;
3114 if (p[0] == '\n')
3115 {
3116 p++;
3118 }
3119 else
3120 {
3121 ASSERT(p[0] == '\0');
3123 }
3124
3125 KdbNumberOfRowsPrinted += RowsPrintedByTerminal;
3126 }
3127}
UINT ScanCode
Definition: VirtualKey.c:24
static VOID KdpFilterEscapes(_Inout_ PSTR String)
Definition: kdb_cli.c:2930
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:2886
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 3160 of file kdb_cli.c.

3163{
3164 static CHAR Buffer[4096];
3165 ULONG Length;
3166 va_list ap;
3167
3168 /* Check if the user has aborted output of the current command */
3169 if (KdbOutputAborted)
3170 return;
3171
3172 /* Build the string */
3173 va_start(ap, Format);
3174 Length = _vsnprintf(Buffer, sizeof(Buffer) - 1, Format, ap);
3175 Buffer[Length] = '\0';
3176 va_end(ap);
3177
3178 /* Actually print it */
3180}
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 3183 of file kdb_cli.c.

3185{
3186 ULONG i;
3187
3188 if ((String == NULL) || (String->Buffer == NULL))
3189 {
3190 KdbpPrint("<NULL>");
3191 return;
3192 }
3193
3194 for (i = 0; i < String->Length / sizeof(WCHAR); i++)
3195 {
3196 KdbpPrint("%c", (CHAR)String->Buffer[i]);
3197 }
3198}
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by KdbpCmdMod().

◆ KdbRegisterCliCallback()

BOOLEAN NTAPI KdbRegisterCliCallback ( PVOID  Callback,
BOOLEAN  Deregister 
)

Definition at line 3203 of file kdb_cli.c.

3206{
3207 ULONG i;
3208
3209 /* Loop all entries */
3210 for (i = 0; i < _countof(KdbCliCallbacks); i++)
3211 {
3212 /* Check if deregistering was requested */
3213 if (Deregister)
3214 {
3215 /* Check if this entry is the one that was registered */
3216 if (KdbCliCallbacks[i] == Callback)
3217 {
3218 /* Delete it and report success */
3220 return TRUE;
3221 }
3222 }
3223 else
3224 {
3225 /* Check if this entry is free */
3226 if (KdbCliCallbacks[i] == NULL)
3227 {
3228 /* Set it and and report success */
3230 return TRUE;
3231 }
3232 }
3233 }
3234
3235 /* Unsuccessful */
3236 return FALSE;
3237}
_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 2930 of file kdb_cli.c.

2932{
2933 PCHAR p;
2934 SIZE_T i;
2935 size_t len;
2936
2937 while ((p = strrchr(String, '\x1b'))) /* Look for escape character */
2938 {
2939 len = strlen(p);
2940 if (p[1] == '[')
2941 {
2942 i = 2;
2943 while (!isalpha(p[i++]));
2944 memmove(p, p + i, len + 1 - i);
2945 }
2946 else
2947 {
2948 memmove(p, p + 1, len);
2949 }
2950 }
2951}
#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 2850 of file kdb_cli.c.

2851{
2852 const unsigned char *cp;
2853
2854 if (n != 0)
2855 {
2856 cp = (unsigned char *)s + n;
2857 do
2858 {
2859 if (*(--cp) == (unsigned char)c)
2860 return (void *)cp;
2861 } while (--n != 0);
2862 }
2863 return NULL;
2864}
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().