Windows의 DTrace
DTrace(DTrace.exe)는 시스템 정보 및 이벤트를 표시하는 명령줄 도구입니다. DTrace는 Windows로 포팅된 오픈 소스 추적 플랫폼입니다. DTrace는 원래 Solaris 운영 체제용으로 개발되었습니다. 사용자/커널 함수의 동적 계측, D-언어를 사용하여 스크립팅하는 기능 및 추측 추적을 제공합니다. 또한 DTrace에는 ETW 계측, ETW 이벤트 생성, 시스템 호출 프로브 및 라이브 덤프 캡처 기능과 같은 Windows OS 관련 확장이 있습니다.
참고 항목
DTrace는 버전 18980 및 Windows Server 빌드 18975 이후의 Windows 참가자 빌드에서 지원됩니다.
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 Techniques for Solaris 10 and OpenSolaris by Richard McDougall, Jim Mauro, Brendan Gregg
Windows DTrace에 대한 피드백 제공
피드백 허브를 사용하여 새 기능을 요청하거나 Windows DTrace의 문제 또는 버그를 보고할 수 있습니다.
- Windows에서 피드백 허브를 시작하려면 검색으로 이동하여 단어 피드백을 입력한 다음 피드백 허브를 선택합니다.
- 기능 제안 또는 문제 보고 중 하나를 선택합니다.
- 문제 또는 제안에 대한 상세하고 구체적인 설명을 제공합니다.
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:::
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(로드된 모듈 나열) 명령을 사용하여 사용 가능한 모든 모듈을 나열합니다.
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(로드된 모듈 나열) 명령을 사용하여 사용 가능한 모든 모듈을 나열합니다.
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??을 사용하시겠습니까? 'String::Copy()'와 일치하도록 프로브 이름의 'probefunc' 부분으로 복사하거나 '*GetPinnableReference'를 'String::GetPinnableReference()'와 일치하도록 복사합니다.
DTrace Windows 아키텍처
사용자는 DTrace 엔진의 프런트 엔드 역할을 하는 DTrace 명령을 통해 DTrace와 상호 작용합니다. D 스크립트는 사용자 공간에서 DIF(중간 형식)로 컴파일되고 실행을 위해 DTrace 커널 구성 요소로 전송되며, DIF Virtual Machine이라고도 합니다. dtrace.sys 드라이버에서 실행됩니다.
Traceext.sys(추적 확장명)는 Windows 커널 확장 드라이버로, Windows에서 DTrace가 추적을 제공하기 위해 사용하는 기능을 노출할 수 있습니다. Windows 커널은 스택 워크 또는 메모리 액세스 중에 설명선을 제공하며 추적 확장에 의해 구현됩니다.
Windows에서 DTrace 설치
지원되는 버전의 Windows를 실행하고 있는지 확인합니다. DTrace의 현재 다운로드는 버전 18980 및 Windows Server 빌드 18975 이후의 20H1 Windows 참가자 빌드에서 지원됩니다. 이전 버전의 Windows에 이 버전의 DTrace를 설치하면 시스템 불안정이 발생할 수 있으며 권장되지 않습니다. (보관된 19H1용 DTrace 버전은 더 이상 사용할 수 없으며 더 이상 지원되지 않습니다.)
Microsoft 다운로드 센터에서 MSI 설치 파일(Windows에서 DTrace 다운로드)을 다운로드합니다.
설치 완료를 선택합니다.
Important
bcdedit를 사용하여 부팅 정보를 변경하기 전에 테스트 PC에서 Patchguard, BitLocker 및 보안 부팅과 같은 Windows 보안 기능을 일시적으로 일시 중단해야 할 수 있습니다. 테스트가 완료되면 이러한 보안 기능을 다시 사용하도록 설정하고 보안 기능이 비활성화된 경우 테스트 PC를 적절하게 관리합니다.
C:\Program Files\DTrace를 포함하도록 PATH 환경 변수 업데이트
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
를 다시 사용하도록 설정합니다.
VSM 및 보안 커널을 사용하도록 설정하려면 "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard\EnableVirtualizationBasedSecurity"를 1로 설정하여 컴퓨터에서 FBT(커널 함수 경계 추적)를 사용하도록 컴퓨터에서 VSM(가상 보안 모드)을 구성합니다.
이렇게 하려면 다음과 같이 REG 추가 명령을 사용합니다.
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 디버거의 기호 경로를 참조 하세요.
Virtual Machine 내에서 DTrace 사용
VM에서 DTrace를 실행하는 경우 다음 PowerShell 명령을 사용하여 VM이 중지될 때 VM을 지원하는 컴퓨터에서 중첩된 가상화를 켭니다. <VMName>
DTrace를 실행 중인 VM에 대해 제공합니다. 관리자 권한으로 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
...
이러한 세 프로브만 나열되면 로드되는 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(프로세스 ID), 실행 파일 이름 및 지난 5초 동안의 개수를 표시하여 지정 [pid,execname] = count();
됩니다.
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