Partager via


dt (Type d’affichage)

La commande dt affiche des informations sur une variable locale, une variable globale ou un type de données. Cela peut afficher des informations sur les types de données simples, ainsi que sur les structures et les unions.

Syntaxe du mode utilisateur

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

Syntaxe du mode noyau

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

Paramètres

Processeur
Spécifie le processeur qui exécute le processus contenant les informations nécessaires. Pour plus d’informations, consultez Syntaxe multiprocesseur. Les processeurs ne peuvent être spécifiés qu’en mode noyau.

DisplayOpts
Spécifie une ou plusieurs des options indiquées dans le tableau suivant. Ces options sont précédées d’un trait d’union.

Option Description

-a[quantity]

Affichez chaque élément de tableau sur une nouvelle ligne, avec son index. Un total d’éléments de quantité s’affiche. Il ne doit pas y avoir d’espace entre l’a et la quantité. Si -a n’est pas suivi d’un chiffre, tous les éléments du tableau sont affichés. Le commutateur -a[quantity] doit apparaître immédiatement avant chaque nom de type ou nom de champ que vous souhaitez afficher de cette façon.

-b

Blocs d’affichage récursifs. Si une structure affichée contient des sous-structures, elle est développée de manière récursive à des profondeurs arbitraires et affichée en intégralité. Les pointeurs sont développés uniquement s’ils se trouvent dans la structure d’origine, et non dans les sous-structures.

-c

Sortie compacte. Tous les champs sont affichés sur une ligne, si possible. (Lorsqu’il est utilisé avec le commutateur -a , chaque élément de tableau prend une ligne plutôt que d’être mis en forme en tant que bloc à plusieurs lignes.)

-d

Lorsqu’il est utilisé avec un nom terminé par un astérisque, affichez une sortie détaillée pour tous les types commençant par Name. Si Name ne se termine pas par un astérisque, affichez une sortie détaillée.

-e

Force dt à énumérer les types. Cette option n’est nécessaire que si dt interprète par erreur la valeur Name en tant qu’instance plutôt que comme type.

-i

Ne mettez pas en retrait les sous-types.

-o

Omettez les valeurs de décalage des champs de structure.

-p

L’adresse est une adresse physique, plutôt qu’une adresse virtuelle.

-r[profondeur]

Vide de manière récursive les champs de sous-type. Si la profondeur est donnée, cette récursivité s’arrête après les niveaux de profondeur . La profondeur doit être un chiffre compris entre 1 et 9, et il ne doit pas y avoir d’espace entre le r et la profondeur. Le commutateur -r[depth] doit apparaître immédiatement avant l’adresse.

-s size

Énumérez uniquement les types dont la taille en octets est égale à la valeur de taille. L’option -s est utile uniquement lorsque les types sont énumérés. Lorsque -s est spécifié, -e est toujours implicite.

-t

Énumérer uniquement les types.

-v

Sortie détaillée. Cela fournit des informations supplémentaires telles que la taille totale d’une structure et le nombre de ses éléments. Lorsque cela est utilisé avec l’option de recherche -y , tous les symboles sont affichés, même ceux sans informations de type associées.

SearchOpts
Spécifie une ou plusieurs des options indiquées dans le tableau suivant. Ces options sont précédées d’un trait d’union.

Option Description

-n

Cela indique que le paramètre suivant est un nom. Cela doit être utilisé si l’élément suivant se compose entièrement de caractères hexadécimaux, car il sera autrement pris en tant qu’adresse.

-y

Cela indique que le paramètre suivant est le début du nom, pas nécessairement le nom entier. Lorsque -y est inclus, toutes les correspondances sont répertoriées, suivies d’informations détaillées sur la première correspondance de la liste. Si -y n’est pas inclus, seules les correspondances exactes sont affichées.

module
Paramètre facultatif spécifiant le module qui définit cette structure. S’il existe une variable locale ou un type portant le même nom qu’une variable globale ou un type, vous devez inclure le module pour spécifier que vous entendez la variable globale. Sinon, la commande dt affiche la variable locale, même si la variable locale est une correspondance sans respect de la casse et que la variable globale est une correspondance sensible à la casse.

