DTrace sur Windows

DTrace (DTrace.exe) est un outil en ligne de commande qui affiche des événements et des informations système. DTrace est une plateforme de suivi open source portée sur Windows. DTrace a été initialement développé pour le système d'exploitation Solaris. Il fournit une instrumentation dynamique des fonctions utilisateur/noyau, la possibilité de générer un script en langage D et des fonctionnalités de suivi spéculatif. En outre, DTrace dispose d'extensions spécifiques au système d'exploitation Windows, telles que l'instrumentation ETW, la génération d'événements ETW, les sondes d'appel système et les fonctionnalités de capture de live dump.

Remarque

DTrace est pris en charge dans les builds Insider de Windows après la version 18980 et Windows Server Build 18975.

Voici l'emplacement du site GitHub de DTrace sur Windows :

https://github.com/microsoft/DTrace-on-Windows

Ouvrir les informations sur DTrace

Pour plus d’informations sur DTrace, consultez la version 1.0 de la spécification OpenDTrace à l’Université de Cambridge.

Le site GitHub principal se trouve à l’adresse https://github.com/opendtrace/.

Un ensemble de scripts utiles est disponible à l’adresse https://github.com/opendtrace/toolkit.

Différents livres sur DTrace sont disponibles. En voici quelques-uns :

DTrace: Dynamic Tracing in Oracle Solaris, Mac OS X and FreeBSD par Brendan Gregg et Jim Mauro

Solaris Performance and Tools: DTrace and MDB Techniques for Solaris 10 and OpenSolaris par Richard McDougall, Jim Mauro et Brendan Gregg

Envoi de commentaires sur Windows DTrace

Utilisez le hub de commentaires pour demander de nouvelles fonctionnalités ou signaler tout problème ou bogue avec Windows DTrace.

  1. Lancez le hub de commentaires. Accédez à la recherche, saisissez le mot feedback (commentaires), puis sélectionnez Feedback Hub (Hub de commentaires).
  2. Sélectionnez Suggest a feature (Suggérer une fonctionnalité) ou Report a problem (Signaler un problème).
  3. Fournissez une description détaillée et spécifique du problème ou de la suggestion.

Extensions DTrace pour Windows

