Windows 上的 DTrace
DTrace (DTrace.exe) 是顯示系統資訊和事件的命令行工具。 DTrace 是移植到 Windows 的開放原始碼追蹤平臺。 DTrace 最初是針對 Solaris 操作系統所開發。 它提供使用者/核心函式的動態檢測、使用 D 語言編寫腳本的能力,以及推測追蹤。 此外,DTrace 具有 Windows OS 特定的擴充功能,例如 ETW 檢測、ETW 事件產生、系統呼叫探查,以及實時傾印擷取功能。
注意
在 18980 版和 Windows Server 組建 18975 之後,Windows 測試人員組建支援 DTrace。
Windows GitHub 網站上的 DTrace 位於:
https://github.com/microsoft/DTrace-on-Windows
開啟 DTrace 資訊
如需 DTrace 的詳細資訊,請參閱 劍橋大學的 OpenDTrace 規格 1.0 版。
主要 GitHub 網站位於 https://github.com/opendtrace/。
有一組實用的腳本可在取得 https://github.com/opendtrace/toolkit。
有許多 DTrace 書籍可供使用,例如:
DTrace:布蘭登·格雷格和吉姆·莫羅在 Oracle Solaris、Mac OS X 和 FreeBSD 中的動態追蹤
Solaris 效能和工具:理查·麥克杜格爾、吉姆·莫羅和布蘭登·格雷格的 DTrace 和 MDB 技術 for Solaris 10 和 OpenSolaris
提供 Windows DTrace 的意見反應
使用意見反應中樞來要求新功能,或使用 Windows DTrace 回報任何問題或錯誤。
- 若要在 Windows 中啟動意見反應中樞,請移至搜尋,輸入意見反應一詞,然後選取 [意見反應中樞]。
- 選取 [ 建議功能 ] 或 [回報問題]。
- 提供問題或建議的詳細特定描述。
DTrace Windows 延伸模組
以下是 Windows 上提供的一些 Dtrace 提供者及其檢測專案。
syscall – NTOS 系統呼叫。
fbt (函式界限追蹤) - 核心函式專案和傳回。
pid (行程識別子) - 使用者模式進程追蹤。 如同內核模式 FBT,但也允許檢測任意函式位移。
etw (Windows 事件追蹤) – 允許針對 ETW 定義探查。 此提供者有助於利用 DTrace 中現有的作業系統檢測。
SYSCALL – NTOS 系統呼叫
SYSCALL 會為每個系統呼叫提供一組探查:輸入探查,會在系統呼叫進入之前引發,並在系統呼叫完成之後引發,但在控制權轉移回用戶層級之前引發的傳回探查。 針對所有 SYSCALL 探查,函式名稱會設定為已檢測系統呼叫的名稱,而模組名稱是函式所在的模組。 從命令提示字元輸入 命令 dtrace.exe -l -P syscall
,即可找到 SYSCALL 提供者所提供的系統呼叫名稱。 請注意,探查名稱為小寫 syscall。 此命令 dtrace -ln syscall:::
也會列出 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
...
請注意,並非所有螢幕輸出都會顯示在這些範例中。 "..."用來表示截斷的輸出。
若要卷動輸出,請透過管道向外傳送至 更多 命令,如下所示:
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:::
會列出 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
...
如需詳細資訊,請參閱 DTrace ETW。
函式界限追蹤 (FBT)
函式界限追蹤 (FBT) 提供者會提供與 Windows 核心中大部分函式專案相關聯的探查和傳回。 函式是程式文字的基本單位。 與其他 DTrace 提供者類似,FBT 在未明確啟用時沒有探查效果。 啟用時,FBT 只會在探查函式中引發探查效果。 FBT 已在 x86 和 x64 平台上實作。
針對每個指令集,有幾個函式不會呼叫其他函式,而且由編譯程式(所謂的分葉函式)高度優化,無法由 FBT 檢測。 這些函式的探查不存在於 DTrace 中。
此命令 dtrace -ln fbt:nt::
會列出 nt 模組可用的所有探查及其參數。 使用除錯程式 lm (List Loaded Modules) 命令來列出所有可用的模組。
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
...
注意
由於 nt 中有數千個可用的呼叫,因此在執行記錄數據的 DTrace 命令時,讓函式名稱保持空白並不是個好主意。 避免可能效能影響的建議方法是至少指定函式名稱的一部分,例如 fbt:nt:*Timer*:entry
。
PID
DTrace PID 提供者可讓您追蹤使用者模式進程的內部執行,例如網頁瀏覽器或資料庫。 您也可以在進程啟動時附加 DTrace,以便偵錯進程啟動問題。 在 PID 定義中,您可以指定函式中定義的函式,以及函式內的特定位移(或所有使用通配符 *) 的位移。 PID 提供者需要在腳本執行時啟動或執行二進位檔。
這個範例命令會顯示與notepad.exe相關聯之 PID 中特定呼叫的相關信息。 使用除錯程式 lm (List Loaded Modules) 命令來列出所有可用的模組。
C:\Windows\system32>dtrace -ln "pid$target:ntdll:RtlAllocateHeap:entry" -c notepad.exe
ID PROVIDER MODULE FUNCTION NAME
5102 pid6100 ntdll RtlAllocateHeap entry
注意
當追蹤以C++撰寫的函式時,函式名稱可能太長或裝飾,無法以完整格式指定為探查。 常見的解決方案是使用唯一符合目標函式的表達式。 例如,使用 『String??複製' 做為探查名稱的 'probefunc' 部分,以符合 'String::Copy()' 或 '*GetPinnableReference' 以符合 'String::GetPinnableReference()'。
DTrace Windows 架構
使用者透過 DTrace 命令與 DTrace 互動,該命令可作為 DTrace 引擎的前端。 D 腳本會在使用者空間中編譯成中繼格式 (DIF),並傳送至 DTrace 核心元件以執行,有時稱為 DIF 虛擬機。 這會在dtrace.sys驅動程序中執行。
Traceext.sys (追蹤延伸模組) 是 Windows 核心延伸模塊驅動程式,可讓 Windows 公開 DTrace 依賴的功能以提供追蹤。 Windows 核心會在 stackwalk 或記憶體存取期間提供圖說文字,然後由追蹤延伸模組實作。
在 Windows 下安裝 DTrace
確認您正在執行支援的 Windows 版本。 在 18980 版和 Windows Server 組建 18975 之後,測試人員組建 20H1 Windows 支援目前的 DTrace 下載。 在舊版 Windows 上安裝此版本的 DTrace 可能會導致系統不穩定,不建議這麼做。 (19H1 的 DTrace 封存版本已無法使用,不再支援。
從 Microsoft 下載中心下載 MSI 安裝檔案 (下載 Windows 上的 DTrace)。
選取 [完成安裝]。
重要
使用 bcdedit 變更開機資訊之前,您可能需要暫時暫停測試計算機上的 Patchguard、BitLocker 和安全開機等 Windows 安全性功能。 在測試完成時重新啟用這些安全性功能,並在停用安全性功能時適當地管理測試計算機。
更新 PATH 環境變數以包含 C:\Program Files\DTrace
set PATH=%PATH%;"C:\Program Files\DTrace"
- 使用 bcdedit 命令在機器上啟用 DTrace。
bcdedit /set dtrace ON
當您更新至新的 Windows 測試人員組建時,您必須再次設定 dtrace bcdedit 選項。
注意
如果您使用 BitLocker,請在變更開機值時將其停用。 如果您未這麼做,系統可能會提示您輸入 BitLocker 修復金鑰。 從這種情況中復原的其中一種方法是開機至復原控制台,並還原 bcdedit 值 。 bcdedit /set {default} dtrace on
如果 OS 更新已移除值,而且您已將它新增至 ,則若要復原 OS,請使用 bcdedit 來移除值 bcdedit /deletevalue {default} dtrace
。 然後停用 BitLocker 並重新啟用 dtrace, bcdedit /set dtrace ON
。
將 「HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard\EnableVirtualizationBasedSecurity」 設定為 1,以啟用 VSM 和安全核心,在機器上設定 VSM(虛擬安全模式)來啟用核心函式界限追蹤 (FBT)。
若要這樣做,請使用 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 的機器上開啟巢狀虛擬化。 <VMName>
提供您執行 DTrace 之 VM 的 。 以系統管理員身分開啟PowerShell Windows。
Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true
重新啟動支援 VM 的電腦。
驗證 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
...
如果只列出這三個探查,載入DTrace.sys驅動程式就會發生問題。
C:\> dtrace -l
ID PROVIDER MODULE FUNCTION NAME
1 dtrace BEGIN
2 dtrace END
3 dtrace ERROR
開始使用 DTrace - 一行命令
從系統管理員命令提示字元執行這些命令以開始使用。
此命令會依程序顯示5秒的 syscall 摘要。 tick-5sec 參數會指定時間週期。 exit(0):會導致命令在完成時結束,回到命令提示字元。 使用 [這個] 指定輸出 [pid,execname] = count();
會顯示進程識別碼 (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
...
使用符號的一行命令
這些命令會利用 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