Time Travel Debugging - Sample App Walkthrough

Small time travel logo showing clock.

This lab introduces Time Travel Debugging (TTD), using a small sample programme with a code flaw. TTD is used to debug, identify and root cause the event. Although the result in this small-scale program is easy to observe, the general procedure can exist used on more than circuitous code. This general process tin can be summarized as follows.

  1. Capture a time travel trace of the failed program.
  2. Use the dx (Display Debugger Object Model Expression) command to discover the exception issue stored in the recording.
  3. Use the !tt (fourth dimension travel) command to travel to the position of the exception issue in the trace.
  4. From that point in the trace single pace backwards until the faulting lawmaking in question comes into telescopic.
  5. With the faulting code in scope, look at the local values and develop a hypothesis of a variable that may incorporate an wrong value.
  6. Make up one's mind the retentiveness accost of the variable with the incorrect value.
  7. Set a memory admission (ba) breakpoint on the address of the suspect variable using the ba (Break on Admission) control.
  8. Use thou- to run back to last bespeak of memory access of the suspect variable.
  9. See if that location, or a few instructions before, is the point of the code flaw. If so, you are done. If the incorrect value came from some other variable, ready another break on admission breakpoint on the 2d variable.
  10. Use g- to run dorsum to the last bespeak of memory admission on the second suspect variable. See if that location or a few instructions before contains the code flaw. If so, you are done.
  11. Repeat this process walking back until the code that set the incorrect value that caused the mistake is located.

Although the general techniques described in this procedure utilize to a wide set of code issues, there are unique code issues that will require a unique arroyo. The techniques illustrated in the walkthrough should serve to expand your debugging tool set and will illustrate some of what is possible with a TTD trace.

Lab objectives

After completing this lab, you will exist able to use the general procedure with a time travel trace to locate problems in code.

Lab setup

You will demand the following hardware to be able to complete the lab.

  • A laptop or desktop computer (host) running Windows 10

You will need the following software to be able to consummate the lab.

  • The WinDbg Preview. For data on installing WinDbg Preview, see WinDbg Preview - Installation
  • Visual Studio to build the sample C++ code.

The lab has the following three sections.

  • Section 1: Build the sample code
  • Section 2: Tape a trace of the "DisplayGreeting" sample
  • Section 3: Clarify the trace file recording to identify the code issue

Section ane: Build the sample lawmaking

In Section 1, you lot will build the sample code using Visual Studio.

Create the sample app in Visual Studio

  1. In Microsoft Visual Studio, click File > New > Project/Solution... and click on the Visual C++ templates.

    Select the Win32 Panel Application.

    Provide a project name of DisplayGreeting and click on OK.

  2. Uncheck the Security Evolution Lifecycle (SDL) checks.

    win32 application wizard application settings.

  3. Click on Finish.

  4. Paste in the following text to the DisplayGreeting.cpp pane in Visual Studio.

                      // DisplayGreeting.cpp : Defines the entry point for the console application. //  #include "stdafx.h" #include <array> #include <stdio.h> #include <cord.h>  void GetCppConGreeting(wchar_t* buffer, size_t size) {     wchar_t const* const message = 50"Hello FROM THE WINDBG TEAM. GOOD LUCK IN ALL OF YOUR Fourth dimension TRAVEL DEBUGGING!";      wcscpy_s(buffer, size, bulletin); }  int master() {      std::array <wchar_t, 50> greeting{};      GetCppConGreeting(greeting.data(), sizeof(greeting));       wprintf(50"%ls\n", greeting.data());       return 0; }                                  
  5. In Visual Studio, click Projection > DisplayGreeting properties. Then click on C/C++ and Code Generation.

    Fix the post-obit backdrop.

    Setting Value
    Security Bank check Disable Security Check (/GS-)
    Basic Runtime Checks Default

    Notation

    Although these setting are non recommended, it is possible to imagine a scenario where someone would propose using these settings to expedite coding or to facilitate sure testing environments.

  6. In Visual Studio, click Build > Build Solution.

    If all goes well, the build windows should display a message indicating that the build succeeded.

  7. Locate the congenital sample app files

    In the Solution Explorer, right click on the DisplayGreeting project and select Open up Binder in File explorer.

    Navigate to the Debug folder that contains the complied exe and symbol pdb file for the sample. For example, y'all would navigate to C:\Projects\DisplayGreeting\Debug, if that'due south the folder that your projects are stored in.

  8. Run the sample app with the code flaw

    Double click on the exe file to run the sample app.

    Screenshot that shows the .exe file running in the console.

    If this dialog box appears, select Close plan

    Screenshot that shows the "(filename).exe has stopped working" dialog box.

    In the side by side department of the walkthrough, we will tape the execution of the sample app to see if nosotros tin can decide why this exception is occurring.

