다음을 통해 공유


!tt(시간 이동)

시계가 있는 시간 이동 디버깅 로고입니다.

정시에 앞뒤로 이동할 수 있는 !tt(시간 이동) 디버거 확장입니다.

!tt 탐색 명령

추적에서 지정된 위치로 이동하여 !tt 확장을 사용하여 시간에서 앞으로 또는 뒤로 이동합니다.

!tt [position]

매개 변수

위치

해당 시점으로 이동할 시간 위치를 다음 형식으로 제공합니다.

  • {position}이(가) 0에서 100 사이의 10진수이면, 트레이스의 약 그 백분율 위치로 이동합니다. 다음은 그 예입니다.

    • !tt 0 - 추적의 시작 부분으로의 시간 이동
    • !tt 50 - 추적을 통해 중간에 시간 여행
    • !tt 100 - 추적의 끝까지의 시간 이동
  • {position}이(가) 0에서 100 사이의 부동 소수점 숫자인 경우 추적의 약 해당 비율까지 이동합니다. 다음은 그 예입니다.

    • !tt 0.00 - 추적의 시작 부분으로의 시간 이동
    • !tt 50.1 - 추적을 통해 중간 정도의 시간 이동
    • !tt 99.9 - 추적의 거의 끝까지 시간 여행
  • {position}이 16진수인 #:#이면 해당 위치로 이동합니다. 다음 숫자를 생략하면 기본값은 0입니다.

    • !tt 1A0: - 위치 1A0:0까지의 시간 이동
    • !tt 1A0:0 - 1A0:0 위치로 시간 이동
    • !tt 1A0:12F - 위치 1A0:12F까지의 시간 이동

    비고

    트레이스는 트레이스 내의 특정 위치 참조(예: 12:0)를 참조하는 두 부분으로 구성된 명령 구조를 사용합니다. 또는 15:7. 두 요소는 여기에 설명된 대로 정의된 16진수입니다.

    xx:yy

    xx- 첫 번째 요소는 시퀀싱 이벤트에 해당하는 시퀀싱 번호입니다.

    yy - 두 번째 요소는 시퀀싱 이벤트 이후의 명령 수에 대략 해당하는 단계 수입니다.

!tt break 명령

레지스터에서 중단

!tt br[-] <register> [<value>]

이 명령은 현재 스레드에서 지정된 레지스터가 변경된 값이 있는 이전 또는 다음 위치로 이동하며, <value>가 지정된 경우에는 해당 값이 되는 위치로 이동합니다.

예제:

!tt br rbx 0x12345678 – rbx를 0x12345678 설정하는 현재 스레드에서 다음 위치를 찾습니다.

!tt br- ebx – rbx를 현재 값으로 설정하는 현재 스레드에서 이전 위치를 찾습니다.

0:000> !tt br- ebx

Setting position: 2C8:0
(3b24.2d98): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 2C8:0
ntdll!LdrInitializeThunk:
00007ff9`999e3dd0 4053            push    rbx
  • watchpoint 등록 명령은 x64 및 ARM64와 같이 지원되는 모든 Windows 아키텍처를 지원합니다.
  • 레지스터 감시점은 범용(및 XMM) 레지스터로 제한됩니다.
  • 레지스터 감시점은 일반 추적 재생 속도에 비해 느린 알고리즘으로 구현됩니다. Ctrl+C를 사용하여 검색을 취소할 수 있습니다.

액세스 중단

!tt ba[-] <rwe> <address> <size> [<address> <size> …]

이 명령은 지정된 방식으로 지정된 메모리 범위 중 하나에 액세스하는 이전/다음 위치로 이동합니다. "R"은 메모리 읽기용이고, "W"는 메모리 쓰기용이고" "E"는 실행을 위한 것입니다. 둘 이상의 이름을 동시에 지정할 수 있습니다(예: "RW"). ba (접근 시 중단) 디버거 명령과 비슷합니다.

예: !tt ba- rw 0x12345678 0x4000 – 메모리 범위에서 읽는 이전 위치를 찾습니다. (0x12345678 – 0x12345678 + 0x4000). !tt ba e 0x7fffe0001234 0x30000 – 지정된 범위에서 실행되는 다음 위치를 찾습니다. 주소와 범위가 ntdll.dll범위를 나타내는 척합니다. 이 명령은 ntdll.dll 입력되는 다음 위치를 찾습니다.

  • 주소/크기를 숫자로 제공해야 합니다. 기호는 지원되지 않습니다.

모듈 중단

모듈 탐색 메서드에서 중단을 사용하여 모듈 수준에서 앞뒤로 이동합니다.

!tt bm[-] [<module> ...]

이 명령 시간은 지정된 모듈 중 하나를 실행하는 이전/다음 위치로 이동합니다.

모듈을 지정하지 않으면 현재 실행 중인 모듈 외부의 이전/다음 실행 지점으로 이동합니다.

이 명령을 사용하여 추적에서 이동하는 경우 뒤로 검색은 앞으로 검색하는 것보다 상당히 느립니다.

사용 사례 예

다음은 두 가지 사용 사례 예제입니다.

사용 사례 1 - 현재 스레드의 다른 모듈에 있는 경우 앞으로 또는 뒤로 이동합니다. 이 경우 TTD는 앞으로 dwmcore에서 ucrtbase 모듈로 이동한 다음 ntdll로 뒤로 이동합니다.

추적 예제는 dwmcore 모듈의 예외에서 시작됩니다.

Setting position: 1C46AE:0
(a54.c98): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 1C46AE:0
dwmcore!wil_atomic_uint32_compare_exchange_relaxed+0xc [inlined in dwmcore!wil_details_FeatureReporting_RecordUsageInCache+0x124]:
00007ffa`441e16a0 f0450fb102      lock cmpxchg dword ptr [r10],r8d ds:00007ffa`444b0450=00000003

!tt bm commmand를 실행합니다. 모듈이 지정되지 않은 경우 현재 실행 중인 모듈인 ucrtbase 외부의 다음 실행 지점으로 이동합니다.

0:001> !tt bm
Replaying - Currently at 1D1BEE:0 (  2.95%)
Setting position: 1C46AF:61
(a54.c98): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 1C46AF:61
ucrtbase!_finite:
00007ffa`4ac3c080 48b9ffffffffffffff7f mov rcx,7FFFFFFFFFFFFFFFh

