时光穿越调试 - 重放跟踪
本部分介绍如何重播时间行程跟踪,以及如何在时间上向前和向后导航。
命令时间行程导航
使用尾随减号和以下命令返回时间。
命令 |
---|
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 (Step) 命令在 TTD 跟踪中前进。
0:000> p
Time Travel Position: F:1
ntdll!LdrpInitializeProcess+0x1bc5:
7774f828 740b je ntdll!LdrpInitializeProcess+0x1bd2 (7774f835) [br=1]
0:000> p
Time Travel Position: F:2
ntdll!LdrpInitializeProcess+0x1bd2:
7774f835 83bdd0feffff00 cmp dword ptr [ebp-130h],0 ss:002b:010ff454=00000000
0:000> p
Time Travel Position: F:3
ntdll!LdrpInitializeProcess+0x1bd9:
7774f83c 0f8450e8ffff je ntdll!LdrpInitializeProcess+0x42f (7774e092) [br=1]
还可以使用 t (跟踪) 命令在跟踪中导航。
0:000> t
Time Travel Position: F:4
ntdll!LdrpInitializeProcess+0x42f:
7774e092 33c0 xor eax,eax
0:000> t
Time Travel Position: F:5
ntdll!LdrpInitializeProcess+0x431:
7774e094 e9f5170000 jmp ntdll!LdrpInitializeProcess+0x1c2b (7774f88e)
使用 p- 命令在 TTD 跟踪中向后单步执行。
0:000> p-
Time Travel Position: F:4
ntdll!LdrpInitializeProcess+0x42f:
7774e092 33c0 xor eax,eax
0:000> p-
Time Travel Position: F:3
ntdll!LdrpInitializeProcess+0x1bd9:
7774f83c 0f8450e8ffff je ntdll!LdrpInitializeProcess+0x42f (7774e092) [br=1]
还可以使用 t- 命令在时间上向后导航。
!tt 导航命令
使用 !tt 命令通过跳过跟踪中的给定位置,在时间上向前或向后导航。
!tt [position]
提供以下任一格式的时间位置,以到达该时间点。
如果 [position] 是介于 0 和 100 之间的十进制数,则它大约会进入跟踪的百分比。 例如
!tt 50
,在跟踪中途旅行。如果 {position} 为 #:#,其中 # 是十六进制数字,则它将前往该位置。 例如,
!tt 1A0:12F
在跟踪中传播到位置 1A0:12F。
有关详细信息,请参阅 Time Travel Debugging - !tt (time travel) 。
!位置
使用 !positions
显示所有活动线程,包括它们在跟踪中的位置。 有关详细信息,请参阅 Time Travel Debugging - !positions (time travel) 。
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 })
使用用户模式 ~ (线程状态) 命令显示相同的八个线程,并使用“.”标记当前线程:
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
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# 不必重置调试器的内部循环。
时间行程调试扩展命令
有关 和 命令的信息!tt
!positions
,!index
请参阅时旅行调试 - 扩展命令。