Section 2: Record a trace of the "DisplayGreeting" sample

In Section 2, you will record a trace of the misbehaving sample "DisplayGreeting" app

To launch the sample app and record a TTD trace, follow these steps. For general data nearly recording TTD traces, see Time Travel Debugging - Record a trace

  1. Run WinDbg Preview as an Ambassador, so equally to exist able to record time travel traces.

  2. In WinDbg Preview, select File > Commencement debugging > Launch executable (advanced).

  3. Enter the path to the user style executable that you wish to record or select Browse to navigate to the executable. For information about working with the launch executable menu in WinDbg Preview, come across WinDbg Preview - Starting time a user-mode session.

    Screen shot of WinDbg Preview showing start recording checkbox in launch executable (advanced) screen.

  4. Bank check the Record with Fourth dimension Travel Debugging box to tape a trace when the executable is launched.

  5. Click Configure and Tape to start recording.

  6. When the "Configure recording" dialog box appears, Click Tape to launch the executable and showtime recording.

    Screen shot of WinDbg Preview showing configure recording dialog with apath set to temp.

  7. The recording dialog appears indicating the trace is being recorded. Shortly after that, the application crashes.

  8. Click on Close Plan, to dismiss the "DisplayGreeting has stopped working" dialog box.

    Faulting app dialog box.

  9. When the programme crashes, the trace file will be closed and written out to disk.

    Screen shot of WinDbg Preview showing output with 1/1 keyframes indexed.

  10. The debugger will automatically open the trace file and index it. Indexing is a process that enables efficient debugging of the trace file. This indexing procedure will take longer for larger trace files.

                      (5120.2540): Intermission teaching exception - code 80000003 (beginning/second chance not available) Fourth dimension Travel Position: D:0 [Unindexed] Index !index Indexed 10/22 keyframes Indexed 20/22 keyframes Indexed 22/22 keyframes Successfully created the alphabetize in 755ms.                                  

Note

A keyframe is a location in a trace used for indexing. Keyframes are generated automatically. Larger traces will incorporate more keyframes.

  1. At this point y'all are at the beginning of the trace file and are gear up to travel forward and backward in time.

    Now that yous accept a recorded a TTD trace, yous can replay the trace back or work with the trace file, for example sharing it with a co-worker. For more information almost working with trace files, come across Time Travel Debugging - Working with Trace Files

In the side by side section of this lab nosotros will analyze the trace file to locate the issue with our code.

Section iii: Clarify the trace file recording to identify the code upshot

In Section 3, y'all will analyze the trace file recording to place the code issue.

Configure the WinDbg Surroundings

  1. Add your local symbol location to the symbol path and reload the symbols, by typing the post-obit commands.

                      .sympath+ C:\MyProjects\DisplayGreeting\Debug .reload                                  
  2. Add your local code location to the source path by typing the following command.

                      .srcpath+ C:\MyProjects\DisplayGreeting\DisplayGreeting                                  
  3. To be able to view the land of the stack and local variables, on the WinDbg Preview ribbon, select View and Locals and View and Stack. Organize the windows to allow you to view them, the source code and the control windows at the same time.

  4. On the WinDbg Preview ribbon, select Source and Open up Source File. Locate the DisplayGreeting.cpp file and open information technology.

