タイム トラベル デバッグ オブジェクトの概要
このセクションでは、データ モデルを使用してタイム トラベル トレースのクエリを実行する方法について説明します。 これは、タイム トラベル トレースでキャプチャされるコードに関する次のような質問に回答するのに便利なツールです。
- トレースでどのような例外が発生しているか?
- 特定のコード モジュールが、トレース内のどの時点で読み込まれたか?
- トレースにおいてスレッドが作成/終了されたのはいつか?
- トレースにおいて実行時間が最も長いスレッドはどれか?
セッション および プロセス データ モデル オブジェクトにデータを追加する TTD 拡張機能があります。 TTD データ モデル オブジェクトには、 dx (デバッガー オブジェクト モデル式の表示) コマンド、WinDbg のモデル ウィンドウ、JavaScript、C++ を通じてアクセスできます。 TTD 拡張機能はタイム トラベル トレースをデバッグするときに自動的に読み込まれます。
プロセス オブジェクト
プロセス オブジェクトに追加されたプライマリ オブジェクトは、 プロセス オブジェクトの TTD 名前空間にあります。 たとえば、@$curprocess.TTD
のようにします。
0:000> dx @$curprocess.TTD
@$curprocess.TTD
Index
Threads
Events
DebugOutput
Lifetime : [2C8:0, 16EC:98A]
DefaultMemoryPolicy : InFragmentAggressive
SetPosition [Sets the debugger to point to the given position on this process.]
GatherMemoryUse [0]
RecordClients
PrevMemoryAccess [(accessMask, address, size [, address, size, ...]) - Find the previous matching memory access before current position.]
NextMemoryAccess [(accessMask, address, size [, address, size, ...]) - Find the next matching memory access after current position.]
Recorder
LINQ クエリとデバッガー オブジェクトの操作に関する一般的な情報については、「デバッガー オブジェクトでの LINQ の使用」を参照してください。
プロパティ
Object | 説明 |
---|---|
有効期限 | トレース全体の有効期間を記述する TTD 範囲オブジェクト。 |
スレッド | TTD スレッド オブジェクトのコレクションが含まれています (トレースの有効期間中の各スレッドごとに 1 つ)。 |
Events | TTD イベント オブジェクトのコレクションが含まれています (トレース内の各イベントごとに 1 つ)。 |
メソッド
メソッド | 説明 |
---|---|
SetPosition() | 0 から 100 の整数または N:N 形式の文字列を入力として受け取り、その場所にトレースをジャンプします。 詳細については、「!tt」を参照してください。 |
セッション オブジェクト
セッション オブジェクトに追加されたプライマリ オブジェクトは、 セッション オブジェクトの TTD 名前空間にあります。 たとえば、@$cursession.TTD
のようにします。
0:000> dx @$cursession.TTD
@$cursession.TTD
Calls [Returns call information from the trace for the specified set of methods: TTD.Calls("module!method1", "module!method2", ...) For example: dx @$cursession.TTD.Calls("user32!SendMessageA")]
Memory [Returns memory access information for specified address range: TTD.Memory(startAddress, endAddress [, "rwec"])]
MemoryForPositionRange [Returns memory access information for specified address range and position range: TTD.MemoryForPositionRange(startAddress, endAddress [, "rwec"], minPosition, maxPosition)]
PinObjectPosition [Pins an object to the given time position: TTD.PinObjectPosition(obj, pos)]
AsyncQueryEnabled : false
RichQueryTypesEnabled : true
DefaultParameterCount : 0x4
Data : Normalized data sources based on the contents of the time travel trace
Utility : Methods that can be useful when analyzing time travel traces
Analyzers : Methods that perform code analysis on the time travel trace
Bookmarks : Bookmark collection
Checkers : Checkers (scripts for detection of common issues recorded in a time travel trace)
Note
拡張機能の内部関数に使用されるオブジェクトとメソッドが、TTDAnalyze によっていくつか追加されています。 一部の名前空間については文書化がされていません。また、現在の名前空間は徐々に進化します。
メソッド
メソッド | 説明 |
---|---|
Data.Heap() | トレース中に割り当てられた ヒープ オブジェクト のコレクション。 これは評価を行う関数であるため実行に時間がかかることに注意してください。 |
Calls() | 入力文字列に一致する 呼び出しオブジェクト のコレクションを返します。 入力文字列にはワイルドカードを含めることができます。 これは評価を行う関数であるため実行に時間がかかることに注意してください。 |
Memory() | これは beginAddress、endAddress、dataAccessMask の各パラメーターを受け取り、 メモリ オブジェクト のコレクションを返すメソッドです。 これは評価を行う関数であるため実行に時間がかかることに注意してください。 |
クエリ出力の並べ替え
クエリから返された行を 1 つ以上の列で並べ替えるためには、OrderBy() メソッドを使用します。 次の例では、TimeStart で昇順に並べ替えています。
0:000> dx -r2 @$cursession.TTD.Calls("kernelbase!GetLastError").OrderBy(c => c.TimeStart)
@$cursession.TTD.Calls("kernelbase!GetLastError").OrderBy(c => c.TimeStart)
[0x0]
EventType : 0x0
ThreadId : 0x2d98
UniqueThreadId : 0x2
TimeStart : 718:7D7 [Time Travel]
TimeEnd : 718:7DA [Time Travel]
Function : KERNELBASE!GetLastError
FunctionAddress : 0x7ff996cf20f0
ReturnAddress : 0x7ff99855ac5a
ReturnValue : 0x0 [Type: unsigned long]
Parameters
SystemTimeStart : Friday, January 12, 2024 21:18:40.862
SystemTimeEnd : Friday, January 12, 2024 21:18:40.862
[0x1]
EventType : 0x0
ThreadId : 0x2d98
UniqueThreadId : 0x2
TimeStart : 72D:1B3 [Time Travel]
TimeEnd : 72D:1B6 [Time Travel]
Function : KERNELBASE!GetLastError
FunctionAddress : 0x7ff996cf20f0
ReturnAddress : 0x7ff9961538df
ReturnValue : 0x57 [Type: unsigned long]
Parameters
SystemTimeStart : Friday, January 12, 2024 21:18:40.862
SystemTimeEnd : Friday, January 12, 2024 21:18:40.862
...
データ モデル オブジェクトの深度を追加で表示するために、-r2 の再帰レベル オプションが使用されています。 dx コマンドのオプションの詳細については、「dx (デバッガー オブジェクト モデル式の表示)」を参照してください。
次の例では、TimeStart で降順に並べ替えています。
0:000> dx -r2 @$cursession.TTD.Calls("kernelbase!GetLastError").OrderByDescending(c => c.TimeStart)
@$cursession.TTD.Calls("kernelbase!GetLastError").OrderByDescending(c => c.TimeStart)
[0x1896]
EventType : Call
ThreadId : 0x3a10
UniqueThreadId : 0x2
TimeStart : 464224:34 [Time Travel]
TimeEnd : 464224:37 [Time Travel]
Function : UnknownOrMissingSymbols
FunctionAddress : 0x7561ccc0
ReturnAddress : 0x7594781c
ReturnValue : 0x0
Parameters
[0x18a0]
EventType : Call
ThreadId : 0x3a10
UniqueThreadId : 0x2
TimeStart : 464223:21 [Time Travel]
TimeEnd : 464223:24 [Time Travel]
Function : UnknownOrMissingSymbols
FunctionAddress : 0x7561ccc0
ReturnAddress : 0x7594781c
ReturnValue : 0x0
Parameters
クエリにおける要素の指定
特定の要素を選択するために、クエリにはさまざまな修飾子を追加できます。 たとえば、このクエリは "kernelbase!GetLastError" が含まれた最初の呼び出しを表示しています。
0:000> dx @$cursession.TTD.Calls("kernelbase!GetLastError").First()
@$cursession.TTD.Calls("kernelbase!GetLastError").First()
EventType : 0x0
ThreadId : 0x2d98
UniqueThreadId : 0x2
TimeStart : 718:7D7 [Time Travel]
TimeEnd : 718:7DA [Time Travel]
Function : KERNELBASE!GetLastError
FunctionAddress : 0x7ff996cf20f0
ReturnAddress : 0x7ff99855ac5a
ReturnValue : 0x0 [Type: unsigned long]
Parameters
SystemTimeStart : Friday, January 12, 2024 21:18:40.862
SystemTimeEnd : Friday, January 12, 2024 21:18:40.862
クエリでのフィルター処理
表示する列を選択して列の表示名を変更するには、Select() メソッドを使用します。
次の例では、ReturnValue が 0 ではない行を返します。TimeStart 列と ReturnValue 列を、Time と Error のカスタム表示名で表示することを選択しています。
0:000> dx -r2 @$cursession.TTD.Calls("kernelbase!GetLastError").Where(c => c.ReturnValue != 0).Select(c => new { Time = c.TimeStart, Error = c.ReturnValue })
@$cursession.TTD.Calls("kernelbase!GetLastError").Where(c => c.ReturnValue != 0).Select(c => new { Time = c.TimeStart, Error = c.ReturnValue })
[0x1]
Time : 72D:1B3 [Time Travel]
Error : 0x57 [Type: unsigned long]
[0x2]
Time : 72D:1FC [Time Travel]
Error : 0x2af9 [Type: unsigned long]
[0x3]
Time : 72D:26E [Time Travel]
Error : 0x2af9 [Type: unsigned long]
グループ化
クエリによって返されたデータをグループ化し、構造化された結果を使用して分析を実行するには、GroupBy() メソッドを使用します。この例では、エラー番号で時間位置をグループ化しています。
0:000> dx -r2 @$cursession.TTD.Calls("kernelbase!GetLastError").Where(c => c.ReturnValue != 0).Select(c => new { Time = c.TimeStart, Error = c.ReturnValue }).GroupBy(x => x.Error)
@$s = @$cursession.TTD.Calls("kernelbase!GetLastError").Where(c => c.ReturnValue != 0).Select(c => new { Time = c.TimeStart, Error = c.ReturnValue }).GroupBy(x => x.Error)
[0x36b7]
[0x0]
[0x1]
[0x2]
[0x3]
[...]
[0x3f0]
[0x0]
[0x1]
[0x2]
[0x3]
...
変数へのクエリ結果の割り当て
クエリ結果を変数 dx @$var = <expression>
に割り当てるには、この構文を使用
次の例では、クエリ結果を myResults に割り当て
dx -r2 @$myResults = @$cursession.TTD.Calls("kernelbase!GetLastError").Where(c => c.ReturnValue != 0).Select(c => new { Time = c.TimeStart, Error = c.ReturnValue })
dx コマンドを使用すると、-g グリッド オプションを使用して、新しく作成した変数を表示できます。 dx コマンドのオプションの詳細については、「dx (デバッガー オブジェクト モデル式の表示)」を参照してください。
0:000> dx -g @$myResults
========================================
= = (+) Time = (+) Error =
========================================
= [0x13] - 3C64A:834 - 0x36b7 =
= [0x1c] - 3B3E7:D6 - 0x3f0 =
= [0x1d] - 3C666:857 - 0x36b7 =
= [0x20] - 3C67E:12D - 0x2 =
= [0x21] - 3C6F1:127 - 0x2 =
= [0x23] - 3A547:D6 - 0x3f0 =
= [0x24] - 3A59B:D0 - 0x3f0 =
例
例外を求めるクエリの実行
次の LINQ クエリでは、TTD.Event オブジェクトを使用し、トレース内の例外をすべて表示しています。
0:000> dx @$curprocess.TTD.Events.Where(t => t.Type == "Exception").Select(e => e.Exception)
@$curprocess.TTD.Events.Where(t => t.Type == "Exception").Select(e => e.Exception)
[0x0] : Exception 0x000006BA of type Software at PC: 0X777F51D0
[0x1] : Exception 0x000006BA of type Software at PC: 0X777F51D0
[0x2] : Exception 0xE06D7363 of type CPlusPlus at PC: 0X777F51D0
特定の API 呼び出しを求めるクエリの実行
TTD.Calls オブジェクト を使用し、特定の API 呼び出しを求めるクエリを実行します。 この例では、メッセージ ボックスを表示する Windows API、user32!MessageBoxW の呼び出し時にエラーが発生しています。 MessageBoxW への呼び出しをすべて一覧表示し、それを関数の開始時刻で並べ替えてから、最後の呼び出しを選択します。
0:000> dx @$cursession.TTD.Calls("user32!MessageBoxW").OrderBy(c => c.TimeStart).Last()
@$cursession.TTD.Calls("user32!MessageBoxW").OrderBy(c => c.TimeStart).Last()
EventType : Call
ThreadId : 0x3a10
UniqueThreadId : 0x2
TimeStart : 458310:539 [Time Travel]
TimeEnd : 45C648:61 [Time Travel]
Function : UnknownOrMissingSymbols
FunctionAddress : 0x750823a0
ReturnAddress : 0x40cb93
ReturnValue : 0x10a7000000000001
Parameters
特定のモジュールの読み込みイベントを求めるクエリの実行
最初に、 lm (読み込まれたモジュールの一覧表示) コマンドを使用して、読み込まれたモジュールを表示します。
0:000> lm
start end module name
012b0000 012cf000 CDog_Console (deferred)
11570000 1158c000 VCRUNTIME140D (deferred)
11860000 119d1000 ucrtbased (deferred)
119e0000 11b63000 TTDRecordCPU (deferred)
11b70000 11cb1000 TTDWriter (deferred)
73770000 73803000 apphelp (deferred)
73ea0000 74062000 KERNELBASE (deferred)
75900000 759d0000 KERNEL32 (deferred)
77070000 771fe000 ntdll (private pdb symbols)
そのうえで、次の dx コマンドを使用して、特定のモジュール (ntdll など) が読み込まれたトレース内の位置を確認します。
dx @$curprocess.TTD.Events.Where(t => t.Type == "ModuleLoaded").Where(t => t.Module.Name.Contains("ntdll.dll"))
@$curprocess.TTD.Events.Where(t => t.Type == "ModuleLoaded").Where(t => t.Module.Name.Contains("ntdll.dll"))
[0x0] : Module Loaded at position: A:0
この LINQ クエリは、特定のモジュールの読み込みイベントを表示します。
0:000> dx @$curprocess.TTD.Events.Where(t => t.Type == "ModuleUnloaded").Where(t => t.Module.Name.Contains("ntdll.dll"))
@$curprocess.TTD.Events.Where(t => t.Type == "ModuleUnloaded").Where(t => t.Module.Name.Contains("ntdll.dll"))
[0x0] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0
アドレス FFFFFFFFFFFFFFFE:0 はトレースの最後を示します。
トレース内のエラー チェックをすべて求めるクエリの実行
トレース内のすべてのエラー チェックをエラー数で並べ替えるには、次のコマンドを使用します。
0:000> dx -g @$cursession.TTD.Calls("kernelbase!GetLastError").Where( x=> x.ReturnValue != 0).GroupBy(x => x.ReturnValue).Select(x => new { ErrorNumber = x.First().ReturnValue, ErrorCount = x.Count()}).OrderByDescending(p => p.ErrorCount),d
==================================================
= = (+) ErrorNumber = ErrorCount =
==================================================
= [1008] - 1008 - 8668 =
= [14007] - 14007 - 4304 =
= [2] - 2 - 1710 =
= [6] - 6 - 1151 =
= [1400] - 1400 - 385 =
= [87] - 87 - 383 =
スレッドが作成されたトレース内の時間位置を求めるクエリの実行
次の dx コマンドを使用すると、トレース内のすべてのイベントをグリッド形式 (-g) で表示できます。
0:000> dx -g @$curprocess.TTD.Events
==================================================================================================================================================================================================
= = (+) Type = (+) Position = (+) Module = (+) Thread =
==================================================================================================================================================================================================
= [0x0] : Module Loaded at position: 2:0 - ModuleLoaded - 2:0 - Module C:\Users\USER1\Documents\Visual Studio 2015\Proje... - =
= [0x1] : Module Loaded at position: 3:0 - ModuleLoaded - 3:0 - Module C:\WINDOWS\SYSTEM32\VCRUNTIME140D.dll at address 0... - =
= [0x2] : Module Loaded at position: 4:0 - ModuleLoaded - 4:0 - Module C:\WINDOWS\SYSTEM32\ucrtbased.dll at address 0X118... - =
= [0x3] : Module Loaded at position: 5:0 - ModuleLoaded - 5:0 - Module C:\Users\USER1\AppData\Local\Dbg\UI\Fast.20170907... - =
= [0x4] : Module Loaded at position: 6:0 - ModuleLoaded - 6:0 - Module C:\Users\USER1\AppData\Local\Dbg\UI\Fast.20170907... - =
= [0x5] : Module Loaded at position: 7:0 - ModuleLoaded - 7:0 - Module C:\WINDOWS\SYSTEM32\apphelp.dll at address 0X73770... - =
= [0x6] : Module Loaded at position: 8:0 - ModuleLoaded - 8:0 - Module C:\WINDOWS\System32\KERNELBASE.dll at address 0X73... - =
= [0x7] : Module Loaded at position: 9:0 - ModuleLoaded - 9:0 - Module C:\WINDOWS\System32\KERNEL32.DLL at address 0X7590... - =
= [0x8] : Module Loaded at position: A:0 - ModuleLoaded - A:0 - Module C:\WINDOWS\SYSTEM32\ntdll.dll at address 0X7707000... - =
= [0x9] : Thread created at D:0 - ThreadCreated - D:0 - - UID: 2, TID: 0x4C2C =
= [0xa] : Thread terminated at 64:0 - ThreadTerminated - 64:0 - - UID: 2, TID: 0x4C2C =
= [0xb] : Thread created at 69:0 - ThreadCreated - 69:0 - - UID: 3, TID: 0x4CFC =
= [0xc] : Thread created at 6A:0 - ThreadCreated - 6A:0 - - UID: 4, TID: 0x27B0 =
= [0xd] : Thread terminated at 89:0 - ThreadTerminated - 89:0 - - UID: 4, TID: 0x27B0 =
= [0xe] : Thread terminated at 8A:0 - ThreadTerminated - 8A:0 - - UID: 3, TID: 0x4CFC =
= [0xf] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\Users\USER1\Documents\Visual Studio 2015\Proje... - =
= [0x10] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\Users\USER1\AppData\Local\Dbg\UI\Fast.20170907... - =
= [0x11] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\WINDOWS\SYSTEM32\VCRUNTIME140D.dll at address 0... - =
= [0x12] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\Users\USER1\AppData\Local\Dbg\UI\Fast.20170907... - =
= [0x13] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\WINDOWS\SYSTEM32\ucrtbased.dll at address 0X118... - =
= [0x14] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\WINDOWS\SYSTEM32\apphelp.dll at address 0X73770... - =
= [0x15] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\WINDOWS\System32\KERNELBASE.dll at address 0X73... - =
= [0x16] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\WINDOWS\System32\KERNEL32.DLL at address 0X7590... - =
= [0x17] : Module Unloaded at position: FFFFFFFFFFFFFFFE:0 - ModuleUnloaded - FFFFFFFFFFFFFFFE:0 - Module C:\WINDOWS\SYSTEM32\ntdll.dll at address 0X7707000... - =
==================================================================================================================================================================================================
+ 記号が付いた列を選択すると、出力を並べ替えられます。
スレッドが作成 (Type == "ThreadCreated") されたトレース内の時間位置をグリッド形式で表示するには、次の LINQ クエリを使用します。
dx -g @$curprocess.TTD.Events.Where(t => t.Type == "ThreadCreated").Select(t => t.Thread)
===========================================================================================================
= = (+) UniqueId = (+) Id = (+) Lifetime = (+) ActiveTime =
===========================================================================================================
= [0x0] : UID: 2, TID: 0x4C2C - 0x2 - 0x4c2c - [0:0, FFFFFFFFFFFFFFFE:0] - [D:0, 64:0] =
= [0x1] : UID: 3, TID: 0x4CFC - 0x3 - 0x4cfc - [0:0, 8A:0] - [69:0, 8A:0] =
= [0x2] : UID: 4, TID: 0x27B0 - 0x4 - 0x27b0 - [0:0, 89:0] - [6A:0, 89:0] =
===========================================================================================================
スレッドが終了 (Type == "ThreadTerminated") されたトレース内の時間位置をグリッド形式で表示するには、次の LINQ クエリを使用します。
0:000> dx -g @$curprocess.TTD.Events.Where(t => t.Type == "ThreadTerminated").Select(t => t.Thread)
===========================================================================================================
= = (+) UniqueId = (+) Id = (+) Lifetime = (+) ActiveTime =
===========================================================================================================
= [0x0] : UID: 2, TID: 0x4C2C - 0x2 - 0x4c2c - [0:0, FFFFFFFFFFFFFFFE:0] - [D:0, 64:0] =
= [0x1] : UID: 4, TID: 0x27B0 - 0x4 - 0x27b0 - [0:0, 89:0] - [6A:0, 89:0] =
= [0x2] : UID: 3, TID: 0x4CFC - 0x3 - 0x4cfc - [0:0, 8A:0] - [69:0, 8A:0] =
===========================================================================================================
実行時間が最も長いスレッドを特定するための出力の並べ替え
トレース内でおおよそ実行時間の最も長いスレッドをグリッド形式で表示するには、次の LINQ クエリを使用します。
0:000> dx -g @$curprocess.TTD.Events.Where(e => e.Type == "ThreadTerminated").Select(e => new { Thread = e.Thread, ActiveTimeLength = e.Thread.ActiveTime.MaxPosition.Sequence - e.Thread.ActiveTime.MinPosition.Sequence }).OrderByDescending(t => t.ActiveTimeLength)
=========================================================
= = (+) Thread = ActiveTimeLength =
=========================================================
= [0x0] - UID: 2, TID: 0x1750 - 0x364030 =
= [0x1] - UID: 3, TID: 0x420C - 0x360fd4 =
= [0x2] - UID: 7, TID: 0x352C - 0x35da46 =
= [0x3] - UID: 9, TID: 0x39F4 - 0x34a5b5 =
= [0x4] - UID: 11, TID: 0x4288 - 0x326199 =
= [0x5] - UID: 13, TID: 0x21C8 - 0x2fa8d8 =
= [0x6] - UID: 14, TID: 0x2188 - 0x2a03e3 =
= [0x7] - UID: 15, TID: 0x40E8 - 0x29e7d0 =
= [0x8] - UID: 16, TID: 0x124 - 0x299677 =
= [0x9] - UID: 4, TID: 0x2D74 - 0x250f43 =
= [0xa] - UID: 5, TID: 0x2DC8 - 0x24f921 =
= [0xb] - UID: 6, TID: 0x3B1C - 0x24ec8e =
= [0xc] - UID: 10, TID: 0x3808 - 0xf916f =
= [0xd] - UID: 12, TID: 0x26B8 - 0x1ed3a =
= [0xe] - UID: 17, TID: 0x37D8 - 0xc65 =
= [0xf] - UID: 8, TID: 0x45F8 - 0x1a2 =
=========================================================
メモリ範囲への読み取りアクセスを求めるクエリの実行
メモリ範囲への読み取りアクセスを求めるクエリを実行するには、 TTD.Memory オブジェクト を使用します。
スレッド環境ブロック (TEB) は、GetLastError() によって返される結果など、スレッドの状態に関するあらゆる情報を格納している構造です。 このデータ構造に対してクエリを実行するには、現在のスレッドで dx @$teb
を実行します。 TEB のメンバーの 1 つに LastErrorValue 変数があります (サイズは 4 バイト)。 次の構文を使用して、TEB の LastErrorValue メンバーを参照できます。 dx &@$teb->LastErrorValue
.
このクエリ例では、メモリ内のその範囲内で実行されたすべての読み取り操作を検索し、ダイアログが作成される前に発生したすべての読み取りを選択してから、結果を並べ替えて最後の読み取り操作を見つける方法を示しています。
0:000> dx @$cursession.TTD.Memory(&@$teb->LastErrorValue, &@$teb->LastErrorValue + 0x4, "r")
@$cursession.TTD.Memory(&@$teb->LastErrorValue, &@$teb->LastErrorValue + 0x4, "r")
[0x0]
[0x1]
[0x2]
[0x3]
トレースで "ダイアログ" イベントが発生している場合は、クエリを実行して、メモリ内のその範囲内で実行されたすべての読み取り操作を検索し、ダイアログが作成される前に発生したすべての読み取りを選択してから、結果を並べ替えて最後の読み取り操作を見つけることができます。 次に、得られた時間位置で SeekTo() を呼び出して、その時点にタイム トラベルをします。
:000> dx @$cursession.TTD.Memory(&@$teb->LastErrorValue, &@$teb->LastErrorValue + 0x4, "r").Where(m => m.TimeStart < @$dialog).OrderBy(m => m.TimeStart).Last().TimeEnd.SeekTo()
Setting position: 458300:37
ModLoad: 6cee0000 6cf5b000 C:\WINDOWS\system32\uxtheme.dll
ModLoad: 75250000 752e6000 C:\WINDOWS\System32\OLEAUT32.dll
ModLoad: 76320000 7645d000 C:\WINDOWS\System32\MSCTF.dll
ModLoad: 76cc0000 76cce000 C:\WINDOWS\System32\MSASN1.dll
GitHub TTD クエリ ラボ
クエリを使用してタイム トラベル デバッグ記録を使用して C++ コードをデバッグし、問題のあるコードの実行に関する情報を見つける方法のチュートリアルについては、「 WinDbg-Samples - Time Travel Debugging and Queriesを参照してください。
ラボで使用されるすべてのコードはここから入手できます。https://github.com/Microsoft/WinDbg-Samples/tree/master/TTDQueries/app-sample
TTD クエリのトラブルシューティング
関数名としての "UnknownOrMissingSymbols"
データ モデル拡張機能で関数名やパラメーター値などを入力するには、完全なシンボル情報が必要です。完全なシンボル情報が使用できない場合は、デバッガーによって "UnknownOrMissingSymbols" が関数名として使用されます。
- プライベート シンボルがある場合は、関数名とパラメーターの正しい一覧が得られます。
- パブリック シンボルがある場合は、関数名と既定のパラメーター セット (4 つの符号なし 64 ビット整数) が得られます。
- クエリを実行しているモジュールのシンボル情報がない場合は、"UnknownOrMissingSymbols" が名前として使用されます。
呼び出しに対する TTD クエリ
クエリが DLL の呼び出しに対して何も返さない理由はいくつかあります。
- 呼び出しの構文が正しくない。 x (シンボルの検査)
x <call>
を使用して、呼び出し構文を確認してみてください。 x によって返されるモジュール名が大文字の場合は、それを使用します。 - DLL がまだ読み込まれておらず、後からトレースで読み込まれる。 これを回避するには、DLL が読み込まれた後の時点に移動して、クエリを再度実行してください。
- クエリ エンジンが追跡できない呼び出しがインライン化される。
- クエリ パターンでワイルドカードを使用しており、多すぎる関数が返される。 一致する関数の数が十分に少なくなるよう、クエリ パターンをより具体的なものにしてください。
参照
Time Travel Debugging - JavaScript オートメーション