dt(显示类型)

dt 命令显示有关局部变量、全局变量或数据类型的信息。 这可以显示有关简单数据类型以及结构和联合的信息。

User-Mode 语法

dt [-DisplayOpts] [-SearchOpts] [module!]Name [[-SearchOpts] Field] [Address] [-l List] 
dt [-DisplayOpts] Address [-l List] 
dt -h 

Kernel-Mode 语法

[Processor] dt [-DisplayOpts] [-SearchOpts] [module!]Name [[-SearchOpts] Field] [Address] [-l List] 
dt [-DisplayOpts] Address [-l List] 
dt -h 

参数

处理器
指定正在运行包含所需信息的进程的处理器。 有关详细信息,请参阅 多处理器语法。 只能在内核模式下指定处理器。

DisplayOpts
指定下表中给定的一个或多个选项。 这些选项前面有连字符。

选项 说明

-a[quantity]

在新行上显示每个数组元素及其索引。 将显示总 数量 元素。 a数量之间不得有空格。 如果 -a 不后跟数字,则显示数组中的所有项。 -a[quantity] 开关应紧接在希望以这种方式显示的每个类型名称或字段名称之前。

-b

以递归方式显示块。 如果显示的结构包含子结构,则它以递归方式扩展为任意深度并完整显示。 仅当指针位于原始结构中,而不是子结构中时,它们才会展开。

-c

压缩输出。 如果可能,所有字段都显示在一行上。 (当与 -a 开关一起使用时,每个数组元素采用一行,而不是格式化为多行块。)

-d

与以星号结尾 的 Name 一起使用时,显示以 Name 开头的所有类型的详细输出。 如果 Name 未以星号结尾,则显示详细输出。

-e

强制 dt 枚举类型。 仅当 dt 错误地将 Name 值解释为实例而不是类型时,才需要此选项。

-i

不要缩进子类型。

-o

省略结构字段的偏移值。

-p

地址 是物理地址,而不是虚拟地址。

-r[depth]

以递归方式转储子类型字段。 如果给定 深度 ,此递归将在 深度 级别后停止。 深度必须是介于 1 和 9 之间的数字,并且 r深度之间不能有空格。 -r[depth] 开关应紧接在地址前面。

-ssize

仅枚举大小(以字节为单位)等于 size 值的类型。 仅当枚举类型时, -s 选项才有用。 指定 -s 时,始终也隐含 -e

-t

仅枚举类型。

-v

详细输出。 这会提供其他信息,例如结构的总大小及其元素数。 与 -y 搜索选项一起使用时,将显示所有符号,即使是没有关联类型信息的符号。

SearchOpts
指定下表中给定的一个或多个选项。 这些选项前面有连字符。

选项 描述

-n

这表示下一个参数是一个名称。 如果下一个项目完全由十六进制字符组成,则应使用此参数,否则它将作为地址。

-y

这表示下一个参数是名称的开头,不一定是整个名称。 如果包含 -y ,则会列出所有匹配项,后跟列表中第一个匹配项的详细信息。 如果未包含 -y ,则仅显示完全匹配项。

模块
一个可选参数,用于指定定义此结构的模块。 如果有与全局变量或类型同名的局部变量或类型,则应包含 模块 以指定全局变量的意思。 否则, dt 命令将显示局部变量,即使局部变量是不区分大小写的匹配项,并且全局变量是区分大小写的匹配项。

名字
指定类型或全局变量的名称。 如果 Name 以星号 (*) 结尾,将显示所有匹配项的列表。 因此, dt A\* 将列出以“A”开头的所有数据类型、全局和静态,但不会显示这些类型的实际实例。 (如果同时使用 -v 显示选项,将显示所有符号,而不仅仅是具有关联类型信息的符号。) 还可以将 Name 替换为句点 () 表示要重复最近使用的 Name 值。

如果 Name 包含空格,则应将其括在括号中。