해당 위치에서 한 단계씩 실행하면 TTD에서 모듈 경계를 올바르게 찾았습니다.

0:001> t-
Time Travel Position: 1C46AF:60
dwmcore!CBaseExpression::IsExpressionValueValid+0x50:
00007ffa`44124b40 48ff15f9db2700  call    qword ptr [dwmcore!_imp__finite (00007ffa`443a2740)] ds:00007ffa`443a2740={ucrtbase!_finite (00007ffa`4ac3c080)}

(a54.c98): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 1C46AE:0
dwmcore!wil_atomic_uint32_compare_exchange_relaxed+0xc [inlined in dwmcore!wil_details_FeatureReporting_RecordUsageInCache+0x124]:
00007ffa`441e16a0 f0450fb102      lock cmpxchg dword ptr [r10],r8d ds:00007ffa`444b0450=00000003

뒤로 검색하여 다음 모듈 경계를 검색합니다.

0:001> !tt bm-
Setting position: 1C46AD:2B1
(a54.c98): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 1C46AD:2B1
ntdll!LdrpDispatchUserCallTarget+0x3b:
00007ffa`4d27f24b 48ffe0          jmp     rax {dwmcore!CKeyframeAnimation::CalculateValueWorker (00007ffa`441264e0)}

그런 다음 모듈 경계에서 다음 모듈로 이동합니다.

