Time Travel Debugging - トレースの再生
このセクションでは、時間を進めたり遡ったりしながら、タイム トラベル トレースを再生する方法について説明します。
コマンドのタイム トラベル ナビゲーション
時間を遡るには、次のコマンドで末尾にマイナス記号を使用します。
コマンド |
---|
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
TTD トレースの順方向実行を停止するには、p (ステップ実行) コマンドを使用します。
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)
TTD トレース内で逆方向にステップ実行するには、p- コマンドを使用します。
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 の 10 進数の場合、そのパーセントで示されるトレース内のおおよその位置に移動します。 たとえば、
!tt 50
にすると、トレースの中間地点まで移動します。[位置] が #:# (#は 16 進数) の場合は、その位置に移動します。 たとえば、
!tt 1A0:12F
にすると、トレース内の 1A0:12F の位置に移動します。
詳細については、「タイム トラベル デバッグ - !tt (タイム トラベル)」を参照してください。
!positions
!positions
を使用すると、すべてのアクティブなスレッドが、それぞれのトレース内の位置を含めて表示されます。 詳細については、「タイム トラベル デバッグ - !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 コマンドの出力で、3 番目のスレッド (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
~ (スレッドの状態) コマンドを使用して、現在 3 番目のスレッド (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
Note
~s# (# はスレッド番号) でも指定したスレッドに切り替わりますが、トレース内の現在の位置は変わりません。 !tt を使用してスレッド内の別の位置に時間移動した場合、デバッガーがメモリから読み取る値は、その位置で参照されます。 ~s# でスレッドを切り替える場合、デバッガーは現在の位置を内部的に変更せず、これがすべてのメモリ クエリに使用されます。 これは主に、~s# によってデバッガーの内部ループがリセットされないようにするための動作です。
タイム トラベル デバッグの拡張コマンド
!tt
コマンド、!positions
コマンド、!index
コマンドの詳細については、「タイム トラベル デバッグ - 拡張コマンド」を参照してください。