Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
"Zaman yolculuğu hata ayıklama logosu, bir saat içerir
"
JavaScript otomasyonunu kullanarak TTD izlemeleriyle komut otomasyonu veya izleme dosyasından olay verilerini bulmak için sorgular kullanma gibi çeşitli yollarla çalışabilirsiniz.
JavaScript ile çalışma hakkında genel bilgi için bkz. JavaScript Hata Ayıklayıcı Betiği. JavaScript Hata Ayıklayıcısı Örnek Betikleride vardır.
JavaScript TTD Komut Otomasyonu
TTD otomasyonu için JavaScript kullanmanın bir yolu, zaman yolculuğu izleme dosyalarıyla çalışmayı otomatikleştirmeye yönelik komutlar göndermektir.
İz dosyasında hareket etme
Bu JavaScript, !tt komutunu kullanarak bir zaman yolculuğu izinin başlangıcına nasıl geçileceğini gösterir.
var dbgControl = host.namespace.Debugger.Utility.Control;
dbgControl.ExecuteCommand("!tt 0",false);
host.diagnostics.debugLog(">>> Sent command to move to the start of the TTD file \n");
Bunu bir ResetTrace işlevine dönüştürebilir ve WinDbg'deki JavaScript kullanıcı arabirimini kullanarak MyTraceUtils.jsolarak kaydedebiliriz.
// My Trace Utils
// WinDbg TTD JavaScript MyTraceUtilsCmd Sample
"use strict";
function MyTraceUtilsCmd()
{
var dbgControl = host.namespace.Debugger.Utility.Control;
dbgControl.ExecuteCommand("!tt 0",false);
host.diagnostics.debugLog(">>> Sent command to move to the start of the TTD file \n");
}
WinDbg'de bir TTD dosyası yüklendikten sonra hata ayıklayıcı komut penceresindeki dx komutunu kullanarak ResetTraceCmd() işlevini çağırın.
0:000> dx Debugger.State.Scripts.MyTraceUtils.Contents.ResetTraceCmd()
>>> Sent command to move to the start of the TTD file
Debugger.State.Scripts.MyTraceUtils.Contents.ResetTraceCmd()
Komut gönderme sınırlamaları
Ancak en basit durumlar dışında komut gönderme yaklaşımının dezavantajları vardır. Metin çıkışının kullanımına dayanır. Bu çıkışı ayrıştırmak, kırılgan ve bakımı zor olan kodlara yol açar. TTD nesnelerini doğrudan kullanmak daha iyi bir yaklaşımdır.
Aşağıdaki örnekte, nesneleri doğrudan kullanarak aynı görevi tamamlamak için nesnelerin doğrudan nasıl kullanılacağı gösterilmektedir.
// My Trace Utils
// WinDbg TTD JavaScript ResetTrace Sample
"use strict";
function ResetTrace()
{
host.currentProcess.TTD.SetPosition(0);
host.diagnostics.debugLog(">>> Set position to the start of the TTD file \n");
}
Bu kodu çalıştırmak, izleme dosyasının başlangıcına geçebileceğimizi gösterir.
0:000> dx Debugger.State.Scripts.MyTraceUtils.Contents.ResetTrace()
(948.148c): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: F:0
>>> Set position to the start of the TTD file
Bu örnekte ResetTraceEnd işlevi, konum izlemenin sonuna ayarlanır ve geçerli ve yeni konum currentThread.TTD Position nesnesi kullanılarak görüntülenir.
// WinDbg TTD JavaScript Sample to Reset Trace using objects directly
// and display current and new position
function ResetTraceEnd()
{
var PositionOutputStart = host.currentThread.TTD.Position;
host.diagnostics.debugLog(">>> Current position in trace file: "+ PositionOutputStart +"\n");
host.currentProcess.TTD.SetPosition(100);
var PositionOutputNew = host.currentThread.TTD.Position;
host.diagnostics.debugLog(">>> New position in trace file: "+ PositionOutputNew +"\n");
}
Bu kodu çalıştırmak, geçerli ve yeni konumu görüntüler.
0:000> dx Debugger.State.Scripts.MyTraceUtils.Contents.ResetTraceEnd()
>>> Current position in trace file: F:0
(948.148c): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: D3:1
>>> New position in trace file: D3:1
Bu genişletilmiş örnekte başlangıç ve bitiş konumu değerleri, izlemedeki konumun değişip değişmediğini görmek için karşılaştırılır.
// WinDbg TTD JavaScript ResetTraceEx Sample
"use strict";
function ResetTraceEx()
{
const PositionOutputStart = host.currentThread.TTD.Position;
host.diagnostics.debugLog(">>> Current position in trace file: "+ PositionOutputStart +"\n");
host.currentProcess.TTD.SetPosition(0);
const PositionOutputNew = host.currentThread.TTD.Position;
host.diagnostics.debugLog(">>> New position in trace file: "+ PositionOutputNew +"\n");
if (parseInt(PositionOutputStart,16) != parseInt(PositionOutputNew,16))
{
host.diagnostics.debugLog(">>> Set position to the start of the TTD file \n");
}
else
{
host.diagnostics.debugLog(">>> Position was already set to the start of the TTD file \n");
}
}
Bu örnek çalıştırmada, izleme dosyasının başında hazır olduğumuzu belirten bir ileti görüntülenir.
0:000> dx Debugger.State.Scripts.MyTraceUtils.Contents.ResetTraceEx()
>>> Current position in trace file: F:0
(948.148c): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: F:0
>>> New position in trace file: F:0
>>> Position was already set to the start of the TTD file
Betiği test etmek için izleme dosyasının yarısına gitmek için !tt komutunu kullanın.
0:000> !tt 50
Setting position to 50% into the trace
Setting position: 71:0
Betiği çalıştırmak artık konumun TTD izlemesinin başlangıcına ayarlandığını belirten uygun iletiyi görüntüler.
0:000> dx Debugger.State.Scripts.MyTraceUtils.Contents.ResetTraceEx()
>>> Current position in trace file: 71:0
(948.148c): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: F:0
>>> New position in trace file: F:0
>>> Set position to the start of the TTD file
Zaman yolculuğu izleme dosyasının dizinini oluşturma
Yalnızca bir izleme dosyası farklı bir bilgisayara kopyalanırsa yeniden dizine alınması gerekir. Daha fazla bilgi için bkz. Zaman Yolculuğu Hata Ayıklama - İzleme Dosyalarıyla Çalışma.
Bu kod, bir izleme dosyasının yeniden dizininin ne kadar sürdüğünü gösteren örnek bir IndexTrace işlevi gösterir.
function IndexTrace()
{
var timeS = (new Date()).getTime();
var output = host.currentProcess.TTD.Index.ForceBuildIndex();
var timeE = (new Date()).getTime();
host.diagnostics.debugLog("\n>>> Trace was indexed in " + (timeE - timeS) + " ms\n");
}
Küçük bir izleme dosyasının çıktısı aşağıdadır.
0:000> dx Debugger.State.Scripts.MyTraceUtils.Contents.IndexTrace()
>>> Trace was indexed in 2 ms
Bir try catch deyimi ekleme
Dizin oluşturma çalıştırıldığında hataların oluşup oluşmadığını denetlemek için, dizin oluşturma kodunu try catch bloğuna alın.
function IndexTraceTry()
{
var timeS = (new Date()).getTime();
try
{
var IndexOutput = host.currentProcess.TTD.Index.ForceBuildIndex();
host.diagnostics.debugLog("\n>>> Index Return Value: " + IndexOutput + "\n");
var timeE = (new Date()).getTime();
host.diagnostics.debugLog("\n>>> Trace was successfully indexed in " + (timeE - timeS) + " ms\n");
}
catch(err)
{
host.diagnostics.debugLog("\n>>> Index Failed! \n");
host.diagnostics.debugLog("\n>>> Index Return Value: " + IndexOutput + "\n");
host.diagnostics.debugLog("\n>>> Returned error: " + err.name + "\n");
}
}
Dizin oluşturma başarılı olursa betik çıktısı aşağıdadır.
0:000> dx Debugger.State.Scripts.MyTraceUtils.Contents.IndexTraceTry()
>>> Index Return Value: Loaded
>>> Trace was successfully indexed in 1 ms
İzleme dizine alınamıyorsa, örneğin izleme hata ayıklayıcıya yüklenmediyse, yakalama döngüsü kodu çalıştırılır.
0:007> dx Debugger.State.Scripts.MyTraceUtils.Contents.IndexTraceTry()
>>> Index Failed!
>>> Index Return Value: undefined
>>> Returned error: TypeError
JavaScript TTD Nesneleri Sorguları
JavaScript ve TTD'nin daha gelişmiş bir kullanımı, izlemede gerçekleşen belirli çağrıları veya olayları bulmak için zaman yolculuğu nesnelerini sorgulamaktır. TTD nesneleri hakkında daha fazla bilgi için bkz:
Zaman Yolculuğu Hata Ayıklama Nesnelerine Giriş
JavaScript Uzantılarında Yerel Hata Ayıklayıcı Nesneleri - Hata Ayıklayıcı Nesne Ayrıntıları
dx komutu, hata ayıklayıcı veri modelinden bilgileri görüntüler ve LINQ söz dizimini kullanarak sorguları destekler. Dx, nesneleri gerçek zamanlı olarak sorgulamak için çok kullanışlıdır. Bu, daha sonra JavaScript kullanılarak otomatikleştirilebilir istenen sorgunun prototipini oluşturmanızı sağlar. dx komutu, nesne modelini keşfederken yararlı olabilecek sekme tamamlama sağlar. LINQ sorguları ve hata ayıklayıcı nesneleriyle çalışma hakkında genel bilgi için bkz. LINQ'yi hata ayıklayıcı nesneleriyle kullanma.
Bu dx komutu, getLastError bu örnekte belirli bir API'ye yapılan tüm çağrıları sayar.
0:000> dx @$cursession.TTD.Calls("kernelbase!GetLastError").Count()
@$cursession.TTD.Calls("kernelbase! GetLastError").Count() : 0x12
Bu komut, GetLastError'ın ne zaman çağrıldığını görmek için tüm zaman yolculuğu izlemesine bakar.
0:000> dx @$cursession.TTD.Calls("kernelbase!GetLastError").Where(c => c.ReturnValue != 0)
@$cursession.TTD.Calls("kernelbase!GetLastError").Where(c => c.ReturnValue != 0)
[0x0]
[0x1]
[0x2]
[0x3]
TTD.Calls Nesnesi için çağrıları bulmak amacıyla dize karşılaştırmaları
Bu örnek komut, belirli çağrıları bulmak için dize karşılaştırmalarının nasıl kullanılacağını gösterir. Bu örnekte sorgu, CreateFileW işlevinin lpFileName parametresinde "OLE" dizesini arar.
dx -r2 @$cursession.TTD.Calls("kernelbase!CreateFileW").Where(x => x.Parameters.lpFileName.ToDisplayString("su").Contains("OLE"))
".Select deyimini ekleyin ve Timestart ile lpFileName parametresinin değerini yazdırın."
dx -r2 @$cursession.TTD.Calls("kernelbase!CreateFileW").Where(x => x.Parameters.lpFileName.ToDisplayString("su").Contains("OLE")).Select(x => new { TimeStart = x.TimeStart, lpFileName = x.Parameters.lpFileName })
TTD.Calls nesnesi, hedef bilgileri içeren bir nesne bulunduğunda bu çıktıyı oluşturur.
[0x0]
TimeStart : 6E37:590
lpFileName : 0x346a78be90 : "C:\WINDOWS\SYSTEM32\OLEACCRC.DLL" [Type: wchar_t *]
İzlemedeki çağrı sayısını görüntüleme
Çalışmak istediğiniz nesneleri keşfetmek için dx komutunu kullandıktan sonra JavaScript ile bunların kullanımını otomatikleştirebilirsiniz. Bu basit örnekte, TTD.Calls nesnesi, kernelbase!GetLastErrorişlevine yapılan çağrıları saymak için kullanılır.
function CountLastErrorCalls()
{
var LastErrorCalls = host.currentSession.TTD.Calls("kernelbase!GetLastError");
host.diagnostics.debugLog(">>> GetLastError calls in this TTD recording: " + LastErrorCalls.Count() +" \n");
}
Betiği bir TTDUtils.js dosyasına kaydedin ve izleme dosyasındaki kernelbase!GetLastError sayısını görüntülemek için dx komutunu kullanarak çalıştırın.
0:000> dx Debugger.State.Scripts.MyTraceUtils.Contents.CountLastErrorCalls()
>>> GetLastError calls in this TTD recording: 18
Çerçeveleri bir yığın halinde görüntüleme
Çerçeveleri bir yığında görüntülemek için bir dizi kullanılır.
function DisplayStack()
{
// Create an array of stack frames in the current thread
const Frames = Array.from(host.currentThread.Stack.Frames);
host.diagnostics.debugLog(">>> Printing stack \n");
// Print out all of the frame entries in the array
for(const [Idx, Frame] of Frames.entries())
{
host.diagnostics.debugLog(">>> Stack Entry -> " + Idx + ": "+ Frame + " \n");
}
}
Bu örnek izlemede tek bir yığın girişi görüntülenir.
0:000> dx Debugger.State.Scripts.MyTraceUtils.Contents.DisplayStack()
>>> Printing stack
>>> Stack Entry -> 0: ntdll!LdrInitializeThunk + 0x21
Bir olayı bulma ve yığını görüntüleme
Bu kodda tüm özel durumlar olayları bulunur ve her birine gitmek için bir döngü kullanılır. Ardından, TTD İş Parçacığı Nesneleri currentThread.ID iş parçacığı kimliğini görüntülemek için kullanılır ve currentThread.Stack yığındaki tüm çerçeveleri görüntülemek için kullanılır.
function HardwareExceptionDisplayStack()
{
var exceptionEvents = host.currentProcess.TTD.Events.Where(t => t.Type == "Exception");
for (var curEvent of exceptionEvents)
{
// Move to the current event position
curEvent.Position.SeekTo();
host.diagnostics.debugLog(">>> The Thread ID (TID) is : " + host.currentThread.Id + "\n");
// Create an array of stack frames in the current thread
const Frames = Array.from(host.currentThread.Stack.Frames);
host.diagnostics.debugLog(">>> Printing stack \n");
// Print out all of the frame entries in the array
for(const [Idx, Frame] of Frames.entries()) {
host.diagnostics.debugLog(">>> Stack Entry -> " + Idx + ": "+ Frame + " \n");
}
host.diagnostics.debugLog("\n");
}
}
Çıkışta özel durum olayının konumu, TID ve yığın çerçeveleri gösterilir.
0:000> dx Debugger.State.Scripts.MyTraceUtils.Contents.HardwareExceptionDisplayStack()
(948.148c): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 91:0
>>> The Thread ID (TID) is : 5260
>>> Printing stack
>>> Stack Entry -> 0: 0x540020
>>> Stack Entry -> 1: 0x4d0049
>>> Stack Entry -> 2: DisplayGreeting!__CheckForDebuggerJustMyCode + 0x16d
>>> Stack Entry -> 3: DisplayGreeting!mainCRTStartup + 0x8
>>> Stack Entry -> 4: KERNEL32!BaseThreadInitThunk + 0x19
>>> Stack Entry -> 5: ntdll!__RtlUserThreadStart + 0x2f
>>> Stack Entry -> 6: ntdll!_RtlUserThreadStart + 0x1b
Bir olayı bulma ve iki komut gönderme
TTD nesnelerini sorgulama ve komut gönderme gerektiğinde birleştirilebilir. Bu örnek, TTD izleme kaydında ThreadCreated türündeki her olayı bulur, o konuma geçer ve iş parçacığı durumunu görüntülemek için ~ Thread Status ve !runaway komutlarını gönderir.
function ThreadCreateThreadStatus()
{
var threadEvents = host.currentProcess.TTD.Events.Where(t => t.Type == "ThreadCreated");
for (var curEvent of threadEvents)
{
// Move to the current event position
curEvent.Position.SeekTo();
// Display Information about threads
host.namespace.Debugger.Utility.Control.ExecuteCommand("~", false);
host.namespace.Debugger.Utility.Control.ExecuteCommand("!runaway 7", false);
}
}
Kodu çalıştırmak, bir özel durum meydana geldiğinde o anda iş parçacığı durumunu görüntüler.
0:000> dx Debugger.State.Scripts.MyTraceUtils.Contents.ThreadCreateThreadStatus()
(948.148c): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: F:0
. 0 Id: 948.148c Suspend: 4096 Teb: 00a33000 Unfrozen
User Mode Time
Thread Time
0:148c 0 days 0:00:00.000
Kernel Mode Time
Thread Time
0:148c 0 days 0:00:00.000
Elapsed Time
Thread Time
0:148c 3474 days 2:27:43.000
Yardımcı program işlevlerini birbirine zincirleme
Bu son örnekte, daha önce oluşturduğumuz yardımcı program işlevlerini çağırabiliriz. Önce IndexTraceTry kullanarak izlemenin dizinini oluşturacağız ve ardından ThreadCreateThreadStatusçağrısı yapacağız. Ardından izleme işleminin başlangıcına gitmek için ResetTrace kullanırız ve son olarak HardwareExceptionDisplayStackçağırırız.
function ProcessTTDFiles()
{
try
{
IndexTraceTry()
ThreadCreateThreadStatus()
ResetTrace()
HardwareExceptionDisplayStack()
}
catch(err)
{
host.diagnostics.debugLog("\n >>> Processing of TTD file failed \n");
}
}
Donanım özel durumu içeren bir iz dosyasında bu betiği çalıştırmak, bu çıkışı üretir.
0:000> dx Debugger.State.Scripts.MyTraceUtils.Contents.ProcessTTDFiles()
>>> Index Return Value: Loaded
>>> Trace was successfully indexed in 0 ms
(948.148c): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: F:0
. 0 Id: 948.148c Suspend: 4096 Teb: 00a33000 Unfrozen
User Mode Time
Thread Time
0:148c 0 days 0:00:00.000
Kernel Mode Time
Thread Time
0:148c 0 days 0:00:00.000
Elapsed Time
Thread Time
0:148c 3474 days 2:27:43.000
>>> Printing stack
>>> Stack Entry -> 0: ntdll!LdrInitializeThunk
>>> Current position in trace file: F:0
(948.148c): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: F:0
>>> New position in trace file: F:0
(948.148c): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 91:0
>>> The Thread ID (TID) is : 5260
>>> Printing stack
>>> Stack Entry -> 0: 0x540020
>>> Stack Entry -> 1: 0x4d0049
>>> Stack Entry -> 2: DisplayGreeting!__CheckForDebuggerJustMyCode + 0x16d
>>> Stack Entry -> 3: DisplayGreeting!mainCRTStartup + 0x8
>>> Stack Entry -> 4: KERNEL32!BaseThreadInitThunk + 0x19
>>> Stack Entry -> 5: ntdll!__RtlUserThreadStart + 0x2f
>>> Stack Entry -> 6: ntdll!_RtlUserThreadStart + 0x1b
Ayrıca Bkz.
Zaman Yolculuğu Hata Ayıklama - Genel Bakış
Zaman Yolculuğu Hata Giderme nesnelerine giriş
JavaScript Uzantılarında Yerel Hata Ayıklayıcı Nesnelerini - Hata Ayıklayıcı Nesne Ayrıntıları