ReactOS 0.4.15-dev-8002-gbbb3b00
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)
 This function is called by KdbEnterDebuggerException...
 
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
 
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 153 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 45 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 40 of file kdb_cli.c.

◆ Ke386GetGlobalDescriptorTable

#define Ke386GetGlobalDescriptorTable   __sgdt

Definition at line 100 of file kdb_cli.c.

◆ Ke386GetLocalDescriptorTable

#define Ke386GetLocalDescriptorTable   __sldt

Definition at line 103 of file kdb_cli.c.

◆ NDEBUG

#define NDEBUG

Definition at line 35 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 50 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 121 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 2808 of file kdb_cli.c.

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

Referenced by KdbpPagerInternal().

◆ ExpKdbgExtDefWrites()

BOOLEAN ExpKdbgExtDefWrites ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ ExpKdbgExtFileCache()

BOOLEAN ExpKdbgExtFileCache ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ ExpKdbgExtHandle()

BOOLEAN ExpKdbgExtHandle ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ ExpKdbgExtIrpFind()

BOOLEAN ExpKdbgExtIrpFind ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ ExpKdbgExtPool()

BOOLEAN ExpKdbgExtPool ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ ExpKdbgExtPoolFind()

BOOLEAN ExpKdbgExtPoolFind ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ ExpKdbgExtPoolUsed()

BOOLEAN ExpKdbgExtPoolUsed ( ULONG  Argc,
PCHAR  Argv[] 
)

◆ KdbDebugPrint()

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

Debug logger function.

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

Definition at line 3491 of file kdb_cli.c.

3494{
3495 KIRQL OldIrql;
3496 ULONG beg, end, num;
3497
3498 /* Avoid recursive calling if we already are in Dmesg mode */
3500 return;
3501
3502 if (KdpDmesgBuffer == NULL)
3503 return;
3504
3505 /* Acquire the printing spinlock without waiting at raised IRQL */
3507
3509 /* Invariant: always_true(KdpDmesgFreeBytes == KdpDmesgBufferSize); */
3511 if (num != 0)
3512 {
3513 end = (beg + num) % KdpDmesgBufferSize;
3514 if (end > beg)
3515 {
3517 }
3518 else
3519 {
3522 }
3524
3525 /* Counting the total bytes written */
3527 }
3528
3529 /* Release the spinlock */
3531
3532 /* Optional step(?): find out a way to notify about buffer exhaustion,
3533 * and possibly fall into kbd to use dmesg command: user will read
3534 * debug strings before they will be wiped over by next writes. */
3535}
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:146
static const ULONG KdpDmesgBufferSize
Definition: kdb_cli.c:140
static volatile ULONG KdpDmesgCurrentPosition
Definition: kdb_cli.c:142
static volatile ULONG KdpDmesgFreeBytes
Definition: kdb_cli.c:143
static PCHAR KdpDmesgBuffer
Definition: kdb_cli.c:141
static volatile ULONG KdbDmesgTotalWritten
Definition: kdb_cli.c:144
static volatile BOOLEAN KdbpIsInDmesgMode
Definition: kdb_cli.c:145
#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 3551 of file kdb_cli.c.

3554{
3555 /* Saves the different symbol-loading status across boot phases */
3556 static ULONG LoadSymbols = 0;
3557
3558 if (BootPhase == 0)
3559 {
3560 /* Write out the functions that we support for now */
3561 DispatchTable->KdpPrintRoutine = KdbDebugPrint;
3562
3563 /* Check if we have a command line */
3565 {
3566 /* Get the KDBG Settings */
3568 }
3569
3570 /* Register for BootPhase 1 initialization and as a Provider */
3571 DispatchTable->KdpInitRoutine = KdbInitialize;
3572 InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
3573 }
3574 else if (BootPhase == 1)
3575 {
3576 /* Register for later BootPhase 2 reinitialization */
3577 DispatchTable->KdpInitRoutine = KdbInitialize;
3578
3579 /* Initialize Dmesg support */
3580
3581 /* Allocate a buffer for Dmesg log buffer. +1 for terminating null,
3582 * see kdbp_cli.c:KdbpCmdDmesg()/2 */
3583 KdpDmesgBuffer = ExAllocatePoolZero(NonPagedPool,
3585 TAG_KDBG);
3586 /* Ignore failure if KdpDmesgBuffer is NULL */
3589
3590 /* Initialize spinlock */
3592 }
3593
3594 /* Initialize symbols support in BootPhase 0 and 1 */
3595 if (BootPhase <= 1)
3596 {
3597 LoadSymbols <<= 1;
3598 LoadSymbols |= KdbSymInit(BootPhase);
3599 }
3600
3601 if (BootPhase == 1)
3602 {
3603 /* Announce ourselves */
3604 CHAR buffer[60];
3606 " KDBG debugger enabled - %s\r\n",
3607 !(LoadSymbols & 0x2) ? "No symbols loaded" :
3608 !(LoadSymbols & 0x1) ? "Kernel symbols loaded"
3609 : "Loading symbols");
3611 }
3612
3613 if (BootPhase >= 2)
3614 {
3615 /* I/O is now set up for disk access: Read KDB Data */
3617
3618 /* Schedule an I/O reinitialization if needed */
3621 {
3622 DispatchTable->KdpInitRoutine = KdbInitialize;
3623 }
3624 }
3625
3626 return STATUS_SUCCESS;
3627}
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:1621
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:3491
NTSTATUS NTAPI KdbInitialize(_In_ PKD_DISPATCH_TABLE DispatchTable, _In_ ULONG BootPhase)
Initializes the KDBG debugger.
Definition: kdb_cli.c:3551
NTSTATUS KdbpCliInit(VOID)
Called when KDB is initialized.
Definition: kdb_cli.c:3393
static BOOLEAN LoadSymbols
Definition: kdb_symbols.c:30
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
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.

Reads the KDBinit file from the SystemRoot\System32\drivers\etc directory and executes it.

Definition at line 3393 of file kdb_cli.c.