Examine the exception

  1. When the trace file was loaded it displays information that an exception occurred.

                      2fa8.1fdc): Break instruction exception - code 80000003 (first/second hazard non available) Time Travel Position: xv:0 eax=68ef8100 ebx=00000000 ecx=77a266ac edx=69614afc esi=6961137c edi=004da000 eip=77a266ac esp=0023f9b4 ebp=0023fc04 iopl=0         nv upward ei pl nz na pe nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206 ntdll!LdrpInitializeProcess+0x1d1c: 77a266ac 83bdbcfeffff00  cmp     dword ptr [ebp-144h],0 ss:002b:0023fac0=00000000                                  
  2. Use the dx command to list all of the events in the recording. The exception issue is listed in the events.

                      0:000> dx -r1 @$curprocess.TTD.Events ... [0x2c]           : Module Loaded at position: 9967:0 [0x2d]           : Exception at 9BDC:0 [0x2e]           : Thread terminated at 9C43:0 ...                                  

    Note

    In this walkthrough three periods are used to indicate that inapplicable output was removed.

  3. Click on the Exception outcome to display information well-nigh that TTD consequence.

                      0:000> dx -r1 @$curprocess.TTD.Events[17] @$curprocess.TTD.Events[17]                 : Exception at 68:0     Type             : Exception     Position         : 68:0 [Time Travel]     Exception        : Exception of blazon Hardware at PC: 0X540020                                  
  4. Click on the Exception field to further drill down on the exception data.

                      0:000> dx -r1 @$curprocess.TTD.Events[17].Exception @$curprocess.TTD.Events[17].Exception                 : Exception of type Hardware at PC: 0X540020     Position         : 68:0 [Time Travel]     Blazon             : Hardware     ProgramCounter   : 0x540020     Code             : 0xc0000005     Flags            : 0x0     RecordAddress    : 0x0                                  

    The exception information indicates that this is a Hardware mistake thrown past the CPU. It also provides the exception code of 0xc0000005 that indicates that this is an access violation. This typically indicates that we were attempting to write to memory that we don't take access to.

  5. Click on the [Time Travel] link in the exception upshot to move to that position in the trace.

                      0:000> dx @$curprocess.TTD.Events[17].Exception.Position.SeekTo() Setting position: 68:0  @$curprocess.TTD.Events[17].Exception.Position.SeekTo() (16c8.1f28): Pause instruction exception - lawmaking 80000003 (first/second chance not available) Time Travel Position: 68:0 eax=00000000 ebx=00cf8000 ecx=99da9203 edx=69cf1a6c esi=00191046 edi=00191046 eip=00540020 esp=00effe4c ebp=00520055 iopl=0         nv up ei pl zr na pe nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246 00540020 ??                                  

    Of note in this output is that the stack and base pointer are pointing to two very different addresses.

                      esp=00effe4c ebp=00520055                                  

    This could betoken that stack corruption - perhaps a function returned and then corrupted the stack. To validate this, nosotros demand to travel back to before the CPU state was corrupted and see if we tin determine when the stack corruption occurred.

Examine the local variables and set a code breakpoint