领域
指定要显示的字段 () 。 如果省略 Field ,则显示所有字段。 如果 字段 后跟句点 (.) ,则也会显示此字段的第一级子字段。 如果 Field 后跟一系列句点,则子字段将显示为等于句点数的深度。 任何后跟句点的字段名称都将被视为前缀匹配项,就像使用了 -y 搜索选项一样。 如果 Field 后跟星号 (*) ,则它只被视为字段的开头,不一定是整个字段,并且将显示所有匹配的字段。

地址
指定要显示的结构的地址。 如果省略 Name ,则必须包含 Address ,并且必须指定全局变量的地址。 除非另有指定,否则将地址设置为虚拟地址。 使用 -p 选项指定物理地址。 使用“at”符号 ( @ ) 指定寄存器 (,例如 ,@eax) 。

列表
指定链接链接列表的字段名称。 必须包含 Address 参数。

环境

说明
模式 用户模式、内核模式
目标 实时、故障转储
平台 全部

其他信息

有关内存操作的概述和其他内存相关命令的说明,请参阅 读取和写入内存

注解

dt 命令输出将始终以 10 为底数显示有符号数字,以十六进制显示无符号数字。

允许符号值的所有 dt 参数也允许字符串通配符。 有关详细信息,请参阅 字符串通配符语法

-y-n 选项可以位于任何名称字段之前。 使用 -y 选项可以指定类型或结构名称的开头。 例如, dt -y ALLEN 将显示有关 ALLENTOWN 类型的数据。 但是,不能使用 dt -y A 显示类型 ALLENTOWN。相反,必须使用 dt -ny A,因为 A 是有效的十六进制值,并且将被解释为没有 -n 选项的地址。

如果 Name 指示结构,则将显示所有字段 (例如 dt myStruct) 。 如果只需要一个特定字段,可以执行 dt myStruct myField。 这将显示 C 将调用 myStruct.myField 的成员。 但请注意,命令 dt myStruct myField1 myField2 显示 myStruct.myField1myStruct.myField2。 它不显示 myStruct.myField1.myField2

如果结构名称或字段后跟下标,则指定数组的单个实例。 例如, dt myStruct myFieldArray[3] 将显示有问题的数组的第四个元素。 但是,如果类型名称后跟下标,则指定整个数组。 例如, dt CHAR[8] myPtr 将显示一个八个字符的字符串。 无论当前基数如何,下标始终采用小数; 0x 前缀将导致错误。

因为 命令使用 中的类型信息。pdb 文件,它可用于调试任何 CPU 平台。

dt 使用的类型信息包括使用 typedef 创建的所有类型名称,包括所有 Windows 定义的类型。 例如, 无符号 longchar 是无效的类型名称,但 ULONGCHAR 是有效的类型名称。 有关所有 Windows 类型名称的完整列表,请参阅Microsoft Windows SDK。

typedefs 在你自己的代码中创建的所有类型都将存在,只要它们已在程序中实际使用。 但是,在标头中定义但从未实际使用过的类型不会存储在 .pdb 符号文件中,并且调试器无法访问。 若要使此类类型可供调试器使用,请使用它作为 typedef 语句的输入。 例如,如果代码中出现以下内容,则 MY_DATA 结构将存储在 .pdb 符号文件中,并由 dt 命令显示:

typedef struct _MY_DATA {
    . . .
    } MY_DATA;
typedef  MY_DATA *PMY_DATA; 

另一方面,以下代码是不够的,因为MY_DATA和PMY_DATA均由初始 typedef 定义,因此,MY_DATA本身未用作任何 typedef 语句的输入:

typedef struct _MY_DATA {
    . . .
    } MY_DATA, *PMY_DATA; 

在任何情况下,类型信息仅包含在完整的符号文件中,而不是已去除所有私有符号信息的符号文件。 有关详细信息,请参阅 公共符号和专用符号

如果要显示 unicode 字符串,需要首先使用 “.enable_unicode (启用 Unicode 显示) 命令。 可以使用 .enable_long_status (启用长整型显示) 命令来控制 长整型的显示