3394{
3399 FILE_STANDARD_INFORMATION FileStdInfo;
3400 HANDLE hFile = NULL;
3401 INT FileSize;
3402 PCHAR FileBuffer;
3403 ULONG OldEflags;
3404
3405 /* Don't load the KDBinit file if its buffer is already lying around */
3407 return STATUS_SUCCESS;
3408
3409 /* Initialize the object attributes */
3410 RtlInitUnicodeString(&FileName, L"\\SystemRoot\\System32\\drivers\\etc\\KDBinit");
3412 &FileName,
3414 NULL,
3415 NULL);
3416
3417 /* Open the file */
3419 &ObjectAttributes, &Iosb, 0,
3422 if (!NT_SUCCESS(Status))
3423 {
3424 DPRINT("Could not open \\SystemRoot\\System32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
3425 return Status;
3426 }
3427
3428 /* Get the size of the file */
3429 Status = ZwQueryInformationFile(hFile, &Iosb,
3430 &FileStdInfo, sizeof(FileStdInfo),
3432 if (!NT_SUCCESS(Status))
3433 {
3434 ZwClose(hFile);
3435 DPRINT("Could not query size of \\SystemRoot\\System32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
3436 return Status;
3437 }
3438 FileSize = FileStdInfo.EndOfFile.u.LowPart;
3439
3440 /* Allocate memory for the file */
3441 FileBuffer = ExAllocatePool(PagedPool, FileSize + 1); /* add 1 byte for terminating '\0' */
3442 if (!FileBuffer)
3443 {
3444 ZwClose(hFile);
3445 DPRINT("Could not allocate %d bytes for KDBinit file\n", FileSize);
3446 return Status;
3447 }
3448
3449 /* Load file into memory */
3450 Status = ZwReadFile(hFile, NULL, NULL, NULL, &Iosb, FileBuffer, FileSize, NULL, NULL);
3451 ZwClose(hFile);
3452
3454 {
3455 ExFreePool(FileBuffer);
3456 DPRINT("Could not read KDBinit file into memory (Status 0x%lx)\n", Status);
3457 return Status;
3458 }
3459
3460 FileSize = min(FileSize, (INT)Iosb.Information);
3461 FileBuffer[FileSize] = '\0';
3462
3463 /* Enter critical section */
3464 OldEflags = __readeflags();
3465 _disable();
3466
3467 /* Interpret the init file... */
3468 KdbInitFileBuffer = FileBuffer;
3469 //KdbEnter(); // FIXME, see commit baa47fa5e
3471
3472 /* Leave critical section */
3473 __writeeflags(OldEflags);
3474
3475 ExFreePool(FileBuffer);
3476
3477 return STATUS_SUCCESS;
3478}
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
return Iosb
Definition: create.c:4402
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PagedPool
Definition: env_spec_w32.h:308
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
struct _FileName FileName
Definition: fatprocs.h:896
#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
void __cdecl _disable(void)
Definition: intrin_arm.h:365
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1669
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1674
PCHAR KdbInitFileBuffer
Definition: kdb_cli.c:136
#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)
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 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:71
int32_t INT
Definition: typedefs.h:58
struct _LARGE_INTEGER::@2296 u

Referenced by KdbInitialize().

◆ KdbpCliInterpretInitFile()

VOID KdbpCliInterpretInitFile ( VOID  )

This function is called by KdbEnterDebuggerException...

Used to interpret the init file in a context with a trapframe setup (KdbpCliInit call KdbEnter which will call KdbEnterDebuggerException which will call this function if KdbInitFileBuffer is not NULL.

Definition at line 3342 of file kdb_cli.c.

3343{
3344 PCHAR p1, p2;
3345 INT_PTR i;
3346 CHAR c;
3347
3348 /* Execute the commands in the init file */
3349 DPRINT("KDB: Executing KDBinit file...\n");
3350 p1 = KdbInitFileBuffer;
3351 while (p1[0] != '\0')
3352 {
3353 i = strcspn(p1, "\r\n");
3354 if (i > 0)
3355 {
3356 c = p1[i];
3357 p1[i] = '\0';
3358
3359 /* Look for "break" command and comments */
3360 p2 = p1;
3361
3362 while (isspace(p2[0]))
3363 p2++;
3364
3365 if (strncmp(p2, "break", sizeof("break")-1) == 0 &&
3366 (p2[sizeof("break")-1] == '\0' || isspace(p2[sizeof("break")-1])))
3367 {
3368 /* break into the debugger */
3370 }
3371 else if (p2[0] != '#' && p2[0] != '\0') /* Ignore empty lines and comments */
3372 {
3373 KdbpDoCommand(p1);
3374 }
3375
3376 p1[i] = c;
3377 }
3378
3379 p1 += i;
3380 while (p1[0] == '\r' || p1[0] == '\n')
3381 p1++;
3382 }
3383 DPRINT("KDB: KDBinit executed\n");
3384}
#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
static BOOLEAN KdbpDoCommand(IN PCHAR Command)
Parses command line and executes command if found.
Definition: kdb_cli.c:3206
VOID KdbpCliMainLoop(IN BOOLEAN EnteredOnSingleStep)
KDB Main Loop.
Definition: kdb_cli.c:3268
#define c
Definition: ke_i.h:80
_Check_return_ _CRTIMP size_t __cdecl strcspn(_In_z_ const char *_Str, _In_z_ const char *_Control)
int32_t INT_PTR
Definition: typedefs.h:64

Referenced by KdbEnterDebuggerException().

◆ KdbpCliMainLoop()

VOID KdbpCliMainLoop ( IN BOOLEAN  EnteredOnSingleStep)

KDB Main Loop.

Parameters
EnteredOnSingleStepTRUE if KDB was entered on single step.

Definition at line 3268 of file kdb_cli.c.

3270{
3271 BOOLEAN Continue;
3272 SIZE_T CmdLen;
3273 static CHAR Command[1024];
3274 static CHAR LastCommand[1024] = "";
3275
3276 if (EnteredOnSingleStep)
3277 {
3279 {
3281 }
3282
3283 KdbpPrint(": ");
3285 {
3286 KdbpPrint("<INVALID>");
3287 }
3288 KdbpPrint("\n");
3289 }
3290
3291 /* Main loop */
3292 do
3293 {
3294 /* Reset the number of rows/cols printed */
3296
3297 /*
3298 * Print the prompt and read a command.
3299 * Repeat the last one if the user pressed Enter.
3300 * This reduces the risk of RSI when single-stepping!
3301 */
3302 // TEMP HACK! Issue an empty string instead of duplicating "kdb:>"
3303 CmdLen = KdbPrompt(/*KdbPromptStr.Buffer*/"", Command, sizeof(Command));
3304 if (CmdLen == 0)
3305 {
3306 /* Nothing received but the user didn't press Enter, retry */
3307 continue;
3308 }
3309 else if (CmdLen > 1) // i.e. (*Command != ANSI_NULL)
3310 {
3311 /* Save this new last command */
3313 RtlStringCbCopyA(LastCommand, sizeof(LastCommand), Command);
3314
3315 /* Remember it */
3317 }
3318 else if (KdbRepeatLastCommand)
3319 {
3320 /* The user directly pressed Enter */
3321 RtlStringCbCopyA(Command, sizeof(Command), LastCommand);
3322 }
3323
3324 /* Reset the number of rows/cols printed and output aborted state */
3327
3328 /* Call the command */
3329 Continue = KdbpDoCommand(Command);
3331 }
3332 while (Continue);
3333}
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
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:134
static ULONG KdbNumberOfRowsPrinted
Definition: kdb_cli.c:131
static BOOLEAN KdbUseIntelSyntax
Definition: kdb_cli.c:128
static BOOLEAN KdbOutputAborted
Definition: kdb_cli.c:133
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:3082
static ULONG KdbNumberOfColsPrinted
Definition: kdb_cli.c:132
#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 1226 of file kdb_cli.c.

1229{
1230 ULONG ul;
1231 ULONGLONG Result = 0;
1235
1236 if (Argc >= 2)
1237 {
1238 /* Check for [L count] part */
1239 ul = 0;
1240 if (strcmp(Argv[Argc-2], "L") == 0)
1241 {
1242 ul = strtoul(Argv[Argc-1], NULL, 0);
1243 if (ul > 0)
1244 {
1245 Argc -= 2;
1246 }
1247 }
1248 else if (Argv[Argc-1][0] == 'L')
1249 {
1250 ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
1251 if (ul > 0)
1252 {
1253 Argc--;
1254 }
1255 }
1256
1257 /* Put the remaining arguments back together */
1258 Argc--;
1259 for (ul = 1; ul < Argc; ul++)
1260 {
1261 Argv[ul][strlen(Argv[ul])] = ' ';
1262 }
1263 Argc++;
1264 }
1265
1266 /* Check if a Frame Address or Thread ID is given */
1267 if (Argc > 1)
1268 {
1269 if (Argv[1][0] == '*')
1270 {
1271 Argv[1]++;
1272
1273 /* Evaluate the expression */
1274 if (!KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result))
1275 return TRUE;
1276
1277 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
1278 KdbpPrint("Warning: Address %I64x is beeing truncated\n", Result);
1279
1280 Frame = (ULONG_PTR)Result;
1281 }
1282 else
1283 {
1284 KdbpPrint("Thread backtrace not supported yet!\n");
1285 return TRUE;
1286 }
1287 }
1288
1289#ifdef _M_IX86
1290 KDESCRIPTOR Gdtr;
1291 USHORT TssSelector;
1292 PKTSS Tss;
1293
1294 /* Retrieve the Global Descriptor Table */
1296
1297 /* Retrieve the current (active) TSS */
1298 TssSelector = Ke386GetTr();
1299 Tss = KdbpRetrieveTss(TssSelector, NULL, &Gdtr);
1300 if (KdbpIsNestedTss(TssSelector, Tss))
1301 {
1302 /* Display the active TSS if it is nested */
1303 KdbpPrint("[Active TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
1304 }
1305#endif
1306
1307 /* If no Frame Address or Thread ID was given, try printing the function at EIP */
1308 if (Argc <= 1)
1309 {
1310 KdbpPrint("Eip:\n");
1312 KdbpPrint("<%p>\n", KeGetContextPc(&Context));
1313 else
1314 KdbpPrint("\n");
1315 }
1316
1317 /* Walk through the frames */
1318 KdbpPrint("Frames:\n");
1319 for (;;)
1320 {
1321 BOOLEAN GotNextFrame;
1322
1323 if (Frame == 0)
1324 goto CheckForParentTSS;
1325
1326 Address = 0;
1327 if (!NT_SUCCESS(KdbpSafeReadMemory(&Address, (PVOID)(Frame + sizeof(ULONG_PTR)), sizeof(ULONG_PTR))))
1328 {
1329 KdbpPrint("Couldn't access memory at 0x%p!\n", Frame + sizeof(ULONG_PTR));
1330 goto CheckForParentTSS;
1331 }
1332
1333 if (Address == 0)
1334 goto CheckForParentTSS;
1335
1336 GotNextFrame = NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof(ULONG_PTR)));
1337 if (GotNextFrame)
1338 {
1340 }
1341 // else
1342 // Frame = 0;
1343
1344 /* Print the location of the call instruction (assumed 5 bytes length) */
1345 if (!KdbSymPrintAddress((PVOID)(Address - 5), &Context))
1346 KdbpPrint("<%08x>\n", Address);
1347 else
1348 KdbpPrint("\n");
1349
1350 if (KdbOutputAborted)
1351 break;
1352
1353 if (!GotNextFrame)
1354 {
1355 KdbpPrint("Couldn't access memory at 0x%p!\n", Frame);
1356 goto CheckForParentTSS; // break;
1357 }
1358
1359 continue;
1360
1361CheckForParentTSS:
1362#ifndef _M_IX86
1363 break;
1364#else
1365 /*
1366 * We have ended the stack walking for the current (active) TSS.
1367 * Check whether this TSS was nested, and if so switch to its parent
1368 * and walk its stack.
1369 */
1370 if (!KdbpIsNestedTss(TssSelector, Tss))
1371 break; // The TSS is not nested, we stop there.
1372
1373 GotNextFrame = KdbpContextFromPrevTss(&Context, &TssSelector, &Tss, &Gdtr);
1374 if (!GotNextFrame)
1375 {
1376 KdbpPrint("Couldn't access parent TSS 0x%04x\n", Tss->Backlink);
1377 break; // Cannot retrieve the parent TSS, we stop there.
1378 }
1379
1380
1381 Address = Context.Eip;
1382 Frame = Context.Ebp;
1383
1384 KdbpPrint("[Parent TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
1385
1387 KdbpPrint("<%08x>\n", Address);
1388 else
1389 KdbpPrint("\n");
1390#endif
1391 }
1392
1393 return TRUE;
1394}
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:1643
static BOOLEAN KdbpEvaluateExpression(IN PCHAR Expression, IN LONG ErrOffset, OUT PULONGLONG Result)
Evaluates an expression...
Definition: kdb_cli.c:422
#define Ke386GetGlobalDescriptorTable
Definition: kdb_cli.c:100
const CSTRING KdbPromptStr
Definition: kdb_cli.c:148
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:570
Definition: ketypes.h:844
USHORT Backlink
Definition: ketypes.h:845
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint64_t ULONGLONG
Definition: typedefs.h:67
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

◆ KdbpCmdBreakPoint()

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

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

Definition at line 1580 of file kdb_cli.c.

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

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

◆ KdbpCmdBugCheck()

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

Bugchecks the system.

Definition at line 2491 of file kdb_cli.c.

2494{
2495 /* Set the flag and quit looping */
2497 return FALSE;
2498}
BOOLEAN KdbpBugCheckRequested
Definition: kdb_cli.c:137

◆ KdbpCmdContinue()

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

Continues execution of the system/leaves KDB.

Definition at line 1401 of file kdb_cli.c.

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

◆ 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

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

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

◆ KdbpCmdEnableDisableClearBreakPoint()

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

Enables, disables or clears a breakpoint.

Definition at line 1539 of file kdb_cli.c.

1542{
1543 PCHAR pend;
1544 ULONG BreakPointNr;
1545
1546 if (Argc < 2)
1547 {
1548 KdbpPrint("%s: argument required\n", Argv[0]);
1549 return TRUE;
1550 }
1551
1552 pend = Argv[1];
1553 BreakPointNr = strtoul(Argv[1], &pend, 0);
1554 if (pend == Argv[1] || *pend != '\0')
1555 {
1556 KdbpPrint("%s: integer argument required\n", Argv[0]);
1557 return TRUE;
1558 }
1559
1560 if (Argv[0][1] == 'e') /* enable */
1561 {
1562 KdbpEnableBreakPoint(BreakPointNr, NULL);
1563 }
1564 else if (Argv [0][1] == 'd') /* disable */
1565 {
1566 KdbpDisableBreakPoint(BreakPointNr, NULL);
1567 }
1568 else /* clear */
1569 {
1570 ASSERT(Argv[0][1] == 'c');
1571 KdbpDeleteBreakPoint(BreakPointNr, NULL);
1572 }
1573
1574 return TRUE;
1575}
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 468 of file kdb_cli.c.

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

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

◆ KdbpCmdHelp()

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

Displays help screen.

Definition at line 2739 of file kdb_cli.c.

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

◆ KdbpCmdMod()

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

Lists loaded modules or the one containing the specified address.

Definition at line 2031 of file kdb_cli.c.

2034{
2035 ULONGLONG Result = 0;
2037 PLDR_DATA_TABLE_ENTRY LdrEntry;
2038 BOOLEAN DisplayOnlyOneModule = FALSE;
2039 INT i = 0;
2040
2041 if (Argc >= 2)
2042 {
2043 /* Put the arguments back together */
2044 Argc--;
2045 while (--Argc >= 1)
2046 Argv[Argc][strlen(Argv[Argc])] = ' ';
2047
2048 /* Evaluate the expression */
2049 if (!KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result))
2050 {
2051 return TRUE;
2052 }
2053
2054 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
2055 KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0],Result);
2056
2058
2059 if (!KdbpSymFindModule((PVOID)Address, -1, &LdrEntry))
2060 {
2061 KdbpPrint("No module containing address 0x%p found!\n", Address);
2062 return TRUE;
2063 }
2064
2065 DisplayOnlyOneModule = TRUE;
2066 }
2067 else
2068 {
2069 if (!KdbpSymFindModule(NULL, 0, &LdrEntry))
2070 {
2071 ULONG_PTR ntoskrnlBase = (ULONG_PTR)__ImageBase;
2072 KdbpPrint(" Base Size Name\n");
2073 KdbpPrint(" %p %08x %s\n", (PVOID)ntoskrnlBase, 0, "ntoskrnl.exe");
2074 return TRUE;
2075 }
2076
2077 i = 1;
2078 }
2079
2080 KdbpPrint(" Base Size Name\n");
2081 for (;;)
2082 {
2083 KdbpPrint(" %p %08x ", LdrEntry->DllBase, LdrEntry->SizeOfImage);
2085 KdbpPrint("\n");
2086
2087 if(DisplayOnlyOneModule || !KdbpSymFindModule(NULL, i++, &LdrEntry))
2088 break;
2089 }
2090
2091 return TRUE;
2092}
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:3105
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 2316 of file kdb_cli.c.

