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[количество]

Отображение каждого элемента массива в новой строке с его индексом. Отобразится общее количество элементов. Между иколичеством не должно быть пробела. Если за параметром -a не следует цифра, отображаются все элементы в массиве. Параметр -a[quantity] должен отображаться непосредственно перед каждым именем типа или именем поля, которые вы хотите отобразить таким образом.

-b

Рекурсивное отображение блоков. Если отображаемая структура содержит подструктуры, она рекурсивно разворачивается до произвольных глубин и отображается полностью. Указатели развертываются, только если они находятся в исходной структуре, а не в подструктурах.

-c

Компактные выходные данные. Все поля отображаются в одной строке, если это возможно. (При использовании с параметром -a каждый элемент массива принимает одну строку, а не форматируется как блок из нескольких строк.)

-d

При использовании с именем, заканчивающимся звездочкой, отображаются подробные выходные данные для всех типов, начинающихся с Name. Если имя не заканчивается звездочкой, отобразятся подробные выходные данные.

-e

Заставляет dt перечислять типы. Этот параметр необходим только в том случае, если dt ошибочно интерпретирует значение Name как экземпляр, а не как тип.

-i

Не отступы для подтипов.

-o

Опустить значения смещения полей структуры.

-p

Адрес — это физический, а не виртуальный адрес.

-r[глубина]

Рекурсивно создает дамп полей подтипа. Если задана глубина , эта рекурсия остановится после уровней глубины . Глубина должна быть цифрой от 1 до 9, а между r и глубиной не должно быть пробела. Параметр -r[depth] должен появиться непосредственно перед адресом.

-ssize

Перечислять только те типы, размер которых в байтах равен значению размера. Параметр -s полезен только при перечислении типов. При указании параметра -s всегда подразумевается и параметр -e .

-t

Перечисление только типов.

-v

Подробные выходные данные. Это дает дополнительные сведения, такие как общий размер структуры и количество ее элементов. Если этот параметр используется вместе с параметром поиска -y , отображаются все символы, даже не имеющие связанных сведений о типе.

SearchOpts
Задает один или несколько параметров, указанных в следующей таблице. Перед этими параметрами стоит дефис.

Параметр Описание

-n

Это означает, что следующим параметром является имя. Это следует использовать, если следующий элемент состоит полностью из шестнадцатеричных символов, так как в противном случае он будет приниматься как адрес.

-Y

Это означает, что следующий параметр является началом имени, а не всем именем. При включении -y отображаются все совпадения, за которыми следуют подробные сведения о первом совпадении в списке. Если параметр -y не включен, будут отображаться только точные совпадения.

Модуль
Необязательный параметр, указывающий модуль, определяющий эту структуру. Если имеется локальная переменная или тип с тем же именем, что и глобальная переменная или тип, необходимо включить модуль , чтобы указать, что имеется в виду глобальная переменная. В противном случае команда dt отобразит локальную переменную, даже если локальная переменная не учитывает регистр, а глобальная переменная — совпадение с учетом регистра.

Имя
Указывает имя типа или глобальной переменной. Если имя заканчивается звездочкой (*), отображается список всех совпадений. Таким образом, dt A\* выводит список всех типов данных, глобальных и статических данных, начиная с "A", но не отображает фактические экземпляры этих типов. (Если параметр отображения -v используется одновременно, будут отображаться все символы, а не только символы со связанными сведениями о типе.) Вы также можете заменить Name точкой (.), чтобы означать, что вы хотите повторить последнее использованное значение Name.

Если Name содержит пробел, он должен быть заключен в круглые скобки.

Поле
Указывает отображаемые поля. Если поле опущено, отображаются все поля. Если за полем следует точка (.), также будут отображаться подполя первого уровня этого поля. Если за полем следует ряд периодов, подполям будет отображаться глубина, равная количеству периодов. Любое имя поля, за которым следует точка, будет рассматриваться как совпадение префикса, как если бы использовался параметр поиска -y . Если за полем следует звездочка (*), она обрабатывается только как начало поля, не обязательно все поле, и отображаются все соответствующие поля.

Адрес
Указывает адрес отображаемой структуры. Если параметр Name не указан, необходимо включить параметр Address и указать адрес глобальной переменной. Если не указано иное, адрес принимается как виртуальный. Используйте параметр -p , чтобы указать физический адрес. Используйте знак "at" ( @ ), чтобы указать регистр (например, @eax).

Список
Указывает имя поля, которое связывает связанный список. Необходимо включить параметр Address .

Среда

Элемент Описание
Режимы Пользовательский режим, режим ядра
Цели Динамический аварийный дамп
Платформы Все

Дополнительные сведения

Обзор операций с памятью и описание других команд, связанных с памятью, см. в разделе Чтение и запись памяти.

Комментарии

В выходных данных команды dt всегда будут отображаться цифры со знаком в формате base 10, а неподписанные — в шестнадцатеричном формате.

Все параметры dt , разрешающие значения символов, также разрешают использование строковых подстановочных знаков. Дополнительные сведения см. в разделе Синтаксис строковых подстановочных знаков .

Параметры -y и -n могут предшествовать любому имени или поля. Параметр -y позволяет указать начало типа или имени структуры. Например, dt -y ALLEN отобразит данные о типе ALLENTOWN. Однако не удалось отобразить тип ALLENTOWN с dt -y A. Вместо этого необходимо использовать dt -ny A, так как A является допустимым шестнадцатеричным значением и будет интерпретироваться как адрес без параметра -n .

Если name указывает структуру, будут отображаться все поля (например, dt myStruct). Если требуется только одно определенное поле, можно выполнить dt myStruct myField. Отобразится элемент, который C вызовет myStruct.myField. Однако обратите внимание, что команда dt myStruct myField1 myField2 отображает myStruct.myField1 и myStruct.myField2. В нем не отображается myStruct.myField1.myField2.

Если за именем или полем структуры следует подстрочный индекс, это указывает один экземпляр массива. Например, dt myStruct myFieldArray[3] отобразит четвертый элемент рассматриваемого массива. Но если за именем типа следует подстрочный индекс, это указывает весь массив. Например, dt CHAR[8] myPtr отображает строку из восьми символов. Подстрочный индекс всегда принимается как десятичный, независимо от текущего радикса; префикс 0x приведет к ошибке.

Так как команда использует сведения о типе из . PDB-файл , его можно свободно использовать для отладки любой платформы ЦП.

Сведения о типах, используемые dt, включают все имена типов, созданные с помощью typedef, включая все типы, определенные Windows. Например, unsigned long и char не являются допустимыми именами типов, а ULONG и CHAR являются. Полный список всех имен типов 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; 

В любом случае сведения о типе включаются только в полный файл символов, а не в файл символов, который был лишен всех частных сведений о символах. Дополнительные сведения см. в разделе Общедоступные и закрытые символы.

Если вы хотите отобразить строки Юникода, сначала необходимо использовать команду .enable_unicode (Включить отображение Юникода). Вы можете управлять отображением длинных целых чисел с помощью команды .enable_long_status (Enable Long Integer Display).

В следующем примере 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. будет отображать все поля с глубиной четыре, чтобы имя первого поля начиналось с , а третье имя поля начиналось с 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 

Следующая команда отображает экземпляр типа данных MYTYPE1, расположенный по адресу 0x0100297C:

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

Следующая команда отображает массив из 10 ULONG по адресу 0x01002BE0:

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 в модуле thismodule. Те, которые имеют префикс с адресом, являются фактическими экземплярами; Те, которые не имеют адресов, являются определениями типов:

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 в структуре, но указатели списков Flink и Blink не отслеживаются:

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 .