At the point of failure in trace information technology is common to end up a few steps after the true cause in error handling lawmaking. With time travel nosotros can go back an instruction at a time, to locate the truthful root cause.

  1. From the Home ribbon use the Footstep Into Dorsum command to step dorsum three instructions. Every bit you lot do this, go along to examine the stack and memory windows.

    The control window will display the time travel position and the registers as you pace back 3 instructions.

                      0:000> t- Fourth dimension Travel Position: 67:xl eax=00000000 ebx=00cf8000 ecx=99da9203 edx=69cf1a6c esi=00191046 edi=00191046 eip=00540020 esp=00effe4c ebp=00520055 iopl=0         nv up ei pl zr na pe nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246 00540020 ??              ???  0:000> t- Time Travel Position: 67:3F eax=00000000 ebx=00cf8000 ecx=99da9203 edx=69cf1a6c esi=00191046 edi=00191046 eip=0019193d esp=00effe48 ebp=00520055 iopl=0         nv up ei pl zr na pe nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246 DisplayGreeting!main+0x4d: 0019193d c3  0:000> t- Time Travel Position: 67:39 eax=0000004c ebx=00cf8000 ecx=99da9203 edx=69cf1a6c esi=00191046 edi=00191046 eip=00191935 esp=00effd94 ebp=00effe44 iopl=0         nv upwardly ei pl nz ac po nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000212 DisplayGreeting!principal+0x45:                                  

    Notation

    In this walkthrough, the command output shows the commands that tin be used instead of the UI Menu options to allow users with a command line usage preference to use command line commands.

  2. At this point in the trace our stack and base pointer accept values that brand more than sense, so it appears that nosotros have getting closer to the point in the code where the corruption occurred.

                      esp=00effd94 ebp=00effe44                                  

    Also of interest is that the locals window contains values from our target app and the source code window is highlighting the line of lawmaking that is ready to be executed at this point in the trace.

    Screenshot of WinDbg Preview showing locals windows with memory ASCII output and source code window.

  3. To further investigate, we can open up a retentivity window to view the contents near the base of operations pointer memory address of 0x00effe44.

  4. To display the associated ASCII characters, from the Memory ribbon, select Text and and then ASCII.

    screenshot of winbbg preview showing memory ascii output and source code window.

  5. Instead of the base pointer pointing to an pedagogy it is pointing to our message text. So something is not right here, this may exist close to the point in fourth dimension that we take corrupted the stack. To farther investigate we will prepare a breakpoint.

Note

In this very pocket-sized sample it would be pretty like shooting fish in a barrel to just wait in the code, but if at that place are hundreds of lines of code and dozens of subroutines the techniques described here can be used to decrease the time necessary to locate the outcome.

TTD and breakpoints

Using breakpoints is a common approach to pause code execution at some event of interest. TTD allows yous to set a breakpoint and travel dorsum in time until that breakpoint is hit after the trace has been recorded. The ability to examine the process land after an upshot has happened, to determine the best location for a breakpoint, enables additional debugging workflows unique to TTD.

Retentivity access breakpoints

Y'all can set breakpoints that fire when a memory location is accessed. Use the ba (break on admission) command, with the post-obit syntax.

              ba <admission> <size> <address> {options}                          
Option Description

due east

execute (when CPU fetches an pedagogy from the address)

r

read/write (when CPU reads or writes to the accost)

w

write (when the CPU writes to the address)

Note that you tin can only set 4 data breakpoints at any given time and it is upwards to you to make sure that you lot are aligning your data correctly or you won't trigger the breakpoint (words must end in addresses divisible by ii, dwords must exist divisible by 4, and quadwords by 0 or 8).

Set the break on memory access breakpoint for the base of operations pointer

  1. At this betoken in the trace we would like to fix a breakpoint on write retentivity admission to base pointer - ebp which in our case is 00effe44. To do this use the ba command using the address nosotros want to monitor. We want to monitor writes for 4 bytes, so we specify w4.

                      0:000> ba w4 00effe44                                  
  2. Select View and so Breakpoints to confirm they are set as intended.

    WinDbg Preview showing breakpoints window with one breakpoint.

  3. From the Home menu, select Go Back to travel dorsum in time until the breakpoint is hit.

                      0:000> k- Breakpoint 0 hit Time Travel Position: 5B:92 eax=0000000f ebx=003db000 ecx=00000000 edx=00cc1a6c esi=00d41046 edi=0053fde8 eip=00d4174a esp=0053fcf8 ebp=0053fde8 iopl=0         nv up ei pl nz ac pe nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216 DisplayGreeting!DisplayGreeting+0x3a: 00d4174a c745e000000000  mov     dword ptr [ebp-20h],0 ss:002b:0053fdc8=cccccccc                                  
  4. Select View and then Locals. In the locals window nosotros tin can see that the destination variable has but part of the bulletin, while the source has contains all of the text. This data supports the idea that the stack was corrupted.

    Screenshot of WinDbg Preview locals window.

  5. At this signal we can examine the program stack to see what code is active. From the View ribbon select Stack.

    Screenshot of WinDbg Preview stack window.