2319{
2320 PKIPCR Pcr = (PKIPCR)KeGetPcr();
2321
2322 KdbpPrint("Current PCR is at 0x%p.\n", Pcr);
2323#ifdef _M_IX86
2324 KdbpPrint(" Tib.ExceptionList: 0x%08x\n"
2325 " Tib.StackBase: 0x%08x\n"
2326 " Tib.StackLimit: 0x%08x\n"
2327 " Tib.SubSystemTib: 0x%08x\n"
2328 " Tib.FiberData/Version: 0x%08x\n"
2329 " Tib.ArbitraryUserPointer: 0x%08x\n"
2330 " Tib.Self: 0x%08x\n"
2331 " SelfPcr: 0x%08x\n"
2332 " PCRCB: 0x%08x\n"
2333 " Irql: 0x%02x\n"
2334 " IRR: 0x%08x\n"
2335 " IrrActive: 0x%08x\n"
2336 " IDR: 0x%08x\n"
2337 " KdVersionBlock: 0x%08x\n"
2338 " IDT: 0x%08x\n"
2339 " GDT: 0x%08x\n"
2340 " TSS: 0x%08x\n"
2341 " MajorVersion: 0x%04x\n"
2342 " MinorVersion: 0x%04x\n"
2343 " SetMember: 0x%08x\n"
2344 " StallScaleFactor: 0x%08x\n"
2345 " Number: 0x%02x\n"
2346 " L2CacheAssociativity: 0x%02x\n"
2347 " VdmAlert: 0x%08x\n"
2348 " L2CacheSize: 0x%08x\n"
2349 " InterruptMode: 0x%08x\n"
2352 Pcr->NtTib.Self
2353 , Pcr->SelfPcr
2354 , Pcr->Prcb, Pcr->Irql
2355 , Pcr->IRR, Pcr->IrrActive , Pcr->IDR
2356 , Pcr->KdVersionBlock
2357 , Pcr->IDT, Pcr->GDT, Pcr->TSS
2358 , Pcr->MajorVersion, Pcr->MinorVersion
2359 , Pcr->SetMember
2360 , Pcr->StallScaleFactor
2361 , Pcr->Number
2363 , Pcr->VdmAlert
2365 , Pcr->InterruptMode);
2366#else
2367 KdbpPrint(" GdtBase: 0x%p\n", Pcr->GdtBase);
2368 KdbpPrint(" TssBase: 0x%p\n", Pcr->TssBase);
2369 KdbpPrint(" UserRsp: 0x%p\n", (PVOID)Pcr->UserRsp);
2370 KdbpPrint(" Self: 0x%p\n", Pcr->Self);
2371 KdbpPrint(" CurrentPrcb: 0x%p\n", Pcr->CurrentPrcb);
2372 KdbpPrint(" LockArray: 0x%p\n", Pcr->LockArray);
2373 KdbpPrint(" Used_Self: 0x%p\n", Pcr->Used_Self);
2374 KdbpPrint(" IdtBase: 0x%p\n", Pcr->IdtBase);
2375 KdbpPrint(" Irql: %u\n", Pcr->Irql);
2376 KdbpPrint(" SecondLevelCacheAssociativity: 0x%u\n", Pcr->SecondLevelCacheAssociativity);
2377 KdbpPrint(" ObsoleteNumber: %u\n", Pcr->ObsoleteNumber);
2378 KdbpPrint(" MajorVersion: 0x%x\n", Pcr->MajorVersion);
2379 KdbpPrint(" MinorVersion: 0x%x\n", Pcr->MinorVersion);
2380 KdbpPrint(" StallScaleFactor: 0x%lx\n", Pcr->StallScaleFactor);
2381 KdbpPrint(" SecondLevelCacheSize: 0x%lx\n", Pcr->SecondLevelCacheSize);
2382 KdbpPrint(" KdVersionBlock: 0x%p\n", Pcr->KdVersionBlock);
2383#endif
2384
2385 return TRUE;
2386}
struct _KIPCR * PKIPCR
#define KeGetPcr()
Definition: ketypes.h:81
KPRCB Prcb
Definition: ketypes.h:976
USHORT MinorVersion
Definition: ketypes.h:964
ULONG SecondLevelCacheSize
Definition: ketypes.h:968
PKIDTENTRY IDT
Definition: ketypes.h:812
USHORT MajorVersion
Definition: ketypes.h:963
UCHAR SecondLevelCacheAssociativity
Definition: ketypes.h:959
ULONG IrrActive
Definition: ketypes.h:809
KIRQL Irql
Definition: ketypes.h:958
UCHAR Number
Definition: ketypes.h:820
KAFFINITY SetMember
Definition: ketypes.h:817
struct _KPRCB * CurrentPrcb
Definition: ketypes.h:951
ULONG IRR
Definition: ketypes.h:808
union _KGDTENTRY64 * GdtBase
Definition: ketypes.h:947
ULONG InterruptMode
Definition: ketypes.h:827
PKGDTENTRY GDT
Definition: ketypes.h:813
struct _KPCR * SelfPcr
Definition: ketypes.h:805
PKSPIN_LOCK_QUEUE LockArray
Definition: ketypes.h:952
struct _KTSS64 * TssBase
Definition: ketypes.h:948
struct _KTSS * TSS
Definition: ketypes.h:814
UCHAR ObsoleteNumber
Definition: ketypes.h:960
NT_TIB NtTib
Definition: ketypes.h:944
ULONG IDR
Definition: ketypes.h:810
union _KIDTENTRY64 * IdtBase
Definition: ketypes.h:956
struct _KPCR * Self
Definition: ketypes.h:950
ULONG StallScaleFactor
Definition: ketypes.h:965
ULONG VdmAlert
Definition: ketypes.h:823
ULONG64 UserRsp
Definition: ketypes.h:949
PVOID KdVersionBlock
Definition: ketypes.h:972
PVOID Used_Self
Definition: ketypes.h:953
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 1913 of file kdb_cli.c.