Nom
Spécifie le nom d’un type ou d’une variable globale. Si Name se termine par un astérisque (*), une liste de toutes les correspondances s’affiche. Par conséquent, dt A\* répertorie tous les types de données, globals et statiques commençant par « A », mais n’affiche pas les instances réelles de ces types. (Si l’option d’affichage -v est utilisée en même temps, tous les symboles sont affichés , et non seulement ceux avec les informations de type associées.) Vous pouvez également remplacer Le nom par un point (.) pour indiquer que vous souhaitez répéter la valeur la plus récemment utilisée de Name.

Si Name contient un espace, il doit être placé entre parenthèses.

Champ
Spécifie le ou les champs à afficher. Si le champ est omis, tous les champs sont affichés. Si le champ est suivi d’une période (.), les sous-champs de premier niveau de ce champ sont également affichés. Si Le champ est suivi d’une série de périodes, les sous-champs sont affichés à une profondeur égale au nombre de périodes. Tout nom de champ suivi d’une période sera traité comme une correspondance de préfixe, comme si l’option de recherche -y a a été utilisée. Si le champ est suivi d’un astérisque (*), il est traité comme uniquement le début du champ, pas nécessairement l’ensemble du champ, et tous les champs correspondants sont affichés.

Adresse
Spécifie l’adresse de la structure à afficher. Si le nom est omis, l’adresse doit être incluse et doit spécifier l’adresse d’une variable globale. L’adresse est considérée comme une adresse virtuelle, sauf indication contraire. Utilisez l’option -p pour spécifier une adresse physique. Utilisez un signe « at » ( @ ) pour spécifier un registre (par exemple, @eax).

Liste
Spécifie le nom du champ qui lie une liste liée. Le paramètre Address doit être inclus.

Environnement

Élément Description
Modes Mode utilisateur, mode noyau
Targets Live, vidage de la mémoire
Platforms Tous

Informations supplémentaires

Pour obtenir une vue d’ensemble de la manipulation de la mémoire et une description d’autres commandes liées à la mémoire, consultez Lecture et écriture de données dans la mémoire.

Notes

La sortie de la commande dt affiche toujours les numéros signés dans la base 10 et les nombres non signés en hexadécimal.

Tous les paramètres dt qui autorisent les valeurs de symboles autorisent également les caractères génériques de chaîne. Pour plus d’informations, consultez la syntaxe de caractère générique de chaîne.

Les options -y et -n peuvent précéder n’importe quel nom ou champ. L’option -y vous permet de spécifier le début du nom de type ou de structure. Par exemple, dt -y ALLEN affiche des données sur le type ALLENTOWN. Toutefois, vous n’avez pas pu afficher le type ALLENTOWN avec dt -y A. Au lieu de cela, vous devrez utiliser dt -ny A, car A est une valeur hexadécimale valide et serait interprétée comme une adresse sans l’option -n .

Si Name indique une structure, tous les champs sont affichés (par exemple, dt myStruct). Si vous ne souhaitez qu’un seul champ spécifique, vous pouvez effectuer dt myStruct myField. Cela affiche le membre que C appelle myStruct.myField. Toutefois, notez que la commande dt myStruct myField1 myField2 affiche myStruct.myField1 et myStruct.myField2. Il n’affiche pas myStruct.myField1.myField2.

Si un nom de structure ou un champ est suivi d’un indice, cela spécifie une instance unique d’un tableau. Par exemple, dt myStruct myFieldArray[3] affiche le quatrième élément du tableau en question. Toutefois, si un nom de type est suivi d’un indice, cela spécifie un tableau entier. Par exemple, dt CHAR[8] myPtr affiche une chaîne à huit caractères. L’indice est toujours pris comme décimal, quel que soit le radix actuel ; un préfixe 0x génère une erreur.

Étant donné que la commande utilise des informations de type à partir du .Fichier pdb , il peut être utilisé librement pour déboguer n’importe quelle plateforme d’UC.