Every bit it is very unlikely that the Microsoft provided wscpy_s() office would accept a lawmaking problems like this, we await further in the stack. The stack shows that Greeting!main calls Greeting!GetCppConGreeting. In our very small code sample nosotros could but open the code at this betoken and likely find the error pretty easily. But to illustrate the techniques that tin can be used with larger, more circuitous program, we will set a new breakpoint to investigate farther.

Set the break on access breakpoint for the GetCppConGreeting function

  1. Use the breakpoints window to clear the existing breakpoint by right clicking on the existing breakpoint and selecting Remove.

  2. Make up one's mind the address of the DisplayGreeting!GetCppConGreeting function using the dx command.

                      0:000> dx &DisplayGreeting!GetCppConGreeting &DisplayGreeting!GetCppConGreeting                 : 0xb61720 [Type: void (__cdecl*)(wchar_t *,unsigned int)]     [Type: void __cdecl(wchar_t *,unsigned int)]                                  
  3. Utilize the ba control to set a breakpoint on memory access. Because the function volition just exist read from retentiveness for execution, nosotros need to set a r - read breakpoint.

                      0:000> ba r4 b61720                                  
  4. Confirm that a Hardware Read breakpoint is active in the breakpoints window.

    WinDbg Preview showing breakpoints window with one hardware read breakpoint.

  5. As we are wondering well-nigh the size of the greeting string nosotros will fix a lookout window to display the value of sizeof(greeting). From the View ribbon, select Watch and provide sizeof(greeting).

    WinDbg Preview showing a watch locals window.

  6. On the Time Travel menu, use Time travel to showtime or utilise the !tt 0command to move to the start of the trace.

                      0:000> !tt 0 Setting position to the beginning of the trace Setting position: fifteen:0 (1e5c.710): Break instruction exception - lawmaking 80000003 (commencement/second adventure not available) Time Travel Position: xv:0 eax=68e28100 ebx=00000000 ecx=77a266ac edx=69e34afc esi=69e3137c edi=00fa2000 eip=77a266ac esp=00ddf3b8 ebp=00ddf608 iopl=0         nv up ei pl nz na pe nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206 ntdll!LdrpInitializeProcess+0x1d1c: 77a266ac 83bdbcfeffff00  cmp     dword ptr [ebp-144h],0 ss:002b:00ddf4c4=00000000                                  
  7. On the Habitation menu, select Go or use the k command, to move forward in the code until the breakpoint is hitting.

                      0:000> thou Breakpoint 2 hit Time Travel Position: 4B:1AD eax=00ddf800 ebx=00fa2000 ecx=00ddf800 edx=00b61046 esi=00b61046 edi=00b61046 eip=00b61721 esp=00ddf7a4 ebp=00ddf864 iopl=0         nv up ei pl nz na po nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202 DisplayGreeting!GetCppConGreeting+0x1: 00b61721 8bec            mov     ebp,esp                                  
  8. On the Home menu, select Pace Out Dorsum or use the chiliad-u command to dorsum one footstep.

                      0:000> 1000-u Time Travel Position: 4B:1AA eax=00ddf800 ebx=00fa2000 ecx=00ddf800 edx=00b61046 esi=00b61046 edi=00b61046 eip=00b61917 esp=00ddf7ac ebp=00ddf864 iopl=0         nv up ei pl nz na po nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202 DisplayGreeting!chief+0x27: 00b61917 e8def7ffff      call    DisplayGreeting!ILT+245(?GetCppConGreetingYAXPA_WIZ) (00b610fa)                                  
  9. It looks like nosotros take constitute the root cause. The greeting array that nosotros alleged is 50 characters in length, while the sizeof(greeting) that we laissez passer into GetCppConGreeting is 0x64, 100).

    WinDbg Preview showing the Display greeting code with a watch locals window showing X64.

    Every bit we look at the size issue further, nosotros as well notice that the message is 75 characters in length, 76 including the end of cord character.

                      Hello FROM THE WINDBG Team. GOOD LUCK IN ALL OF YOUR Time TRAVEL DEBUGGING!                                  
  10. One manner to fix the code would be to aggrandize the size of the grapheme assortment to 100.

                      std::array <wchar_t, 100> greeting{};                                  

    And we also need to modify sizeof(greeting) to size(greeting) in this line of code.

                                          GetCppConGreeting(greeting.data(), size(greeting));                                  
  11. To validate these fixes, we could recompile the code and ostend that it runs without mistake.