Voici quelques-uns des fournisseurs disponibles sur Windows et ce qu’ils instrumentent.

  • syscall – Appels système NTOS

  • fbt (suivi des limites de fonction) – Entrées et retours de la fonction noyau

  • pid (ID de processus) – Suivi des processus en mode utilisateur (comme le FBT en mode noyau, mais permettant également l'instrumentation de décalages de fonctions arbitraires)

  • etw (suivi d’événements pour Windows) – Permet aux sondes d’être définies pour ETW (ce fournisseur permet de tirer parti de l’instrumentation existante du système d’exploitation dans DTrace)

SYSCALL

SYSCALL fournit une paire de sondes pour chaque appel système : une sonde d'entrée qui se déclenche avant l'entrée de l'appel système, et une sonde de retour qui se déclenche après la fin de l'appel système, mais avant que le contrôle ne revienne au niveau de l'utilisateur. Pour toutes les sondes SYSCALL, le nom de la fonction est défini comme étant le nom de l'appel système instrumenté, et le nom du module est le module dans lequel la fonction existe. Pour connaître les noms des appels système tels qu'ils sont fournis par le fournisseur SYSCALL, vous pouvez saisir la commande dtrace.exe -l -P syscall à partir de l’invite de commandes. Notez que le nom de la sonde est syscall (en minuscules). La commande dtrace -ln syscall::: répertorie également toutes les sondes et leurs paramètres disponibles auprès du fournisseur syscall.

C:\> dtrace -ln syscall:::
  ID   PROVIDER            MODULE                          FUNCTION NAME
    6    syscall                                 NtWaitHighEventPair entry
    7    syscall                                 NtWaitHighEventPair return
    8    syscall                       NtRegisterThreadTerminatePort entry
    9    syscall                       NtRegisterThreadTerminatePort return
...

Notez que ces exemples n'affichent pas toutes les sorties écran. « … » représente la sortie tronquée.

Pour faire défiler la sortie, dirigez la sortie vers la commande more, comme suit :

dtrace -ln syscall:::|more

Ajoutez l'option v pour afficher plus d'informations sur les sondes syscall disponibles.

C:\> dtrace -lvn syscall:::
...

  942    syscall                                    NtSaveMergedKeys entry

        Probe Description Attributes
                Identifier Names: Private
                Data Semantics:   Private
                Dependency Class: ISA

        Argument Attributes
                Identifier Names: Private
                Data Semantics:   Private
                Dependency Class: ISA

        Argument Types
                args[0]: HANDLE
                args[1]: HANDLE
                args[2]: HANDLE
...

ETW

DTrace prend en charge les sondes ETW manifestées/tracées existantes. Vous pouvez instrumenter, filtrer et analyser les événements ETW de manière synchrone au moment de leur déclenchement. En outre, DTrace peut servir à combiner divers événements/états du système afin de fournir un flux de sortie consolidé pour aider à déboguer des situations d'erreur complexes.

La commande dtrace -ln etw::: répertorie toutes les sondes et leurs paramètres disponibles auprès du fournisseur syscall.

  C:\> dtrace -ln etw:::
  ID   PROVIDER            MODULE                          FUNCTION NAME
  944        etw 048dc470-37c1-52a8-565a-54cb27be37ec           0xff_0xffffffffffffffff generic_event
  945        etw aab97afe-deaf-5882-1e3b-d7210f059dc1           0xff_0xffffffffffffffff generic_event
  946        etw b0f40491-9ea6-5fd5-ccb1-0ec63be8b674           0xff_0xffffffffffffffff generic_event
  947        etw 4ee869fa-9954-4b90-9a62-308c74f99d32           0xff_0xffffffffffffffff generic_event
  ...

Pour plus d’informations, consultez DTrace ETW.

FBT (suivi des limites de fonction)

Le fournisseur FBT (suivi des limites de fonction) propose des sondes associées à l’entrée et au retour de la plupart des fonctions dans le noyau Windows. La fonction est l’unité fondamentale du texte de programme. Comme les autres fournisseurs de DTrace, FBT n'a pas d'effet de sonde lorsqu'il n'est pas explicitement activé. Lorsqu'il est activé, le FBT n'induit qu'un effet de sonde dans les fonctions sondées. Le FBT a été implémenté sur les plateformes x86 et x64.

Pour chaque jeu d'instructions, il existe un petit nombre de fonctions qui n'appellent pas d'autres fonctions et qui sont hautement optimisées par le compilateur (les fonctions terminales) qui ne peuvent pas être instrumentées par le FBT. Les sondes associées à ces fonctions ne sont pas présentes dans DTrace.

La commande dtrace -ln fbt:nt:: répertorie toutes les sondes et leurs paramètres disponibles pour le module nt. Utilisez la commande lm (Lister les modules chargés) du débogueur pour répertorier tous les modules disponibles.

C:\>dtrace -ln "fbt:nt::"
   ID   PROVIDER            MODULE                          FUNCTION NAME
 3336        fbt                nt                PiDqActionDataFree entry
 3337        fbt                nt                PiDqActionDataFree return
 3338        fbt                nt PiDqActionDataGetRequestedProperties entry
 3339        fbt                nt PiDqActionDataGetRequestedProperties return
 3340        fbt                nt _CmGetMatchingFilteredDeviceInterfaceList entry
...

Remarque

Comme il existe des milliers d'appels disponibles dans nt, il ne serait pas judicieux de laisser le nom de la fonction vide lors de l'exécution d'une commande DTrace qui journalise des données. Pour éviter un éventuel impact sur les performances, il est recommandé de spécifier au moins une partie du nom de la fonction (par exemple, fbt:nt:*Timer*:entry).

PID

Le fournisseur de PID DTrace permet de suivre l'exécution interne de processus en mode utilisateur tels qu'un navigateur Web ou une base de données. Vous pouvez également attacher DTrace au moment du lancement du processus afin de déboguer les problèmes de démarrage du processus. Dans le cadre de la définition du PID, vous spécifiez les fonctions définies dans le processus et les décalages spécifiques (ou tous les décalages à l'aide du caractère générique *) au sein de la fonction. Le fournisseur de PID exige que le binaire soit lancé ou en cours d'exécution au moment de l'exécution du script.

Cet exemple de commande affiche des informations sur un appel spécifique dans le PID associé à notepad.exe. Utilisez la commande lm (Lister les modules chargés) du débogueur pour répertorier tous les modules disponibles.

C:\Windows\system32>dtrace -ln "pid$target:ntdll:RtlAllocateHeap:entry" -c notepad.exe
   ID   PROVIDER            MODULE                          FUNCTION NAME
 5102    pid6100             ntdll                   RtlAllocateHeap entry

Remarque

Lors du suivi de fonctions écrites en C++, les noms de fonctions peuvent être trop longs ou trop décorés pour être spécifiés sous forme de sonde avec leur forme complète. Une solution courante consiste à utiliser une expression qui correspond uniquement à la fonction cible. Par exemple, utilisez « String??Copy » comme partie « probefunc » du nom de la sonde pour correspondre à « String::Copy() », ou « *GetPinnableReference » pour correspondre à « String::GetPinnableReference() ».

Architecture DTrace Windows

Les utilisateurs interagissent avec DTrace via la commande DTrace, qui sert d'interface avec le moteur DTrace. Les scripts en langage D sont compilés dans un format intermédiaire (DIF) dans l'espace utilisateur et envoyés au composant noyau de DTrace pour exécution, parfois appelé « machine virtuelle DIF ». Il s’exécute dans le pilote dtrace.sys.

Traceext.sys (extension de suivi) est un pilote d’extension de noyau Windows, qui permet à Windows d’exposer les fonctionnalités sur lesquelles DTrace s’appuie pour fournir le suivi. Le noyau Windows fournit des légendes pendant la passerelle de pile ou les accès mémoire qui sont ensuite implémentés par l’extension de suivi.

Schéma montrant l'architecture DTrace Windows avec dtrace.exe connecté à libtrace, qui communique avec DTrace.sys, et appelle Traceext.sys.

Installation de DTrace sous Windows

  1. Vérifiez que votre appareil exécute une version prise en charge de Windows. Le téléchargement actuel de DTrace est pris en charge dans les builds Insider de Windows 20H1 après la version 18980 et Windows Server Build 18975. L'installation de cette version de DTrace sur des versions plus anciennes de Windows peut entraîner une instabilité du système et n'est pas recommandée. (La version archivée de DTrace pour 19H1 n’est plus disponible et n’est plus prise en charge.)

  2. Téléchargez le fichier d’installation MSI (Télécharger DTrace sur Windows) depuis le Centre de téléchargement Microsoft.

  3. Sélectionnez l’installation complète.

    Important

    Avant d’utiliser bcdedit pour modifier les informations de démarrage, vous devrez peut-être suspendre temporairement les fonctionnalités de sécurité Windows telles que Patchguard, BitLocker et le démarrage sécurisé sur le PC de test. Réactivez ces fonctionnalités de sécurité lorsque les tests sont terminés et gérez de manière appropriée le PC de test lorsque ces fonctionnalités de sécurité sont désactivées.

  4. Mettez à jour la variable d'environnement PATH pour y inclure C:\Program Files\DTrace

set PATH=%PATH%;"C:\Program Files\DTrace"
  1. Activez DTrace sur la machine en utilisant la commande bcdedit.
bcdedit /set dtrace ON

Lorsque vous effectuez une mise à jour vers une nouvelle build de Windows Insider, vous devez à nouveau définir l'option dtrace bcdedit.

Remarque

Si vous utilisez BitLocker, désactivez-le lorsque vous modifiez les valeurs de démarrage. Si vous ne le faites pas, il se peut que l'on vous demande la clé de récupération BitLocker. Pour rétablir la situation telle qu'elle était avant l'apparition de ce problème, une solution consiste à démarrer la console de récupération et de restaurer la valeur de bcdedit, bcdedit /set {default} dtrace on. Si une mise à jour du système d'exploitation a supprimé la valeur et que vous l'avez ajoutée, pour récupérer le système d'exploitation, utilisez bcdedit pour supprimer la valeur, bcdedit /deletevalue {default} dtrace. Désactivez ensuite BitLocker, puis réactivez dtrace, bcdedit /set dtrace ON.

Configurez le VSM (mode sécurisé virtuel) sur la machine pour activer le suivi des limites de fonction (FBT) du noyau en définissant « HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard\EnableVirtualizationBasedSecurity » sur 1 pour activer le VSM et le noyau sécurisé.

Pour ce faire, utilisez la commande REG Add, comme suit :

REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard\ /v EnableVirtualizationBasedSecurity /t REG_DWORD /d 1

Certaines commandes DTrace utilisent des symboles Windows. Pour utiliser les symboles Windows, créez un répertoire de symboles et définissez leur chemin d'accès :

mkdir c:\symbols
set _NT_SYMBOL_PATH=srv*C:\symbols*https://msdl.microsoft.com/download/symbols

Pour plus d’informations sur les chemins d’accès aux symboles, consultez Chemin d’accès aux symboles pour les débogueurs Windows.

Utilisation de DTrace dans une machine virtuelle

Si vous exécutez DTrace sur une machine virtuelle (VM), activez la virtualisation imbriquée sur la machine servant de base à la VM (lorsque la VM est arrêtée) à l'aide de la commande PowerShell suivante. Indiquez la <VMName> pour la machine virtuelle dans laquelle vous exécutez DTrace. Ouvrez une fenêtre PowerShell en tant qu’administrateur.

Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true

Redémarrez le PC sur lequel est basé la machine virtuelle.

Validation de l’installation de DTrace

Utilisez l’option -l pour répertorier les sondes actives. Si DTrace est actif, de nombreuses sondes doivent être répertoriées pour les événements ETW et système.

Ouvrez une invite de commandes Windows en tant qu’administrateur pour saisir les commandes DTrace.

C:\> dtrace -l

...

  179    syscall                                 NtLockVirtualMemory return
  180    syscall                               NtDeviceIoControlFile entry
  181    syscall                               NtDeviceIoControlFile return
  182    syscall                                 NtCreateUserProcess entry
  183    syscall                                 NtCreateUserProcess return
  184    syscall                                      NtQuerySection entry
  185    syscall                                      NtQuerySection return

...

 3161        etw 222962ab-6180-4b88-a825-346b75f2a24a           0xff_0xffffffffffffffff generic_event
 3162        etw 3ac66736-cc59-4cff-8115-8df50e39816b           0xff_0xffffffffffffffff generic_event
 3163        etw 42695762-ea50-497a-9068-5cbbb35e0b95           0xff_0xffffffffffffffff generic_event
 3164        etw 3beef58a-6e0f-445d-b2a4-37ab737bd47e           0xff_0xffffffffffffffff generic_event

...

Si seules ces trois sondes sont répertoriées, le pilote DTrace.sys chargé pose problème.

C:\>  dtrace -l
   ID   PROVIDER            MODULE                          FUNCTION NAME
    1     dtrace                                                     BEGIN
    2     dtrace                                                     END
    3     dtrace                                                     ERROR

Bien démarrer avec DTrace - Commandes en une ligne

Commencez par exécuter ces commandes à partir d’une invite administrateur.

Cette commande affiche un résumé syscall par programme pendant 5 secondes. Le paramètre tick-5sec spécifie la période. exit(0); permet de quitter la commande dès qu'elle est terminée et de revenir à l'invite de commande. La sortie est spécifiée à l’aide de la commande. [pid,execname] = count();. Elle affiche l'ID de processus (PID), le nom de l'exécutable et le décompte des 5 dernières secondes.

C:\> dtrace -Fn "tick-5sec {exit(0);} syscall:::entry{ @num[pid,execname] = count();} "  
dtrace: description 'tick-5sec ' matched 471 probes
CPU FUNCTION
  0 | :tick-5sec

     1792  svchost.exe                                                       4
     4684  explorer.exe                                                      4
     4916  dllhost.exe                                                       4
     6192  svchost.exe                                                       4
     6644  SecurityHealth                                                    4
       92  TrustedInstall                                                    5
      504  csrss.exe                                                         5
      696  svchost.exe                                                       6
...

Cette commande résume les appels de mise en place/annulation de retardateur pendant 3 secondes :

C:\> dtrace -Fn "tick-3sec {exit(0);} syscall::Nt*Timer*:entry { @[probefunc, execname, pid] = count();}"
dtrace: description 'tick-3sec ' matched 14 probes
CPU FUNCTION
  0 | :tick-3sec

  NtCreateTimer                                       WmiPrvSE.exe                                            948                1
  NtCreateTimer                                       svchost.exe                                             564                1
  NtCreateTimer                                       svchost.exe                                            1276                1
  NtSetTimer2                                         svchost.exe                                            1076                1
  NtSetTimer2                                         svchost.exe                                            7080                1
  NtSetTimerEx                                        WmiPrvSE.exe                                            948                1
...  

Commandes en une ligne qui utilisent des symboles

Ces commandes tirent parti des symboles Windows et nécessitent que le chemin des symboles soit défini, comme indiqué dans la section relative à l'installation. Comme mentionné précédemment dans l’installation, créez un répertoire et définissez le chemin d’accès des symboles à l’aide de ces commandes.

C:\> mkdir c:\symbols
C:\> set _NT_SYMBOL_PATH=srv*C:\symbols*https://msdl.microsoft.com/download/symbols

Cet exemple de commande affiche les principales fonctions NT.

C:\> dtrace -n "fbt:nt:*Timer*:entry { @k[probefunc] = count(); } tick-5s { trunc(@k, 10);printa(@k); exit(0); }"
dtrace: description 'fbt:nt:*Timer*:entry ' matched 340 probes
CPU     ID                    FUNCTION:NAME
  0  22362                         :tick-5s
  KeCancelTimer                                                   712
  KeSetTimer2                                                     714
  HalpTimerClearProblem                                           908
  ExpSetTimerObject                                               935
  NtSetTimerEx                                                    935
  KeSetTimer                                                     1139
  KeSetCoalescableTimer                                          3159
  KeResumeClockTimerFromIdle                                    11767
  xHalTimerOnlyClockInterruptPending                            22819
  xHalTimerQueryAndResetRtcErrors                               22819

Cette commande crée un dump de la structure du noyau SystemProcess.

C:\> dtrace -n "BEGIN {print(*(struct nt`_EPROCESS *) nt`PsInitialSystemProcess);exit(0);}"

...

   uint64_t ParentSecurityDomain = 0
    void *CoverageSamplerContext = 0
    void *MmHotPatchContext = 0
    union _PS_PROCESS_CONCURRENCY_COUNT ExpectedConcurrencyCount = {
         Fraction :20 = 0
         Count :12 = 0
        uint32_t AllFields = 0
    }
    struct _KAFFINITY_EX IdealProcessorSets = {
        uint16_t Count = 0x1
        uint16_t Size = 0x20
        uint32_t Reserved = 0
        uint64_t [32] Bitmap = [ 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
    }
}

Cette commande affiche la pile supérieure du noyau au cours des 10 dernières secondes.

C:\> dtrace -qn "profile-997hz { @[stack()] = count(); } tick-10sec { trunc(@,5); printa(@); exit(0);}"

              nt`KiDispatchInterruptContinue
              nt`KiDpcInterrupt+0x318
              nt`KiSwapThread+0x1054
              nt`KiCommitThreadWait+0x153
              nt`KeRemoveQueueEx+0x263
              nt`IoRemoveIoCompletion+0x54
              nt`NtWaitForWorkViaWorkerFactory+0x284
              nt`KiSystemServiceCopyEnd+0x35
               14

              nt`KiDispatchInterruptContinue
              nt`KiDpcInterrupt+0x318
...

Cette commande affiche les principaux modules appelés par notepad.exe lors du lancement. L'option -c exécute la commande spécifiée (notepad.exe) et se termine à la fin.

C:\> dtrace -qn "pid$target:::entry { @k[probemod] = count();} tick-10s{printa(@k); exit(0);}" -c notepad.exe

  gdi32full                                                         5
  msvcp_win                                                         6
  combase                                                           7
  notepad                                                           9
  ADVAPI32                                                         10
  GDI32                                                            11
  SHELL32                                                          11
  USER32                                                           21
  win32u                                                          345
  KERNELBASE                                                     3727
  msvcrt                                                         7749
  KERNEL32                                                       9883
  RPCRT4                                                        11710
  ntdll                                                        383445

Voir aussi

Programmation Windows DTrace

DTrace ETW

DTrace Live Dump

Exemples de code Windows DTrace