Les informations de type utilisées par dt incluent tous les noms de types créés avec typedef, y compris tous les types définis par Windows. Par exemple, les caractères longs non signés ne sont pas des noms de types valides, mais ULONG et CHAR. Consultez le Kit de développement logiciel (SDK) Microsoft Windows pour obtenir la liste complète de tous les noms de types Windows.

Tous les types créés par typedefs au sein de votre propre code seront présents , tant qu’ils ont réellement été utilisés dans votre programme. Toutefois, les types définis dans vos en-têtes mais qui ne sont jamais réellement utilisés ne seront pas stockés dans les fichiers de symboles .pdb et ne seront pas accessibles au débogueur. Pour rendre ce type disponible pour le débogueur, utilisez-le comme entrée d’une instruction typedef . Par exemple, si les éléments suivants s’affichent dans votre code, la structure MY_DATA sera stockée dans le fichier de symboles .pdb et peut être affichée par la commande dt :

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

En revanche, le code suivant ne suffirait pas, car les deux MY_DATA et PMY_DATA sont définis par le typedef initial et, par conséquent, MY_DATA n’a pas été utilisé comme entrée d’une instruction typedef :

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

Dans tous les cas, les informations de type sont incluses uniquement dans un fichier de symboles complet, et non dans un fichier de symboles qui a été supprimé de toutes les informations de symbole privé. Pour en savoir plus, consulter Symboles publics et privés.

Si vous souhaitez afficher des chaînes Unicode, vous devez d’abord utiliser la commande .enable_unicode (Activer l’affichage Unicode). Vous pouvez contrôler l’affichage des entiers longs avec la commande .enable_long_status (Activer l’affichage des entiers longs).

Dans l’exemple suivant, dt affiche une variable globale :

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

Dans l’exemple suivant, dt affiche le champ de tableau gn :

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

La commande suivante affiche certains sous-champs d’une variable :

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

La commande suivante affiche les sous-champs du champ m_t1. Étant donné que la période provoque automatiquement la correspondance des préfixes, cela affiche également les sous-champs de n’importe quel champ commençant par « 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 

Vous pouvez répéter cela à n’importe quelle profondeur. Par exemple, la commande dt mcl1 a.. c. affiche tous les champs à profondeur quatre, de sorte que le premier nom de champ a commencé par un et le troisième nom de champ a commencé avec c.

Voici un exemple plus détaillé de la façon dont les sous-champs peuvent être affichés. Tout d’abord, affichez le champ Ldr :

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

Développez maintenant le champ de type de pointeur :

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) 

Affichez maintenant le champ CriticalSectionTimeout :

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

Développez maintenant les sous-champs de structure CriticalSectionTimeout à un niveau profond :

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

Développez maintenant les sous-champs de structure CriticalSectionTimeout à deux niveaux :

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 

La commande suivante affiche une instance du type de données MYTYPE1 située à l’adresse 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 

La commande suivante affiche un tableau de 10 ULONG à l’adresse 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 

La commande suivante poursuit l’affichage précédent à une autre adresse. Notez que « ULONG » n’a pas besoin d’être entré à nouveau :

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

Voici quelques exemples d’affichage de type. La commande suivante affiche tous les types et globals commençant par la chaîne « MY » dans le module thismodule. Ceux préfixés avec une adresse sont des instances réelles ; ces sans adresses sont des définitions de type :

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 

Lorsque vous effectuez un affichage de type, l’option -v peut être utilisée pour afficher la taille de chaque élément. L’option -s size peut être utilisée pour énumérer uniquement les éléments d’une taille spécifique. Là encore, les préfixes avec une adresse sont des instances réelles ; ces sans adresses sont des définitions de type :

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 

Voici un exemple de l’option -b . La structure est développée et le tableau OwnerThreads au sein de la structure est développé, mais les pointeurs de liste Flink et Blink ne sont pas suivis :

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

Voici un exemple de dt en mode noyau. La commande suivante génère des résultats similaires à !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"

.... 

Si vous souhaitez exécuter une commande pour chaque élément de la liste, utilisez l’extension !list .

Enfin, la commande dt -h affiche un texte d’aide court récapitunant la syntaxe dt .