在以下示例中, dt 显示一个全局变量:

0:000> dt mt1 
   +0x000 a                : 10
   +0x004 b                : 98 'b'
   +0x006 c                : 0xdd
   +0x008 d                : 0xabcd
   +0x00c gn               : [6] 0x1
   +0x024 ex               : 0x0 

在以下示例中, dt 显示数组字段 gn

0:000> dt mt1 -a gn 
   +0x00c gn : 
    [00] 0x1
    [01] 0x2
    [02] 0x3
    [03] 0x4
    [04] 0x5
    [05] 0x6 

以下命令显示变量的某些子字段:

0:000> dt mcl1 m_t1 dpo 
   +0x010 dpo  : DEEP_ONE
   +0x070 m_t1 : MYTYPE1 

以下命令显示字段 m_t1的子字段。 由于句点自动导致前缀匹配,因此还会显示以“m_t1”开头的任何字段的子字段:

0:000> dt mcl1 m_t1. 
   +0x070 m_t1  : 
      +0x000 a     : 0
      +0x004 b     : 0 '
      +0x006 c     : 0x0
      +0x008 d     : 0x0
      +0x00c gn    : [6] 0x0
      +0x024 ex    : 0x0 

可以重复此操作到任何深度。 例如,命令 dt mcl1 a.。c. 将显示所有字段到深度 4,以便第一个字段名称以 a 开头,第三 字段名称以 c 开头。

下面是有关如何显示子字段的更详细示例。 首先,显示 Ldr 字段:

0:000> dt nt!_PEB Ldr 7ffdf000 
   +0x00c Ldr : 0x00191ea0 

现在展开指针类型字段:

0:000> dt nt!_PEB Ldr Ldr. 7ffdf000 
   +0x00c Ldr  : 0x00191ea0
      +0x000 Length : 0x28
      +0x004 Initialized : 0x1 '
      +0x008 SsHandle : (null)
      +0x00c InLoadOrderModuleList : _LIST_ENTRY [ 0x191ee0 - 0x192848 ]
      +0x014 InMemoryOrderModuleList : _LIST_ENTRY [ 0x191ee8 - 0x192850 ]
      +0x01c InInitializationOrderModuleList : _LIST_ENTRY [ 0x191f58 - 0x192858 ]
      +0x024 EntryInProgress : (null) 

现在显示 CriticalSectionTimeout 字段:

0:000> dt nt!_PEB CriticalSectionTimeout 7ffdf000 
   +0x070 CriticalSectionTimeout : _LARGE_INTEGER 0xffffe86d`079b8000 

现在,将 CriticalSectionTimeout 结构子字段展开一个级别:

0:000> dt nt!_PEB CriticalSectionTimeout. 7ffdf000 
   +0x070 CriticalSectionTimeout  :  0xffffe86d`079b8000
      +0x000 LowPart                 : 0x79b8000
      +0x004 HighPart                : -6035
      +0x000 u                       : __unnamed
      +0x000 QuadPart                : -25920000000000 

现在,将 CriticalSectionTimeout 结构子字段展开两个级别:

0:000> dt nt!_PEB CriticalSectionTimeout.. 7ffdf000 
   +0x070 CriticalSectionTimeout   :  0xffffe86d`079b8000
      +0x000 LowPart                  : 0x79b8000
      +0x004 HighPart                 : -6035
      +0x000 u                        :
         +0x000 LowPart                  : 0x79b8000
         +0x004 HighPart                 : -6035
      +0x000 QuadPart                 : -25920000000000 

以下命令显示位于地址0x0100297C的数据类型MYTYPE1实例:

0:000> dt 0x0100297c MYTYPE1 
   +0x000 a                : 22
   +0x004 b                : 43 '+'
   +0x006 c                : 0x0
   +0x008 d                : 0x0
   +0x00c gn               : [6] 0x0
   +0x024 ex               : 0x0 

以下命令在地址0x01002BE0显示包含 10 个 ULONG 的数组:

0:000> dt -ca10 ULONG 01002be0 
[0] 0x1001098
[1] 0x1
[2] 0xdead
[3] 0x7d0
[4] 0x1
[5] 0xcd
[6] 0x0
[7] 0x0
[8] 0x0
[9] 0x0 

以下命令继续在不同地址上显示上一次。 请注意,不需要重新输入“ULONG”:

0:000> dt -ca4 . 01002d00 
Using sym ULONG
[0] 0x12
[1] 0x4ac
[2] 0xbadfeed
[3] 0x2 

下面是一些类型显示的示例。 以下命令显示 此模块中以字符串“MY”开头的所有类型和全局。 以地址为前缀的实例是实际实例;没有地址的为类型定义:

0:000> dt thismodule!MY* 
010029b8  thismodule!myglobal1
01002990  thismodule!myglobal2
          thismodule!MYCLASS1
          thismodule!MYCLASS2
          thismodule!MYCLASS3
          thismodule!MYTYPE3::u
          thismodule!MYTYPE1
          thismodule!MYTYPE3
          thismodule!MYTYPE3
          thismodule!MYFLAGS 

执行类型显示时, -v 选项可用于显示每个项的大小。 -ssize 选项可用于仅枚举特定大小的项。 同样,带地址前缀的实例是实际实例;没有地址的为类型定义:

0:001> dt -s 2 -v thismodule!* 
Enumerating symbols matching thismodule!*, Size = 0x2
Address   Size Symbol
           002 thismodule!wchar_t
           002 thismodule!WORD
           002 thismodule!USHORT
           002 thismodule!SHORT
           002 thismodule!u_short
           002 thismodule!WCHAR
00427a34   002 thismodule!numberOfShips
00427a32   002 thismodule!numberOfPlanes
00427a30   002 thismodule!totalNumberOfItems 

下面是 -b 选项的示例。 结构已展开,结构中的 OwnerThreads 数组已展开,但不遵循 FlinkBlink 列表指针:

kd> dt nt!_ERESOURCE -b 0x8154f040 
   +0x000 SystemResourcesList :  [ 0x815bb388 - 0x816cd478 ]
      +0x000 Flink            : 0x815bb388
      +0x004 Blink            : 0x816cd478
   +0x008 OwnerTable       : (null)
   +0x00c ActiveCount      : 1
   +0x00e Flag             : 8
   +0x010 SharedWaiters    : (null)
   +0x014 ExclusiveWaiters : (null)
   +0x018 OwnerThreads     :
    [00]
      +0x000 OwnerThread      : 0
      +0x004 OwnerCount       : 0
      +0x004 TableSize        : 0
    [01]
      +0x000 OwnerThread      : 0x8167f563
      +0x004 OwnerCount       : 1
      +0x004 TableSize        : 1
   +0x028 ContentionCount  : 0
   +0x02c NumberOfSharedWaiters : 0
   +0x02e NumberOfExclusiveWaiters : 0
   +0x030 Address          : (null)
   +0x030 CreatorBackTraceIndex : 0
   +0x034 SpinLock         : 0

下面是内核模式下 dt 的示例。 以下命令生成的结果类似于 !process 0 0

kd> dt nt!_EPROCESS -l ActiveProcessLinks.Flink -y Ima -yoi Uni 814856f0 
## ActiveProcessLinks.Flink at 0x814856f0

UniqueProcessId : 0x00000008
ImageFileName : [16] "System"

## ActiveProcessLinks.Flink at 0x8138a030

UniqueProcessId : 0x00000084
ImageFileName : [16] "smss.exe"

## ActiveProcessLinks.Flink at 0x81372368

UniqueProcessId : 0x000000a0
ImageFileName : [16] "csrss.exe"

## ActiveProcessLinks.Flink at 0x81369930

UniqueProcessId : 0x000000b4
ImageFileName : [16] "winlogon.exe"

.... 

如果要对列表的每个元素执行命令,请使用 !list 扩展。

最后, dt -h 命令将显示总结 dt 语法的简短帮助文本。