1916{
1919 BOOLEAN ReferencedProcess = FALSE;
1920 PCHAR State, pend, str1, str2;
1921 ULONG_PTR ul;
1923
1924 if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
1925 {
1927 if (!Entry || Entry == &PsActiveProcessHead)
1928 {
1929 KdbpPrint("No processes in the system!\n");
1930 return TRUE;
1931 }
1932
1933 KdbpPrint(" PID State Filename\n");
1934 do
1935 {
1936 Process = CONTAINING_RECORD(Entry, EPROCESS, ActiveProcessLinks);
1937
1939 {
1940 str1 = "\x1b[1m*";
1941 str2 = "\x1b[0m";
1942 }
1943 else
1944 {
1945 str1 = " ";
1946 str2 = "";
1947 }
1948
1949 State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
1950 ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
1951
1952 KdbpPrint(" %s0x%08x %-10s %s%s\n",
1953 str1,
1954 Process->UniqueProcessId,
1955 State,
1956 Process->ImageFileName,
1957 str2);
1958
1959 Entry = Entry->Flink;
1960 }
1961 while(Entry != &PsActiveProcessHead);
1962 }
1963 else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
1964 {
1965 if (Argc < 3)
1966 {
1967 KdbpPrint("process attach: process id argument required!\n");
1968 return TRUE;
1969 }
1970
1971 ul = strtoulptr(Argv[2], &pend, 0);
1972 if (Argv[2] == pend)
1973 {
1974 KdbpPrint("process attach: '%s' is not a valid process id!\n", Argv[2]);
1975 return TRUE;
1976 }
1977
1978 if (!KdbpAttachToProcess((PVOID)ul))
1979 {
1980 return TRUE;
1981 }
1982
1983 KdbpPrint("Attached to process 0x%p, thread 0x%p.\n", (PVOID)ul,
1985 }
1986 else
1987 {
1989
1990 if (Argc >= 2)
1991 {
1992 ul = strtoulptr(Argv[1], &pend, 0);
1993 if (Argv[1] == pend)
1994 {
1995 KdbpPrint("proc: '%s' is not a valid process id!\n", Argv[1]);
1996 return TRUE;
1997 }
1998
2000 {
2001 KdbpPrint("proc: Invalid process id!\n");
2002 return TRUE;
2003 }
2004
2005 /* Remember our reference */
2006 ReferencedProcess = TRUE;
2007 }
2008
2009 State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
2010 ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
2011 KdbpPrint("%s"
2012 " PID: 0x%08x\n"
2013 " State: %s (0x%x)\n"
2014 " Image Filename: %s\n",
2015 (Argc < 2) ? "Current process:\n" : "",
2016 Process->UniqueProcessId,
2017 State, Process->Pcb.State,
2018 Process->ImageFileName);
2019
2020 /* Release our reference, if any */
2021 if (ReferencedProcess)
2023 }
2024
2025 return TRUE;
2026}
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:1128
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 2501 of file kdb_cli.c.

2504{
2505 /* Reboot immediately (we do not return) */
2507 return FALSE;
2508}
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] == 's') /* sregs */
989 {
990 KdbpPrint("CS 0x%04x Index 0x%04x %cDT RPL%d\n",
991 Context->SegCs & 0xffff, (Context->SegCs & 0xffff) >> 3,
992 (Context->SegCs & (1 << 2)) ? 'L' : 'G', Context->SegCs & 3);
993 KdbpPrint("DS 0x%04x Index 0x%04x %cDT RPL%d\n",
994 Context->SegDs, Context->SegDs >> 3, (Context->SegDs & (1 << 2)) ? 'L' : 'G', Context->SegDs & 3);
995 KdbpPrint("ES 0x%04x Index 0x%04x %cDT RPL%d\n",
996 Context->SegEs, Context->SegEs >> 3, (Context->SegEs & (1 << 2)) ? 'L' : 'G', Context->SegEs & 3);
997 KdbpPrint("FS 0x%04x Index 0x%04x %cDT RPL%d\n",
998 Context->SegFs, Context->SegFs >> 3, (Context->SegFs & (1 << 2)) ? 'L' : 'G', Context->SegFs & 3);
999 KdbpPrint("GS 0x%04x Index 0x%04x %cDT RPL%d\n",
1000 Context->SegGs, Context->SegGs >> 3, (Context->SegGs & (1 << 2)) ? 'L' : 'G', Context->SegGs & 3);
1001 KdbpPrint("SS 0x%04x Index 0x%04x %cDT RPL%d\n",
1002 Context->SegSs, Context->SegSs >> 3, (Context->SegSs & (1 << 2)) ? 'L' : 'G', Context->SegSs & 3);
1003 }
1004 else /* dregs */
1005 {
1006 ASSERT(Argv[0][0] == 'd');
1007 KdbpPrint("DR0 0x%08x\n"
1008 "DR1 0x%08x\n"
1009 "DR2 0x%08x\n"
1010 "DR3 0x%08x\n"
1011 "DR6 0x%08x\n"
1012 "DR7 0x%08x\n",
1013 Context->Dr0, Context->Dr1, Context->Dr2, Context->Dr3,
1014 Context->Dr6, Context->Dr7);
1015 }
1016
1017 return TRUE;
1018}

