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

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 扩展中的本机调试器对象

另请参阅

将 LINQ 与调试器对象配合使用

NatVis 中的本机调试器对象

JavaScript 扩展中的本机调试器对象