dx(显示调试器对象模型表达式)
dx 命令使用 NatVis 扩展模型显示 C++ 表达式。 有关 NatVis 的更多信息,请参阅创建本机对象的自定义视图。
dx [-g|-gc #][-c #][-n|-v]-r[#] Expression[,<FormatSpecifier> ]
dx [{-?}|{-h}]
参数
Expression
要显示的 C++ 表达式。
-g
显示为可迭代的数据网格对象。 每个迭代元素都是网格中的一行,并且这些元素的每个显示子元素都是一列。 这样可以查看结构数组等内容,其中每个数组元素显示在一行中,结构的每个字段都显示在列中。
选择列名称(其中存在可用的 DML 链接)将按该列进行排序。 如果已按该列排序,排序顺序将倒置。
可迭代的任何对象都将具有通过 DML 添加的选择并按住(或右键单击)上下文菜单项,称为“显示为网格”。 在输出窗口中选择并按住(或右键单击)对象,然后选择此选项,将在网格视图中显示对象,而不是标准树视图。
列名旁显示的 (+) 提供选择并按住(或右键单击)和选择行为。
- 选择该列并将其分解为自己的表。 可以看到原始行加上展开列的子级。
- 选择并按住(或右键单击)提供“扩展到网格”,它将获取该列并将其作为最右边的列添加回当前表。
-gc #
显示为网格,并将网格单元格大小限制为指定数量的 (#) 字符。
-c # 显示容器延续(跳过容器的 #元素)。此选项通常用于自定义输出自动化方案,并提供“...”列表底部的延续元素。
-n 可通过两种方式呈现数据。 使用 NatVis 可视化(默认)或使用底层本地 C/C++ 结构。 指定 -n 参数以仅使用本地 C/C++ 结构而不是 NatVis 可视化效果呈现输出。
-v
显示包含方法和其他非典型对象的详细信息。
-r#
以递归方式显示最高 # 级别的子类型(字段)。 如果未指定 #,则递归级别为默认值。
[<,FormatSpecifier>]
使用以下任何格式说明符来修改默认呈现。
格式说明符 | 说明 |
---|---|
,x | 以十六进制形式显示序号 |
,d | 以十进制为单位显示序号 |
,o | 以八进制为单位显示序号 |
,b | 以二进制形式显示序号 |
,en | 仅按名称显示枚举(无值) |
c, | 显示为单个字符(而不是字符串) |
,s | 以 ASCII 引号的形式显示 8 位字符串 |
,sb | 以 ASCII 不带引号的形式显示 8 位字符串 |
,s8 | 以 UTF-8 引号显示 8 位字符串 |
,s8b | 以 UTF-8 不带引号的形式显示 8 位字符串 |
,su | 以 UTF-16 引号显示 16 位字符串 |
,sub | 以 UTF-16 不带引号的形式显示 16 位字符串 |
,! | 仅以原始模式显示对象(例如无 NatVis) |
,# | 将指针/数组/容器的长度指定为文本值 #(替换为数字) |
,[<表达式>] | 将指针/数组/容器的长度指定为表达式 <expression> |
,nd | 找不到对象的派生 (runtype) 类型。 仅显示静态值 |
dx -?
显示命令行帮助。
dx -h 显示调试器中可用的对象的帮助。
dx -id
仅供 Microsoft 内部使用。 用于跟踪命令输出中的数据模型链接。
命令行用法示例。
.dx settings 命令可用于显示有关 Debug 设置对象的信息。 有关调试设置对象的详细信息,请参阅 .settings。
kd> dx -r1 Debugger.Settings
Debugger.Settings
Debug
Display
EngineInitialization
Extensions
Input
Sources
Symbols
AutoSaveSettings : false
使用 -r1 递归选项查看其他调试器对象 - 会话、设置和状态。
kd> dx -r1 Debugger
Debugger
Sessions
Settings
State
Utility
LastEvent
使用 -r3 递归选项指定 Debugger.Sessions 对象,以进一步向下传输对象链。
kd> dx -r3 Debugger.Sessions
Debugger.Sessions
[0] : Remote KD: KdSrv:Server=@{<Local>},Trans=@{1394:Channel=0}
Processes
[0] : <Unknown Image>
[4] : <Unknown Image>
[304] : smss.exe
[388] : csrss.exe
[456] : wininit.exe
[468] : csrss.exe
[528] : services.exe
[536] : lsass.exe
[544] : winlogon.exe
[620] : svchost.exe
... ...
添加 x 格式说明符以显示十六进制中的序号值。
kd> dx -r3 Debugger.Sessions,x
Debugger.Sessions,x
[0x0] : Remote KD: KdSrv:Server=@{<Local>},Trans=@{1394:Channel=0}
Processes
[0x0] : <Unknown Image>
[0x4] : <Unknown Image>
[0x130] : smss.exe
[0x184] : csrss.exe
[0x1c8] : wininit.exe
[0x1d4] : csrss.exe
[0x210] : services.exe
[0x218] : lsass.exe
[0x220] : winlogon.exe
[0x26c] : svchost.exe
[0x298] : svchost.exe
[0x308] : dwm.exe
[0x34c] : nvvsvc.exe
[0x37c] : nvvsvc.exe
[0x384] : svchost.exe
... ...
此示例使用活动调试会话列出第一个进程中第一个线程的调用堆栈。
kd> dx -r1 Debugger.Sessions.First().Processes.First().Threads.First().Stack.Frames
Debugger.Sessions.First().Processes.First().Threads.First().Stack.Frames
[0x0] : nt!RtlpBreakWithStatusInstruction
[0x1] : nt!KdCheckForDebugBreak + 0x7a006
[0x2] : nt!KiUpdateRunTime + 0x42
[0x3] : nt!KiUpdateTime + 0x129
[0x4] : nt!KeClockInterruptNotify + 0x1c3
[0x5] : hal!HalpTimerClockInterruptEpilogCommon + 0xa
[0x6] : hal!HalpTimerClockInterruptCommon + 0x3e
[0x7] : hal!HalpTimerClockInterrupt + 0x1cb
[0x8] : nt!KiIdleLoop + 0x1a
使用 -g 选项将输出显示为数据网格。 选择要排序的列。
kd> dx -g @$curprocess.Modules
使用 -h 选项显示有关对象的信息。
kd> dx -h Debugger.State
Debugger.State [State pertaining to the current execution of the debugger (e.g.: user variables)]
DebuggerVariables [Debugger variables which are owned by the debugger and can be referenced by a pseudo-register prefix of @$]
PseudoRegisters [Categorized debugger managed pseudo-registers which can be referenced by a pseudo-register prefix of @$]
UserVariables [User variables which are maintained by the debugger and can be referenced by a pseudo-register prefix of @$]
使用 Environment 对象显示 TEB 和 PEB 信息
使用 Environment 对象显示与线程和进程关联的 TEB 和 PEB 信息。
若要显示与当前线程关联的 TEB,请使用此命令。
0: kd> dx -r2 @$curthread.Environment
@$curthread.Environment
EnvironmentBlock [Type: _TEB]
[+0x000] NtTib [Type: _NT_TIB]
[+0x038] EnvironmentPointer : Unable to read memory at Address 0x38
[+0x040] ClientId [Type: _CLIENT_ID]
[+0x050] ActiveRpcHandle : Unable to read memory at Address 0x50
[+0x058] ThreadLocalStoragePointer : Unable to read memory at Address 0x58
[+0x060] ProcessEnvironmentBlock : Unable to read memory at Address 0x60
[+0x068] LastErrorValue : Unable to read memory at Address 0x68
[+0x06c] CountOfOwnedCriticalSections : Unable to read memory at Address 0x6c
[+0x070] CsrClientThread : Unable to read memory at Address 0x70
[+0x078] Win32ThreadInfo : Unable to read memory at Address 0x78
[+0x080] User32Reserved [Type: unsigned long [26]]
[+0x0e8] UserReserved [Type: unsigned long [5]]
[+0x100] WOW32Reserved : Unable to read memory at Address 0x100
[+0x108] CurrentLocale : Unable to read memory at Address 0x108
[+0x10c] FpSoftwareStatusRegister : Unable to read memory at Address 0x10c
...
若要显示与当前进程关联的 PEB,请使用此命令。
0: kd> dx -r2 @$curprocess.Environment
@$curprocess.Environment
EnvironmentBlock [Type: _PEB]
[+0x000] InheritedAddressSpace : Unable to read memory at Address 0x0
[+0x001] ReadImageFileExecOptions : Unable to read memory at Address 0x1
[+0x002] BeingDebugged : Unable to read memory at Address 0x2
[+0x003] BitField : Unable to read memory at Address 0x3
[+0x003 ( 0: 0)] ImageUsesLargePages : Unable to read memory at Address 0x3
[+0x003 ( 1: 1)] IsProtectedProcess : Unable to read memory at Address 0x3
[+0x003 ( 2: 2)] IsImageDynamicallyRelocated : Unable to read memory at Address 0x3
[+0x003 ( 3: 3)] SkipPatchingUser32Forwarders : Unable to read memory at Address 0x3
[+0x003 ( 4: 4)] IsPackagedProcess : Unable to read memory at Address 0x3
[+0x003 ( 5: 5)] IsAppContainer : Unable to read memory at Address 0x3
[+0x003 ( 6: 6)] IsProtectedProcessLight : Unable to read memory at Address 0x3
[+0x003 ( 7: 7)] IsLongPathAwareProcess : Unable to read memory at Address 0x3
[+0x004] Padding0 [Type: unsigned char [4]]
[+0x008] Mutant : Unable to read memory at Address 0x8
[+0x010] ImageBaseAddress : Unable to read memory at Address 0x10
[+0x018] Ldr : Unable to read memory at Address 0x18
[+0x020] ProcessParameters : Unable to read memory at Address 0x20
...
Kernel Io.Handles 对象
使用当前进程 Io.Handles 对象显示内核句柄信息。
0: kd> dx -r1 @$curprocess.Io.Handles
@$curprocess.Io.Handles
[0x8]
[0xc]
[0x10]
[0x14]
[0x18]
...
使用 .First() 函数,用于显示有关第一个句柄的信息。
0: kd> dx -r2 @$curprocess.Io.Handles.First()
@$curprocess.Io.Handles.First()
Handle : 0x8
Type : Unexpected failure to dereference object
GrantedAccess : Unexpected failure to dereference object
Object [Type: _OBJECT_HEADER]
[+0x000] PointerCount : 228806 [Type: __int64]
[+0x008] HandleCount : 6 [Type: __int64]
[+0x008] NextToFree : 0x6 [Type: void *]
[+0x010] Lock [Type: _EX_PUSH_LOCK]
[+0x018] TypeIndex : 0xf2 [Type: unsigned char]
[+0x019] TraceFlags : 0x0 [Type: unsigned char]
[+0x019 ( 0: 0)] DbgRefTrace : 0x0 [Type: unsigned char]
[+0x019 ( 1: 1)] DbgTracePermanent : 0x0 [Type: unsigned char]
[+0x01a] InfoMask : 0x0 [Type: unsigned char]
[+0x01b] Flags : 0x2 [Type: unsigned char]
[+0x01b ( 0: 0)] NewObject : 0x0 [Type: unsigned char]
[+0x01b ( 1: 1)] KernelObject : 0x1 [Type: unsigned char]
[+0x01b ( 2: 2)] KernelOnlyAccess : 0x0 [Type: unsigned char]
[+0x01b ( 3: 3)] ExclusiveObject : 0x0 [Type: unsigned char]
[+0x01b ( 4: 4)] PermanentObject : 0x0 [Type: unsigned char]
[+0x01b ( 5: 5)] DefaultSecurityQuota : 0x0 [Type: unsigned char]
[+0x01b ( 6: 6)] SingleHandleEntry : 0x0 [Type: unsigned char]
[+0x01b ( 7: 7)] DeletedInline : 0x0 [Type: unsigned char]
[+0x01c] Reserved : 0x0 [Type: unsigned long]
[+0x020] ObjectCreateInfo : 0xfffff801f6d9c6c0 [Type: _OBJECT_CREATE_INFORMATION *]
[+0x020] QuotaBlockCharged : 0xfffff801f6d9c6c0 [Type: void *]
[+0x028] SecurityDescriptor : 0xffffb984aa815d06 [Type: void *]
[+0x030] Body [Type: _QUAD]
ObjectType : Unexpected failure to dereference object
UnderlyingObject : Unexpected failure to dereference object
请注意,Io.Handles 对象是仅内核对象。
使用强制转换来解决符号文件限制
显示有关各种 Windows 系统变量的信息时,有时公共符号中不提供所有类型信息。 此示例说明了这种情况。
0: kd> dx nt!PsIdleProcess
Error: No type (or void) for object at Address 0xfffff800e1d50128
dx 命令支持引用没有类型信息的变量的地址。 这种 “address of ”引用被视为 “void *”,并可被当作 “void *”引用。 这意味着,如果数据类型已知,可以使用以下语法显示变量的类型信息。
dx (Datatype *)&VariableName
例如,对于数据类型为 nt!_EPROCESS 的 nt!PsIdleProcess,请使用此命令。
dx (nt!_EPROCESS *)&nt!PsIdleProcess
(nt!_EPROCESS *)&nt!PsIdleProcess : 0xfffff800e1d50128 [Type: _EPROCESS *]
[+0x000] Pcb [Type: _KPROCESS]
[+0x2c8] ProcessLock [Type: _EX_PUSH_LOCK]
[+0x2d0] CreateTime : {4160749568} [Type: _LARGE_INTEGER]
[+0x2d8] RundownProtect [Type: _EX_RUNDOWN_REF]
[+0x2e0] UniqueProcessId : 0x1000 [Type: void *]
[+0x2e8] ActiveProcessLinks [Type: _LIST_ENTRY]
[+0x2f8] Flags2 : 0x218230 [Type: unsigned long]
[+0x2f8 ( 0: 0)] JobNotReallyActive : 0x0 [Type: unsigned long]
dx 命令不支持使用 @@ MASM 语法切换表达式计算器。 有关表达式计算器的详细信息,请参阅计算表达式。
将 LINQ 与调试器对象配合使用
LINQ 语法可与调试器对象一起使用,以搜索和操作数据。 LINQ 在概念上类似于用于查询数据库的结构化查询语言 (SQL)。 您可以使用许多 LINQ 方法搜索、过滤和分析调试数据。 有关将 LINQ 与调试器对象一起使用的信息,请参阅 将 LINQ 与调试器对象结合使用。
将调试器对象与 NatVis 和 JavaScript 配合使用
有关将调试器对象与 NatVis 结合使用的信息,请参阅 NatVis 中的本机调试器对象。
有关将调试器对象与 JavaScript 结合使用的信息,请参阅 JavaScript 扩展中的本机调试器对象。