次の方法で共有


Windows 上の DTrace

DTrace (DTrace.exe) は、システム情報とイベントを表示するコマンドライン ツールです。 DTrace は、Windows に移植されたオープンソースのトレース プラットフォームです。 DtraceはもともとSolarisオペレーティングシステム用に開発されました。 ユーザー/カーネル関数、D 言語を使用してスクリプトを作成する機能、および投機的トレースの両方の動的インストルメンテーションを提供します。 さらに、DTrace には、ETW インストルメンテーション、ETW イベント生成、システム呼び出しプローブ、ライブ ダンプ キャプチャ機能などの Windows OS 固有の拡張機能があります。

Note

DTraceは、バージョン18980およびWindows Server Build 18975以降のInsiderのビルドでサポートされています。

Windows GitHubサイトのDTraceは次の場所にあります。

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

DTrace情報を開く

DTraceの詳細については、ケンブリッジ大学のOpenDTrace Specification version 1.0を参照してください。

主要なGitHubサイトはhttps://github.com/opendtrace/にあります。

有用なスクリプトのセットは、https://github.com/opendtrace/toolkitで入手できます。

次のようなDTraceの書籍が多数用意されています。

DTrace:Brendan GreggとJim MauroによるOracle Solaris、Mac OS XおよびFreeBSDにおける動的トレース

Solaris のパフォーマンスとツール: Solaris 10 と OpenSolaris の DTrace と MDB の手法 リチャード・マクドゥーガル、ジム・マウロ、ブレンダン・グレッグ

Windows DTraceに関するフィードバックの提供

フィードバック ハブを使用して、新しい機能を要求したり、Windows DTrace で問題やバグを報告したりできます。

  1. Windows でフィードバック ハブを起動するには、検索に移動し、 feedback という単語を入力し、 Feedback Hub を選択します。
  2. 機能の提案または問題の報告を選択します。
  3. 問題または提案の詳細な具体的な説明を提供します。

DTrace Windows拡張機能

Windows で使用できる Dtrace プロバイダーの一部と、そのインストルメント化された機能を次に示します。

  • syscall – NTOS システム呼び出し。

  • fbt (関数境界トレース) – カーネル関数のエントリと戻り値。

  • pid(プロセスID) – ユーザーモードプロセスのトレース。 カーネル モード FBT と同様ですが、任意の関数オフセットのインストルメンテーションも可能です。

  • etw (Windows のイベント トレース) – ETW に対してプローブを定義できるようにします。 このプロバイダーは、DTrace の既存のオペレーティング システム インストルメンテーションを活用するのに役立ちます。

SYSCALL – NTOS システム呼び出し

SYSCALLは、システムコールが入力される前に起動するエントリプローブと、システムコールが完了した後で制御がユーザーレベルに戻る前に起動するリターンプローブのペアをシステムコールごとに提供します。 すべてのSYSCALLプローブで、関数名は計装システム コールの名前に設定され、モジュール名は関数が存在するモジュールです。 SYSCALLプロバイダが提供するシステムコールの名前は、コマンドdtrace.exe -l -P syscallプロンプトからコマンドを入力することによって確認できます。 プローブ名は小文字のsyscallであることに注意してください。 このコマンドは、システムコールdtrace -ln 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
...

これらの例では、すべての画面出力が表示されるわけではないことに注意してください。 「..」は、切り捨てられた出力を表すために使用されます。

出力をスクロールするには、次のように「moreもっと」コマンドにパイプアウトします。

dtrace -ln syscall:::|more

vオプションを追加すると、使用可能なsyscallプローブに関する詳細情報が表示されます。

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には、既存のマニフェストプローブまたはトレースログ付きETWプローブのサポートが含まれています。 イベントの発生時に、ETW イベントを同期的にインストルメント化、フィルター処理、解析できます。 さらに、DTraceを使用してさまざまなイベント/システム状態を組み合わせて、複雑なエラー状況のデバッグに役立つ統合出力ストリームを提供できます。

