Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
A extensão do depurador !tt (time travel) permite navegar para a frente e para trás no tempo.
!tt comandos de navegação
Use a extensão !tt para navegar para frente ou para trás no tempo, viajando para uma determinada posição no rastreamento.
!tt [position]
Parâmetros
posição
Forneça uma posição temporal em qualquer um dos seguintes formatos para viajar até aquele momento no tempo.
Se {position} for um número decimal entre 0 e 100, ele avança aproximadamente essa percentagem no traço. Por exemplo:
- !tt 0 - Viagem no tempo até ao início do traço
- !tt 50 - Viagem no tempo até a metade do traço
- !tt 100 - Viagem no tempo até ao fim do rastro
Se {position} é um número de ponto flutuante entre 0 e 100, ele atinge aproximadamente essa percentagem no traçado. Por exemplo:
- !tt 0.00 - Viagem no tempo até ao início do rastreio
- !tt 50.1 - Viagem no tempo até pouco mais da metade do traço
- !tt 99.9 - Viagem no tempo até quase o fim do traço
Se {position} é #:#, onde # é um número hexadecimal, ele viaja para essa posição. Se o número após : for omitido, assume o valor zero.
- !tt 1A0: - Viagem no tempo até a posição 1A0:0
- !tt 1A0:0 - Viagem no tempo até à posição 1A0:0
- !tt 1A0:12F - Viagem no tempo para a posição 1A0:12F
Observação
Os rastreamentos usam uma posição de instrução de duas partes que faz referência a uma referência de posição específica no rastreamento, por exemplo, 12:0. ou 15:7. Os dois elementos são números hexadecimais definidos como descrito aqui.
xx:yy
xx- O primeiro elemento é o número de sequenciamento, que corresponde a um evento de sequenciamento.
yy - o segundo elemento é uma contagem de passos, que corresponde aproximadamente à contagem de instruções desde o evento de sequenciamento.
!tt comandos de interrupção
Quebra no registo
!tt br[-] <register> [<value>]
Este comando navegará até a posição anterior/seguinte onde o registro especificado alterou os valores (ou, se <value> for especificado, torna-se o valor especificado) no thread atual.
Exemplos:
!tt br rbx 0x12345678 – Encontre a próxima posição no thread atual que define RBX para 0x12345678.
!tt br- ebx – Encontre a posição anterior no thread atual que definiu RBX para seu valor atual.
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
- O comando register watchpoint suporta todas as arquiteturas Windows suportadas, como x64 e ARM64.
- O ponto de observação do registo limita-se aos registos de uso geral (e XMM).
- O ponto de observação do registro é implementado com um algoritmo que é lento em comparação com a velocidade normal de reprodução de rastreamento. A pesquisa pode ser cancelada usando Ctrl+C.
Pausa no acesso
!tt ba[-] <rwe> <address> <size> [<address> <size> …]
Este comando navegará até a posição anterior/seguinte onde um dos intervalos de memória especificados é acessado da(s) maneira(s) especificada(s): "R" é para leitura de memória, "W" é para gravação de memória e "E" é para execução. Mais de um pode ser especificado simultaneamente, ou seja, "RW". Isso é semelhante ao comando do depurador ba (Break on Access).
Exemplos: !tt ba- rw 0x12345678 0x4000 – encontrar a posição anterior que realiza a leitura a partir do intervalo de memória. (0x12345678 – 0x12345678 + 0x4000).
!tt ba e 0x7fffe0001234 0x30000 – encontrar a próxima posição que executa a partir do intervalo especificado. Imagine que o endereço e o intervalo correspondem ao intervalo de ntdll.dll. Este comando encontraria a próxima posição onde ntdll.dll é inserido.
- Os endereços/tamanhos devem ser fornecidos como números. Não há suporte para símbolos.
Interrupção no módulo
Utilize o método de navegação "Interromper no módulo" para avançar ou retroceder ao nível do módulo.
!tt bm[-] [<module> ...]
Este comando viaja no tempo para a posição anterior/seguinte que executa um dos módulos especificados.
Se nenhum módulo for especificado, ele viajará para o ponto de execução anterior/seguinte fora do módulo atualmente em execução.
Ao usar esse comando para mover no rastreamento, a pesquisa para trás é consideravelmente mais lenta do que a pesquisa para frente.
Exemplos de casos de uso
Aqui estão dois exemplos de casos de uso.
Caso de uso 1 - Avance ou retroceda até estar num módulo diferente na thread atual. Neste caso, o TTD move-se do módulo dwmcore para o módulo ucrtbase, avançando e depois retrocedendo para o ntdll.
O exemplo de rastreamento começa em uma exceção no módulo 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
Executa o comando !tt bm. Como nenhum módulo é especificado, viaje para o próximo ponto de execução fora do módulo atualmente em execução - 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
Uma única etapa a partir desse local, o TTD encontrou corretamente o limite do módulo.
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
Pesquise para trás o próximo limite do módulo.
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)}
Em seguida, avance do limite do módulo para o próximo módulo.
0:001> t
Time Travel Position: 1C46AD:2B2
dwmcore!CKeyframeAnimation::CalculateValueWorker:
00007ffa`441264e0 48895c2408 mov qword ptr [rsp+8],rbx ss:0000004e`5151f4d0=0000000000000000
Caso de uso 2 - Avançar até que um módulo seja inserido. Neste exemplo, 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
Você pode usar !tt bm- <module> para pesquisar para trás.
Modelo de Dados - NextModuleAccess e PrevModuleAccess
Use o comando dx (Display Debugger Object Model Expression) e os objetos de modelo de dados NextModuleAccess e PrevModuleAccess para acessar a mesma funcionalidade, que está disponível no comando !tt.
Siga em frente para o próximo limite de acesso do módulo.
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
Viaje para trás até o próximo limite de acesso anterior.
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
Siga em frente para o próximo limite de acesso ao módulo 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
Usar objetos de modelo do depurador para pontos de interrupção TTD
A funcionalidade de quebra no acesso à memória pode ser acessada através do comando dx (Display Debugger Object Model Expression), as janelas do modelo de dados dos depuradores, JavaScript e C++. Para obter informações gerais sobre como trabalhar com consultas LINQ e objetos do depurador, consulte Usando o LINQ com os objetos do depurador.
TTD.PrevRegisterWrite
dx @$curthread.TTD.PrevRegisterWrite("<reg>" [, <value>])
Este método procura a posição anterior onde o registro especificado alterou valores (ou, se <value> for especificado, torna-se o valor especificado) no thread atual. É análogo ao !tt br- comando acima, exceto que não navega automaticamente para a posição. Em vez disso, ele retorna informações como as seguintes:
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
Da mesma forma, você pode usar @$curthread. TTD. NextRegisterWrite(...) para procurar a próxima alteração de registo.
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
Use os links [Viagem no Tempo] no resultado para se deslocar para essa posição no rastreamento.
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> …])
Este método procura a posição anterior onde um dos intervalos de memória especificados é acessado da(s) maneira(s) especificada(s). É análogo ao comando !tt ba- acima, exceto que não navega automaticamente para a posição. Em vez disso, ele retorna informações como as seguintes:
@$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
Da mesma forma, você pode usar @$curprocess.TTD.NextMemoryAccess(…) para procurar o próximo acesso à memória.
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
Informação Adicional
Esta extensão só funciona com vestígios de viagem no tempo. Para obter mais informações sobre viagem no tempo, consulte Depuração de viagem no tempo - Visão geral.