Setting a breakpoint using the source window

  1. An alternative way to perform this investigation would exist to set a breakpoint by clicking on whatsoever line of lawmaking. For instance clicking on the right side of the std:assortment definition line in the source window will set a breakpoint there.

    Screenshot of source window showing breakpoint set on std:array.

  2. On the Fourth dimension Travel carte, use Time travel to showtime command to move to the commencement of the trace.

                      0:000> !tt 0 Setting position to the beginning of the trace Setting position: 15:0 (1e5c.710): Break instruction exception - lawmaking 80000003 (first/second adventure not available) Fourth dimension Travel Position: 15:0 eax=68e28100 ebx=00000000 ecx=77a266ac edx=69e34afc esi=69e3137c edi=00fa2000 eip=77a266ac esp=00ddf3b8 ebp=00ddf608 iopl=0         nv upwardly ei pl nz na pe nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206 ntdll!LdrpInitializeProcess+0x1d1c: 77a266ac 83bdbcfeffff00  cmp     dword ptr [ebp-144h],0 ss:002b:00ddf4c4=00000000                                  
  3. On the Home Ribbon click on Become to travel dorsum until the breakpoint is striking.

                      Breakpoint 0 hit Time Travel Position: 5B:AF eax=0000000f ebx=00c20000 ecx=00000000 edx=00000000 esi=013a1046 edi=00effa60 eip=013a17c1 esp=00eff970 ebp=00effa60 iopl=0         nv up ei pl nz na po nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202 DisplayGreeting!DisplayGreeting+0x41: 013a17c1 8bf4            mov     esi,esp                                  

Set the break on access breakpoint for the greeting variable

Another culling way to perform this investigation, would be to fix a breakpoint on suspect variables and examine what code is changing them. For instance, to set a breakpoint on the greeting variable in the GetCppConGreeting method, use this procedure.

This portion of the walkthrough assumes that yous are still located at the breakpoint from the previous department.

  1. From View then Locals. In the locals window, greeting is available in the current context, so we will exist able to determine its retentivity location.

  2. Use the dx command to examine the greeting array.

                      0:000> dx &greeting &greeting                 : 0xddf800 [Blazon: std::array<wchar_t,l> *]    [+0x000] _Elems           : "꽘棶檙瞝???" [Type: wchar_t [50]]                                  

    In this trace, greeting is located in memory at ddf800.

  3. Utilise the breakpoints window to clear any existing breakpoint by right clicking on the existing breakpoint and selecting Remove.

  4. Set the breakpoint with the ba control using the retention accost we desire to monitor for write admission.

                      ba w4 ddf800                                  
  5. On the Time Travel menu, use Time travel to start command to motility to the start of the trace.

                      0:000> !tt 0 Setting position to the beginning of the trace Setting position: 15:0 (1e5c.710): Interruption instruction exception - code 80000003 (first/second chance non available) Time Travel Position: 15:0 eax=68e28100 ebx=00000000 ecx=77a266ac edx=69e34afc esi=69e3137c edi=00fa2000 eip=77a266ac esp=00ddf3b8 ebp=00ddf608 iopl=0         nv up ei pl nz na pe nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206 ntdll!LdrpInitializeProcess+0x1d1c: 77a266ac 83bdbcfeffff00  cmp     dword ptr [ebp-144h],0 ss:002b:00ddf4c4=00000000                                  
  6. On the Home menu, select Become to travel forward to the offset bespeak of memory access of the greeting array.

                      0:000> g- Breakpoint 0 hit Time Travel Position: 5B:9C eax=cccccccc ebx=002b1000 ecx=00000000 edx=68d51a6c esi=013a1046 edi=001bf7d8 eip=013a1735 esp=001bf6b8 ebp=001bf7d8 iopl=0         nv upward ei pl nz na po nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202 DisplayGreeting!GetCppConGreeting+0x25: 013a1735 c745ec04000000  mov     dword ptr [ebp-14h],iv ss:002b:001bf7c4=cccccccc                                  

    Alternatively, we could have traveled to the end of the trace and worked in reverse through the code to notice that last signal in the trace that the array memory location was written to.