このコマンドは、システムコールdtrace -ln etw:::プロバイダから利用可能なすべてのプローブとそのパラメータの一覧を表示します。

  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
  ...

詳細については、DTrace ETWを参照してください。

関数バウンダリトレース(FBT)

関数バウンダリトレース(FBT)プロバイダは、Windowsカーネル内のほとんどの関数とのエントリとリターンに関連付けられたプローブを提供します。 関数はプログラムテキストの基本単位です。 他のDTraceプロバイダと同様に、FBTは明示的に有効にされていない場合はプローブ効果がありません。 有効の場合、FBTはプローブされた関数でプローブ効果だけを誘導します。 FBTは、x86およびx64プラットフォームに実装されています。

各命令セットには、他の関数を呼び出さず、コンパイラによって高度に最適化された少数の関数(いわゆるリーフ関数)があり、FBTによってインスツルメンテーションすることはできません。 これらの関数のプローブはDTraceには存在しません。

このコマンドdtrace -ln fbt:nt::は、ntモジュールで使用可能なすべてのプローブとそのパラメータを一覧表示します。 使用可能なすべてのモジュールを一覧表示するには、 デバッガlm(ロードされたモジュールのリスト)コマンドを使用します。

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
...

Note

nt内で使用可能なコールは数千あるため、データをログに記録するDTraceコマンドを実行する場合は、関数名を空のままにしておくことはお勧めできません。 パフォーマンスへの影響を回避するために推奨される方法は、fbt:nt:*Timer*:entryなどの機能名の少なくとも一部を指定することです。

PID

Dtrace PIDプロバイダでは、ウェブブラウザやデータベースなどのユーザーモードプロセスの内部実行をトレースできます。 プロセス起動時にDTraceを接続して、プロセス起動の問題をデバッグすることもできます。 PID定義の一部として、プロセスで定義された関数と、関数内の特定のオフセット(またはすべてワイルドカード*を使用したオフセット)を指定します。 PIDプロバイダは、スクリプト実行時にバイナリを起動または実行する必要があります。

このコマンド例では、notepad.exeに関連付けられたPID内の特定のコールに関する情報を表示します。 使用可能なすべてのモジュールを一覧表示するには、 デバッガlm(ロードされたモジュールのリスト)コマンドを使用します。

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

Note

C++で記述された関数をトレースする場合、関数名が長すぎたり、完全な形式でプローブとして指定できないことがあります。 一般的な解決策は、ターゲット関数に一意に一致する式を使用することです。 例えば、「String::Copy()」に一致させるにはプローブ名の「probefunc」部分に「String??Copy」を、「String::GetPinnableReference()」に一致させるには「*GetPinnableReference」を使用します。

Dtrace Windowsアーキテクチャ

ユーザーはDTraceコマンドを使用してDTraceと対話し、DTraceエンジンのフロントエンドとして機能します。 Dスクリプトはユーザ空間で中間フォーマット(DIF)にコンパイルされ、実行のためにDTraceカーネルコンポーネントに送信されます。DIF仮想機械と呼ばれることもあります。 これはdtrace.sysドライバで実行されます。

Traceext.sys(トレースエクステンション)は、Windowsカーネル拡張ドライバであり、DTraceがトレースを提供するために依存する機能をWindowsで公開できます。 Windowsカーネルは、スタックウォークまたはメモリアクセス中にコールアウトを提供し、トレース拡張によって実装されます。

DTrace Windows アーキテクチャを示す図。DTrace.sys と通信して Traceext.sys を呼び出す libtrace に、dtrace.exe が接続されています。

