다음을 통해 공유


시간 이동 디버깅 - 추적 재생

시계가 포함된 시간 이동 디버깅 로고입니다.

이 섹션에서는 시간 이동 추적을 재생하고 정시에 앞뒤로 탐색하는 방법을 설명합니다.

명령 시간 이동 탐색

다음 명령과 함께 후행 빼기 기호를 사용하여 시간을 거슬러 이동합니다.

명령
p- (뒤로 단계)
t- (추적 후면)
g- (뒤로 이동)

자세한 내용은 시간 이동 디버깅 - 탐색 명령을 참조하세요.

리본 단추 시간 이동 탐색

또는 리본 단추를 사용하여 추적을 탐색합니다.

리본 메뉴의 이동, 뒤로 이동, 한 단계 뒤로 이동 단추의 스크린샷

TTD 추적 재생 예제

g- 명령을 사용하여 이벤트 또는 TTD 추적의 시작 부분에 도달할 때까지 뒤로 실행합니다. 역방향 실행을 중지할 수 있는 이벤트는 앞으로 실행을 중지하는 것과 동일합니다. 이 예제에서는 추적의 시작에 도달합니다.

0:000> g-
TTD: Start of trace reached.
(3f78.4274): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 29:0
ntdll!ZwTestAlert+0x14:
00007ffc`61f789d4 c3              ret

p(단계) 명령을 사용하여 TTD 추적에서 앞으로 이동합니다.

0:000> p
Time Travel Position: F:1
eax=0173a5b0 ebx=00fd8000 ecx=7774f821 edx=0f994afc esi=0f99137c edi=00de0000
eip=7774f828 esp=010ff34c ebp=010ff584 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!LdrpInitializeProcess+0x1bc5:
7774f828 740b            je      ntdll!LdrpInitializeProcess+0x1bd2 (7774f835) [br=1]
0:000> p
Time Travel Position: F:2
eax=0173a5b0 ebx=00fd8000 ecx=7774f821 edx=0f994afc esi=0f99137c edi=00de0000
eip=7774f835 esp=010ff34c ebp=010ff584 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!LdrpInitializeProcess+0x1bd2:
7774f835 83bdd0feffff00  cmp     dword ptr [ebp-130h],0 ss:002b:010ff454=00000000
0:000> p
Time Travel Position: F:3
eax=0173a5b0 ebx=00fd8000 ecx=7774f821 edx=0f994afc esi=0f99137c edi=00de0000
eip=7774f83c esp=010ff34c ebp=010ff584 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!LdrpInitializeProcess+0x1bd9:
7774f83c 0f8450e8ffff    je      ntdll!LdrpInitializeProcess+0x42f (7774e092) [br=1]

t(추적) 명령을 사용하여 추적을 탐색할 수도 있습니다.

0:000> t
Time Travel Position: F:4
eax=0173a5b0 ebx=00fd8000 ecx=7774f821 edx=0f994afc esi=0f99137c edi=00de0000
eip=7774e092 esp=010ff34c ebp=010ff584 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!LdrpInitializeProcess+0x42f:
7774e092 33c0            xor     eax,eax
0:000> t
Time Travel Position: F:5
eax=00000000 ebx=00fd8000 ecx=7774f821 edx=0f994afc esi=0f99137c edi=00de0000
eip=7774e094 esp=010ff34c ebp=010ff584 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!LdrpInitializeProcess+0x431:
7774e094 e9f5170000      jmp     ntdll!LdrpInitializeProcess+0x1c2b (7774f88e)

p- 명령을 사용하여 TTD 추적에서 뒤로 이동합니다.

0:000> p-
Time Travel Position: F:4
eax=0173a5b0 ebx=00fd8000 ecx=7774f821 edx=0f994afc esi=0f99137c edi=00de0000
eip=7774e092 esp=010ff34c ebp=010ff584 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!LdrpInitializeProcess+0x42f:
7774e092 33c0            xor     eax,eax
0:000> p-
Time Travel Position: F:3
eax=0173a5b0 ebx=00fd8000 ecx=7774f821 edx=0f994afc esi=0f99137c edi=00de0000
eip=7774f83c esp=010ff34c ebp=010ff584 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!LdrpInitializeProcess+0x1bd9:
7774f83c 0f8450e8ffff    je      ntdll!LdrpInitializeProcess+0x42f (7774e092) [br=1]

t- 명령을 사용하여 시간을 뒤로 탐색할 수도 있습니다.

!tt 탐색 명령

추적에서 지정된 위치로 건너뛰어 !tt 명령을 사용하여 정시에 앞으로 또는 뒤로 이동합니다.

!tt [위치]

다음 형식 중 어느 형식으로든 시간 위치를 제공하여 해당 시점으로 이동합니다.

  • [position]가 0에서 100 사이의 10진수인 경우 추적으로 약 해당 백분율로 이동합니다. 예를 들어 !tt 50 추적의 중간으로 이동합니다.

  • {position}이 #:#이면 여기서 #은 16진수 숫자인 경우 해당 위치로 이동합니다. 예를 들어 !tt 1A0:12F 은 추적에서 1A0:12F 위치로 이동합니다.

자세한 내용은 시간 이동 디버깅 - !tt(시간 이동)를 참조하세요.

!위치

를 사용하여 !positions 추적의 위치를 포함하여 모든 활성 스레드를 표시합니다. 자세한 내용은 시간 이동 디버깅 - !위치(시간 이동)를 참조하세요.

0:000> !positions
>*Thread ID=0x1C74 - Position: F:2
 Thread ID=0x1750 - Position: A5:0
 Thread ID=0x3FFC - Position: 200:0
 Thread ID=0x36B8 - Position: 403:0
 Thread ID=0x3BC4 - Position: 5F2:0
 Thread ID=0x392C - Position: B45:0
 Thread ID=0x32B4 - Position: C87:0
 Thread ID=0x337C - Position: DF1:0
* indicates an actively running thread

이 예제에서는 현재 위치에 8개의 스레드가 있음을 보여 줍니다. 현재 스레드는 ''>로 표시된 3604입니다.

스레드 및 해당 위치의 현재 목록을 표시하는 또 다른 방법은 데이터 모델 dx 명령을 사용하는 것입니다.

dx -g @$curprocess.Threads.Select(t => new { IsCurrent = t.Id == @$curthread.Id, ThreadId = t.Id, Position = t.TTD.Position })

사용자 모드 ~ (스레드 상태) 명령은 동일한 8개의 스레드를 표시하고 현재 스레드를 '.'로 표시합니다.

0:000> ~
.  0  Id: 954.1c74 Suspend: 4096 Teb: 00fdb000 Unfrozen
   1  Id: 954.1750 Suspend: 4096 Teb: 00fea000 Unfrozen
   2  Id: 954.3ffc Suspend: 4096 Teb: 00fde000 Unfrozen
   3  Id: 954.36b8 Suspend: 4096 Teb: 00fe1000 Unfrozen
   4  Id: 954.3bc4 Suspend: 4096 Teb: 00fe4000 Unfrozen
   5  Id: 954.392c Suspend: 4096 Teb: 00fed000 Unfrozen
   6  Id: 954.32b4 Suspend: 4096 Teb: 00ff0000 Unfrozen
   7  Id: 954.337c Suspend: 4096 Teb: 00ff3000 Unfrozen

!positions 명령 출력에서 세 번째 스레드(3FFC) 옆에 있는 링크를 클릭하여 추적의 해당 위치(200:0)로 이동합니다.

0:002> !tt 200:0
Setting position: 200:0
(954.3ffc): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 200:0
eax=00000000 ebx=012da718 ecx=7775396c edx=00000000 esi=012e1848 edi=012e1a08
eip=7775396c esp=014cf9f8 ebp=014cfbfc iopl=0         nv up ei ng nz ac po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000293
ntdll!NtWaitForWorkViaWorkerFactory+0xc:
7775396c c21400          ret     14h

~ (스레드 상태) 명령을 사용하여 이제 세 번째 스레드 3ffc에 위치했는지 확인합니다.

0:002> ~
   0  Id: 954.1c74 Suspend: 4096 Teb: 00fdb000 Unfrozen
   1  Id: 954.1750 Suspend: 4096 Teb: 00fea000 Unfrozen
.  2  Id: 954.3ffc Suspend: 4096 Teb: 00fde000 Unfrozen
   3  Id: 954.36b8 Suspend: 4096 Teb: 00fe1000 Unfrozen
   4  Id: 954.3bc4 Suspend: 4096 Teb: 00fe4000 Unfrozen
   5  Id: 954.392c Suspend: 4096 Teb: 00fed000 Unfrozen
   6  Id: 954.32b4 Suspend: 4096 Teb: 00ff0000 Unfrozen
   7  Id: 954.337c Suspend: 4096 Teb: 00ff3000 Unfrozen

참고

~s#(여기서 # 는 스레드 번호)도 지정된 스레드로 전환하지만 추적의 현재 위치는 변경되지 않습니다. !tt를 사용하여 다른 스레드의 위치로 시간 이동하면 메모리에서 읽은 모든 값(및 디버거)이 해당 위치에서 조회됩니다. ~s#으로 스레드를 전환할 때 디버거는 모든 메모리 쿼리에 사용되는 현재 위치를 내부적으로 변경하지 않습니다. 이는 주로 ~ s# 이 디버거의 내부 루프를 다시 설정할 필요가 없도록 이러한 방식으로 작동합니다.

시간 이동 디버깅 확장 명령

!positions!index 명령에 대한 !tt자세한 내용은 시간 이동 디버깅 - 확장 명령을 참조하세요.

참고 항목

시간 이동 디버깅 - 개요

시간 이동 디버깅 - 추적 기록

시간 이동 디버깅 - 추적 파일 작업

시간 이동 디버깅 - 샘플 앱 연습