Use the TTD.Memory objects to view retentivity admission

Another way to determine at what points in the trace memory has been accessed, is to utilise the TTD.Memory objects and the dx control.

  1. Utilise the dx command to examine the greeting array.

                      0:000> dx &greeting &greeting                 : 0xddf800 [Blazon: std::assortment<wchar_t,50> *]    [+0x000] _Elems           : "꽘棶檙瞝???" [Type: wchar_t [50]]                                  

    In this trace, greeting is located in memory at ddf800.

  2. Use the dx command to look at the four bytes in retentivity starting at that address with the read write admission.

                      0:000> dx -r1 @$cursession.TTD.Retentiveness(0xddf800,0xddf804, "rw") @$cursession.TTD.Retentiveness(0x1bf7d0,0x1bf7d4, "rw")                     [0x0]                [0x1]                [0x2]                [0x3]                [0x4]                [0x5]                [0x6]                [0x7]                [0x8]                [0x9]                [0xa]                ...                                  
  3. Click on any of the occurrences to display more than data about that occurrence of memory access.

                      0:000> dx -r1 @$cursession.TTD.Retentiveness(0xddf800,0xddf804, "rw")[5] @$cursession.TTD.Memory(0xddf800,0xddf804, "rw")[five]                     EventType        : MemoryAccess     ThreadId         : 0x710     UniqueThreadId   : 0x2     TimeStart        : 27:3C1 [Time Travel]     TimeEnd          : 27:3C1 [Time Travel]     AccessType       : Write     IP               : 0x6900432f     Address          : 0xddf800     Size             : 0x4     Value            : 0xddf818                                  
  4. Click on [Time Travel] to position the trace at the signal in time.

                      0:000> dx @$cursession.TTD.Memory(0xddf800,0xddf804, "rw")[5].TimeStart.SeekTo() @$cursession.TTD.Memory(0xddf800,0xddf804, "rw")[5].TimeStart.SeekTo() (1e5c.710): Break instruction exception - code 80000003 (first/2nd chance not available) Fourth dimension Travel Position: 27:3C1 eax=00ddf81c ebx=00fa2000 ecx=00ddf818 edx=ffffffff esi=00000000 edi=00b61046 eip=6900432f esp=00ddf804 ebp=00ddf810 iopl=0         nv up ei pl nz ac po nc cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000212 ucrtbased!_register_onexit_function+0xf: 6900432f 51              push    ecx                                  
  5. If we are interested in the terminal occurrence of read/write memory admission in the trace we tin can click on the last item in the list or suspend the .Terminal() function to the stop of the dx control.

                      0:000> dx -r1 @$cursession.TTD.Memory(0xddf800,0xddf804, "rw").Last() @$cursession.TTD.Retentiveness(0xddf800,0xddf804, "rw").Concluding()                     EventType        : MemoryAccess     ThreadId         : 0x710     UniqueThreadId   : 0x2     TimeStart        : 53:100E [Time Travel]     TimeEnd          : 53:100E [Fourth dimension Travel]     AccessType       : Read     IP               : 0x690338e4     Accost          : 0xddf802     Size             : 0x2     Value            : 0x45                                  
  6. We could so click on [Time Travel] to move to that position in the trace and look further at the lawmaking execution at that point, using the techniques described earlier in this lab.

For more information near the TTD.Retentivity objects, see TTD.Memory Object.

Summary

In this very pocket-size sample the result could have been adamant by looking at the few lines of code, but in larger programs the techniques presented here can exist used to decrease the time necessary to locate an issue.

In one case a trace is recorded, the trace and repro steps can be shared, and the issue volition be reproducible on need on any PC.

Meet As well

Time Travel Debugging - Overview

Time Travel Debugging - Recording

Time Travel Debugging - Replay a trace

Time Travel Debugging - Working with trace files