时光穿越调试 - 重放跟踪

具有时钟的“时间行程”调试徽标。

本部分介绍如何重播时间行程跟踪,以及如何在时间上向前和向后导航。

命令时间行程导航

使用尾随减号和以下命令返回时间。

命令
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
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]

提供以下任一格式的时间位置,以到达该时间点。

  • 如果 [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
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# 不必重置调试器的内部循环。

时间行程调试扩展命令

有关 和 命令的信息!tt!positions!index请参阅时旅行调试 - 扩展命令

另请参阅

时光穿越调试 - 概述

时间旅行调试 - 记录跟踪

时光穿越调试 - 使用跟踪文件

时光穿越调试 - 示例应用演练