◆ KdbpCmdSet()

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

Sets or displays a config variables value.

Definition at line 2560 of file kdb_cli.c.

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

◆ KdbpCmdStep()

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

Continues execution of the system/leaves KDB.

Definition at line 1412 of file kdb_cli.c.

1415{
1416 ULONG Count = 1;
1417
1418 if (Argc > 1)
1419 {
1420 Count = strtoul(Argv[1], NULL, 0);
1421 if (Count == 0)
1422 {
1423 KdbpPrint("%s: Integer argument required\n", Argv[0]);
1424 return TRUE;
1425 }
1426 }
1427
1428 if (Argv[0][0] == 'n')
1430 else
1432
1433 /* Set the number of single steps and return to the interrupted code. */
1435
1436 return FALSE;
1437}
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 1704 of file kdb_cli.c.

1707{
1711 BOOLEAN ReferencedThread = FALSE, ReferencedProcess = FALSE;
1713 PULONG_PTR Frame;
1714 ULONG_PTR Pc;
1715 ULONG_PTR ul = 0;
1716 PCHAR State, pend, str1, str2;
1717 static const PCHAR ThreadStateToString[DeferredReady+1] =
1718 {
1719 "Initialized", "Ready", "Running",
1720 "Standby", "Terminated", "Waiting",
1721 "Transition", "DeferredReady"
1722 };
1723
1725
1726 if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
1727 {
1729
1730 if (Argc >= 3)
1731 {
1732 ul = strtoulptr(Argv[2], &pend, 0);
1733 if (Argv[2] == pend)
1734 {
1735 KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]);
1736 return TRUE;
1737 }
1738
1740 {
1741 KdbpPrint("thread: Invalid process id!\n");
1742 return TRUE;
1743 }
1744
1745 /* Remember our reference */
1746 ReferencedProcess = TRUE;
1747 }
1748
1749 Entry = Process->ThreadListHead.Flink;
1750 if (Entry == &Process->ThreadListHead)
1751 {
1752 if (Argc >= 3)
1753 KdbpPrint("No threads in process 0x%px!\n", (PVOID)ul);
1754 else
1755 KdbpPrint("No threads in current process!\n");
1756
1757 if (ReferencedProcess)
1759
1760 return TRUE;
1761 }
1762
1763 KdbpPrint(" TID State Prior. Affinity EBP EIP\n");
1764 do
1765 {
1766 Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
1767
1768 if (Thread == KdbCurrentThread)
1769 {
1770 str1 = "\x1b[1m*";
1771 str2 = "\x1b[0m";
1772 }
1773 else
1774 {
1775 str1 = " ";
1776 str2 = "";
1777 }
1778
1779 if (!Thread->Tcb.InitialStack)
1780 {
1781 /* Thread has no kernel stack (probably terminated) */
1782 Stack = Frame = NULL;
1783 Pc = 0;
1784 }
1785 else if (Thread->Tcb.TrapFrame)
1786 {
1790 }
1791 else
1792 {
1794 Frame = (PULONG_PTR)Stack[4];
1795 Pc = 0;
1796
1797 if (Frame) /* FIXME: Should we attach to the process to read Ebp[1]? */
1798 KdbpSafeReadMemory(&Pc, Frame + 1, sizeof(Pc));
1799 }
1800
1801 if (Thread->Tcb.State < (DeferredReady + 1))
1802 State = ThreadStateToString[Thread->Tcb.State];
1803 else
1804 State = "Unknown";
1805
1806 KdbpPrint(" %s0x%08x %-11s %3d 0x%08x 0x%08x 0x%08x%s\n",
1807 str1,
1809 State,
1812 Frame,
1813 Pc,
1814 str2);
1815
1816 Entry = Entry->Flink;
1817 }
1818 while (Entry != &Process->ThreadListHead);
1819
1820 /* Release our reference, if any */
1821 if (ReferencedProcess)
1823 }
1824 else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
1825 {
1826 if (Argc < 3)
1827 {
1828 KdbpPrint("thread attach: thread id argument required!\n");
1829 return TRUE;
1830 }
1831
1832 ul = strtoulptr(Argv[2], &pend, 0);
1833 if (Argv[2] == pend)
1834 {
1835 KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]);
1836 return TRUE;
1837 }
1838
1839 if (!KdbpAttachToThread((PVOID)ul))
1840 {
1841 return TRUE;
1842 }
1843
1844 KdbpPrint("Attached to thread 0x%08x.\n", ul);
1845 }
1846 else
1847 {
1849
1850 if (Argc >= 2)
1851 {
1852 ul = strtoulptr(Argv[1], &pend, 0);
1853 if (Argv[1] == pend)
1854 {
1855 KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]);
1856 return TRUE;
1857 }
1858
1860 {
1861 KdbpPrint("thread: Invalid thread id!\n");
1862 return TRUE;
1863 }
1864
1865 /* Remember our reference */
1866 ReferencedThread = TRUE;
1867 }
1868
1869 if (Thread->Tcb.State < (DeferredReady + 1))
1870 State = ThreadStateToString[Thread->Tcb.State];
1871 else
1872 State = "Unknown";
1873
1874 KdbpPrint("%s"
1875 " TID: 0x%08x\n"
1876 " State: %s (0x%x)\n"
1877 " Priority: %d\n"
1878 " Affinity: 0x%08x\n"
1879 " Initial Stack: 0x%08x\n"
1880 " Stack Limit: 0x%08x\n"
1881 " Stack Base: 0x%08x\n"
1882 " Kernel Stack: 0x%08x\n"
1883 " Trap Frame: 0x%08x\n"
1884#ifndef _M_AMD64
1885 " NPX State: %s (0x%x)\n"
1886#endif
1887 , (Argc < 2) ? "Current Thread:\n" : ""
1889 , State, Thread->Tcb.State
1897#ifndef _M_AMD64
1899#endif
1900 );
1901
1902 /* Release our reference if we had one */
1903 if (ReferencedThread)
1905 }
1906
1907 return TRUE;
1908}
_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:50
@ 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:1103
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 3206 of file kdb_cli.c.