0:001> t
Time Travel Position: 1C46AD:2B2
dwmcore!CKeyframeAnimation::CalculateValueWorker:
00007ffa`441264e0 48895c2408      mov     qword ptr [rsp+8],rbx ss:0000004e`5151f4d0=0000000000000000
사용 사례 2 - 모듈이 입력될 때까지 앞으로 이동합니다. 이 예제에서는 ntdll입니다.
0:001> !tt bm ntdll
Replaying - Currently at 1CBF15:0 (  1.66%)
Setting position: 1C46B0:97
(a54.c98): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 1C46B0:97
ntdll!LdrpDispatchUserCallTarget:
00007ffa`4d27f210 4c8b1db1c11000  mov     r11,qword ptr [ntdll!LdrSystemDllInitBlock+0xb8 (00007ffa`4d38b3c8)] ds:00007ffa`4d38b3c8=00007df503990000

뒤로 검색하는 데 사용할 !tt bm- <module> 수 있습니다.

데이터 모델 - NextModuleAccess 및 PrevModuleAccess

dx(디버거 개체 모델 식 표시) 명령과 NextModuleAccess 및 PrevModuleAccess 데이터 모델 개체를 사용하여 !tt 명령에서 사용할 수 있는 동일한 기능에 액세스합니다.

다음 모듈 액세스 경계로 이동합니다.

0:001> dx @$curprocess.TTD.NextModuleAccess()
Replaying - Currently at 1D1BEE:0 (  2.95%)
@$curprocess.TTD.NextModuleAccess() : [UTID 3] Execute [1C46AE:0] -> [1C46AF:61] ucrtbase 0x7ffa4ac3c080
    Position         : 1C46AF:61
    OriginalPosition : 1C46AE:0
    UniqueThreadId   : 0x3
    AccessType       : Execute
    Address          : 0x7ffa4ac3c080
    ModuleName       : ucrtbase

다음 이전 액세스 경계로 뒤로 이동합니다.

0:001> dx @$curprocess.TTD.PrevModuleAccess()
@$curprocess.TTD.PrevModuleAccess() : [UTID 3] Execute [1C46AE:0] -> [1C46AD:2B1] ntdll 0x7ffa4d27f24b
    Position         : 1C46AD:2B1
    OriginalPosition : 1C46AE:0
    UniqueThreadId   : 0x3
    AccessType       : Execute
    Address          : 0x7ffa4d27f24b
    ModuleName       : ntdll

다음 ntdll 모듈 액세스 경계로 이동합니다.

0:001> dx @$curprocess.TTD.NextModuleAccess("ntdll")
Replaying - Currently at 1CBF15:0 (  1.66%)
@$curprocess.TTD.NextModuleAccess("ntdll") : [UTID 3] Execute [1C46AE:0] -> [1C46B0:97] ntdll 0x7ffa4d27f210
    Position         : 1C46B0:97
    OriginalPosition : 1C46AE:0
    UniqueThreadId   : 0x3
    AccessType       : Execute
    Address          : 0x7ffa4d27f210
    ModuleName       : ntdll

TTD 중단점에 디버거 모델 개체 사용

메모리 액세스 중단 기능은 dx(디버거 개체 모델 식 표시) 명령, 디버거 데이터 모델 창, JavaScript 및 C++를 통해 액세스할 수 있습니다. LINQ 쿼리 및 디버거 개체 작업에 대한 일반적인 내용은 디버거 개체와 함께 LINQ 사용을 참조 하세요.

TTD.PrevRegisterWrite

dx @$curthread.TTD.PrevRegisterWrite("<reg>" [, <value>])

이 메서드는 현재 스레드에서 지정된 레지스터가 값을 변경한 이전 위치(또는 지정된 경우 <value> 지정된 값이 되는 위치)를 검색합니다. 위치로 !tt br- 자동으로 이동하지 않는다는 점을 제외하면 위의 명령과 유사합니다. 대신 다음과 같은 정보를 반환합니다.

0:000> dx @$curthread.TTD.PrevRegisterWrite("rbx")

@$curthread.TTD.PrevRegisterWrite("rbx")                 : [UTID 2] rbx [2C8:0] 0x0 -> [2C8:0] 0x0
    Register         : rbx
    Position         : 2C8:0 [Time Travel]
    Value            : 0x0
    OriginalPosition : 2C8:0 [Time Travel]
    OriginalValue    : 0x0
    UniqueThreadId   : 0x2

비슷하게, @$curthread.TTD.NextRegisterWrite(…) 함수를 사용하여 다음 레지스터 변경을 검색할 수 있습니다.

0:000> dx @$curthread.TTD.NextRegisterWrite("rbx")

@$curthread.TTD.NextRegisterWrite("rbx")                 : [UTID 2] rbx [2C8:1] 0x0 -> [2C8:2] 0x963127f5a0
    Register         : rbx
    Position         : 2C8:2 [Time Travel]
    Value            : 0x963127f5a0
    OriginalPosition : 2C8:1 [Time Travel]
    OriginalValue    : 0x0
    UniqueThreadId   : 0x2

출력의 [시간 이동] 링크를 사용하여 추적의 해당 위치로 이동합니다.

0:000> dx -s @$create("Debugger.Models.TTD.Position", 712, 0).SeekTo()
(3b24.2d98): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 2C8:0

TTD.PrevMemoryAccess

dx @$curprocess.TTD.PrevMemoryAccess("<rwe>", <address>, <size> [, <address>, <size> …])

이 메서드는 지정된 메모리 범위 중 하나가 지정된 방식으로 액세스되는 이전 위치를 검색합니다. 위치로 자동으로 이동하지 않는다는 점을 제외하면 위의 !tt ba- 명령과 유사합니다. 대신 다음과 같은 정보를 반환합니다.

@$curprocess.TTD.PrevMemoryAccess("w", 0x01a16a939820, 0x10) : [UTID 3] Write 0x1a16a939828 4 bytes [1C46AE:0] -> [1C4575:0]
   Position         : 1C4575:0
   OriginalPosition : 1C46AE:0
   UniqueThreadId   : 0x3
   Address          : 0x1a16a939828
   Size             : 0x4
   AccessType       : Write

마찬가지로 다음 메모리 액세스를 검색하는 데 사용할 @$curprocess.TTD.NextMemoryAccess(…) 수 있습니다.

0:000> dx @$curprocess. TTD. NextMemoryAccess("r", 0x00007ff9`95420000, 0xFF)

@$curprocess.TTD.NextMemoryAccess("r", 0x00007ff9`95420000, 0xFF)                 : [UTID 2] Read 0x7ff995420000 2 bytes [2C8:0] -> [66C:10A2]
    Position         : 66C:10A2 [Time Travel]
    OriginalPosition : 2C8:0 [Time Travel]
    UniqueThreadId   : 0x2
    Address          : 0x7ff995420000
    Size             : 0x2
    AccessType       : Read

!tt DLL

ttdext.dll

추가 정보

이 확장은 시간 이동 추적에서만 작동합니다. 시간 여행에 대한 자세한 내용은 시간 여행 디버깅 - 개요를 참조하세요.

또한 참조하십시오

시간 이동 디버깅 - 개요