WindowsでのDTraceのインストール

  1. サポートされているバージョンのWindowsを実行していることを確認します。 DTraceの現在のダウンロードは、バージョン18980とWindows Server Build 18975以降の20H1 WindowsのInsiderビルドでサポートされています。 このバージョンのDTraceを旧バージョンのWindowsにインストールすると、システムが不安定になる可能性があり、推奨しません。 (19H1用のDTraceのアーカイブバージョンは使用できなくなり、サポートされなくなりました。)

  2. MicrosoftダウンロードセンターからMSIインストールファイル(WindowsのDtraceダウンロード)をダウンロードします。

  3. 「インストールの完了」を選択します。

    重要

    bcdeditを使用してブート情報を変更する前に、テストPCのPatchguard、BitLocker、Secure BootなどのWindowsセキュリティ機能を一時的に停止する必要があります。 テストが完了したら、これらのセキュリティ機能を再度有効にし、セキュリティ機能が無効になっている場合は、テストPCを適切に管理します。

  4. PATH 環境変数を更新して C:\Program Files\DTraceを含めます

set PATH=%PATH%;"C:\Program Files\DTrace"
  1. bcditコマンドを使用して、機械上でDTraceを有効にします。
bcdedit /set dtrace ON

新しいWindows Insiderビルドにアップデートするときは、dtrace bceditオプションを再度設定する必要があります。

Note

BitLockerを使用している場合は、ブート値を変更するときに無効にします。 これを行わないと、BitLockerの回復キーの入力を求めるプロンプトが表示される場合があります。 この状況から回復する1つの方法は、回復コンソールを起動してbcdit値、bcdedit /set {default} dtrace onを復元することです。 OSのアップデートで値が削除され、それを追加した場合、OSを回復するには、bcdeditを使って値、bcdedit /deletevalue {default} dtraceを削除します。 次に、BitLockerを無効にしてdtrace、bcdedit /set dtrace ONを再度有効にします。

VSMとセキュアカーネルを有効にするには、「HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard\EnableVirtualizationBasedSecurity」を1に設定して、カーネル機能境界トレース(FBT)を有効にするために機械上でVSM(仮想セキュアモード)を構成します。

これを行うには、次のようにREG Addコマンドを使用します。

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

一部のDTraceコマンドでは、Windowsのシンボルが使用されます。 Windowsのシンボルを使用するには、シンボルディレクトリを作成し、シンボルパスを設定します。

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

シンボルパスの詳細については、Windowsデバッガのシンボルパスを参照してください。

仮想機械内でのDTraceの使用

VMでDTraceを実行している場合は、次のPowerShellコマンドを使用して、VMをサポートする機械でネストされた仮想化をオンにします。 DTraceを実行しているVMに<VMName>を提供します。 管理者としてPowerShell Windowsを開きます。

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

VMをサポートするPCをリブートします。

DTraceインストールの検証

アクティブプローブをリストするには、-lオプションを使用します。 DTraceがアクティブな場合は、etwおよびシステムイベントについて多くのプローブをリストする必要があります。

管理者としてWindowsコマンドプロンプトを開き、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

...

これら3つのプローブだけがリストされている場合は、DTrace.sysドライバがロードされている問題があります。

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

DTraceを使用する前に - 1行のコマンド

管理者コマンドプロンプトからこれらのコマンドを実行して開始します。

このコマンドは、プログラムごとに5秒間syscallサマリーを表示します。 tick-5secパラメータは、期間を指定します。 exit(0);を指定すると、コマンドが完了すると終了してコマンドプロンプトに戻ります。 出力は、 [pid,execname] = count(); を使用して指定します。プロセス ID (PID)、実行可能ファイル名、および過去 5 秒間のカウントが表示されます。

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
...

このコマンドは、タイマーセット/キャンセルコールを3秒間要約します。

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
...  

シンボルを使用する1行のコマンド

これらのコマンドはWindowsのシンボルを利用し、インストールセクションで説明されているようにシンボルパスを設定する必要があります。 インストールで前述したように、これらのコマンドを使用してディレクトリを作成し、シンボル パスを設定します。

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

このコマンド例では、上位の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

このコマンドは、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 ]
    }
}

このコマンドは、過去10秒間のトップカーネルスタックを表示します。

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
...

このコマンドは、起動中にnotepad.exeによって呼び出される上位モジュールを表示します。 -cオプションは指定されたコマンド(notepad.exe)を実行し、完了すると終了します。

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

関連項目