3208{
3209 SIZE_T i;
3210 PCHAR p;
3211 ULONG Argc;
3212 // FIXME: for what do we need a 1024 characters command line and 256 tokens?
3213 static PCHAR Argv[256];
3214 static CHAR OrigCommand[1024];
3215
3216 RtlStringCbCopyA(OrigCommand, sizeof(OrigCommand), Command);
3217
3218 Argc = 0;
3219 p = Command;
3220
3221 for (;;)
3222 {
3223 while (*p == '\t' || *p == ' ')
3224 p++;
3225
3226 if (*p == '\0')
3227 break;
3228
3229 i = strcspn(p, "\t ");
3230 Argv[Argc++] = p;
3231 p += i;
3232 if (*p == '\0')
3233 break;
3234
3235 *p = '\0';
3236 p++;
3237 }
3238
3239 if (Argc < 1)
3240 return TRUE;
3241
3242 for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
3243 {
3245 continue;
3246
3247 if (strcmp(KdbDebuggerCommands[i].Name, Argv[0]) == 0)
3248 {
3249 return KdbDebuggerCommands[i].Fn(Argc, Argv);
3250 }
3251 }
3252
3253 /* Now invoke the registered callbacks */
3254 if (KdbpInvokeCliCallbacks(Command, Argc, Argv))
3255 {
3256 return TRUE;
3257 }
3258
3259 KdbpPrint("Command '%s' is unknown.\n", OrigCommand);
3260 return TRUE;
3261}
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:3172

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

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

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

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

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

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

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

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

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

3085{
3086 static CHAR Buffer[4096];
3087 ULONG Length;
3088 va_list ap;
3089
3090 /* Check if the user has aborted output of the current command */
3091 if (KdbOutputAborted)
3092 return;
3093
3094 /* Build the string */
3095 va_start(ap, Format);
3096 Length = _vsnprintf(Buffer, sizeof(Buffer) - 1, Format, ap);
3097 Buffer[Length] = '\0';
3098 va_end(ap);
3099
3100 /* Actually print it */
3102}
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(), KdbpCliMainLoop(), KdbpCmdBackTrace(), KdbpCmdBreakPoint(), KdbpCmdBreakPointList(), KdbpCmdDisassembleX(), KdbpCmdDmesg(), KdbpCmdEnableDisableClearBreakPoint(), KdbpCmdEvalExpression(), KdbpCmdFilter(), KdbpCmdGdtLdtIdt(), KdbpCmdHelp(), KdbpCmdMod(), KdbpCmdPcr(), KdbpCmdProc(), KdbpCmdRegs(), KdbpCmdSet(), KdbpCmdStep(), KdbpCmdThread(), KdbpDoCommand(), KdbpEvaluateExpression(), and KdbpPrintUnicodeString().

◆ KdbpPrintUnicodeString()

VOID KdbpPrintUnicodeString ( _In_ PCUNICODE_STRING  String)

Definition at line 3105 of file kdb_cli.c.

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

Referenced by KdbpCmdMod().

◆ KdbRegisterCliCallback()

BOOLEAN NTAPI KdbRegisterCliCallback ( PVOID  Callback,
BOOLEAN  Deregister 
)

Definition at line 3125 of file kdb_cli.c.

3128{
3129 ULONG i;
3130
3131 /* Loop all entries */
3132 for (i = 0; i < _countof(KdbCliCallbacks); i++)
3133 {
3134 /* Check if deregistering was requested */
3135 if (Deregister)
3136 {
3137 /* Check if this entry is the one that was registered */
3138 if (KdbCliCallbacks[i] == Callback)
3139 {
3140 /* Delete it and report success */
3142 return TRUE;
3143 }
3144 }
3145 else
3146 {
3147 /* Check if this entry is free */
3148 if (KdbCliCallbacks[i] == NULL)
3149 {
3150 /* Set it and and report success */
3152 return TRUE;
3153 }
3154 }
3155 }
3156
3157 /* Unsuccessful */
3158 return FALSE;
3159}
_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 2852 of file kdb_cli.c.

2854{
2855 PCHAR p;
2856 SIZE_T i;
2857 size_t len;
2858
2859 while ((p = strrchr(String, '\x1b'))) /* Look for escape character */
2860 {
2861 len = strlen(p);
2862 if (p[1] == '[')
2863 {
2864 i = 2;
2865 while (!isalpha(p[i++]));
2866 memmove(p, p + i, len + 1 - i);
2867 }
2868 else
2869 {
2870 memmove(p, p + 1, len);
2871 }
2872 }
2873}
#define isalpha(c)
Definition: acclib.h:74
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
_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 2772 of file kdb_cli.c.

2773{
2774 const unsigned char *cp;
2775
2776 if (n != 0)
2777 {
2778 cp = (unsigned char *)s + n;
2779 do
2780 {
2781 if (*(--cp) == (unsigned char)c)
2782 return (void *)cp;
2783 } while (--n != 0);
2784 }
2785 return NULL;
2786}
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 109 of file kdb_cli.c.

110{
111#ifdef _M_IX86
112 return strtoul(nptr, endptr, base);
113#else
114 return strtoull(nptr, endptr, base);
115#endif
116}
#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 345 of file kdb_cli.c.

Referenced by UhciGet32BitFrameNumber().

◆ Help

int Help

Definition at line 344 of file kdb_cli.c.

Referenced by create_system_dirid(), and KdbpCmdHelp().

◆ Id

ULONG Id

Definition at line 159 of file kdb_cli.c.

Referenced by KdbpCmdFilter().

◆ KdbBreakOnModuleLoad

BOOLEAN KdbBreakOnModuleLoad = FALSE
static

Definition at line 129 of file kdb_cli.c.

Referenced by KdbpCmdSet().

◆ KdbCliCallbacks

PKDBG_CLI_ROUTINE KdbCliCallbacks[10]
static

Definition at line 127 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 144 of file kdb_cli.c.

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

◆ KdbInitFileBuffer

PCHAR KdbInitFileBuffer = NULL

Definition at line 136 of file kdb_cli.c.

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

◆ KdbNumberOfColsPrinted

ULONG KdbNumberOfColsPrinted = 0
static

Definition at line 132 of file kdb_cli.c.

Referenced by KdbpCliMainLoop(), and KdbpPagerInternal().

◆ KdbNumberOfRowsPrinted

ULONG KdbNumberOfRowsPrinted = 0
static

Definition at line 131 of file kdb_cli.c.

Referenced by KdbpCliMainLoop(), and KdbpPagerInternal().

◆ KdbOutputAborted

BOOLEAN KdbOutputAborted = FALSE
static

Definition at line 133 of file kdb_cli.c.

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

◆ KdbpBugCheckRequested

BOOLEAN KdbpBugCheckRequested = FALSE

Definition at line 137 of file kdb_cli.c.

Referenced by KdbEnterDebuggerException(), and KdbpCmdBugCheck().

◆ KdbpIsInDmesgMode

volatile BOOLEAN KdbpIsInDmesgMode = FALSE
static

Definition at line 145 of file kdb_cli.c.

Referenced by KdbDebugPrint(), and KdbpCmdDmesg().

◆ KdbPromptStr

◆ KdbRepeatLastCommand

BOOLEAN KdbRepeatLastCommand = FALSE
static

Definition at line 134 of file kdb_cli.c.

Referenced by KdbpCliMainLoop(), and KdbpPagerInternal().

◆ KdbUseIntelSyntax

BOOLEAN KdbUseIntelSyntax = FALSE
static

Definition at line 128 of file kdb_cli.c.

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

◆ KdpDmesgBuffer

PCHAR KdpDmesgBuffer = NULL
static

Definition at line 141 of file kdb_cli.c.

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

◆ KdpDmesgBufferSize

const ULONG KdpDmesgBufferSize = 128 * 1024
static

Definition at line 140 of file kdb_cli.c.

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

◆ KdpDmesgCurrentPosition

volatile ULONG KdpDmesgCurrentPosition = 0
static

Definition at line 142 of file kdb_cli.c.

Referenced by KdbDebugPrint(), and KdbpCmdDmesg().

◆ KdpDmesgFreeBytes

volatile ULONG KdpDmesgFreeBytes = 0
static

Definition at line 143 of file kdb_cli.c.

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

◆ KdpDmesgLogSpinLock

KSPIN_LOCK KdpDmesgLogSpinLock
static

Definition at line 146 of file kdb_cli.c.

Referenced by KdbDebugPrint(), and KdbInitialize().

◆ Name

Definition at line 158 of file kdb_cli.c.

Referenced by KdbpCmdFilter().

◆ Syntax

PCHAR Syntax

Definition at line 343 of file kdb_cli.c.

Referenced by KdbpCmdHelp().