时间旅行调试(TTD)允许用户记录跟踪,这些跟踪是对程序执行的记录。时间线是执行过程中发生的事件的直观表示,这些事件可以是包括断点,内存读/写,函数调用和返回以及异常。

使用时间线窗口可以快速查看重要事件,了解相对位置并轻松跳转到它们在TTD跟踪文件中的位置,使用多个时间线以可视方式探索时间旅行轨迹中的事件并发现事件相关性。

打开TTD跟踪文件时将显示时间线窗口,并显示关键事件,而无需手动创建数据模型查询。同时,所有时间旅行对象均可用,以允许进行更复杂的数据查询。有关创建和使用时间旅行跟踪文件的更多信息,请点此查看。

时间线类型

时间线窗口可以显示以下事件:

1.异常(你可以进一步过滤特定的异常代码);

2.断点(添加断点时也会自动添加断点的时间线);

3.函数调用(以module!function形式搜索);

4.内存访问(在两个内存地址之间进行读/写/执行);

将鼠标停在每个事件上,通过工具提示获取更多信息。点击事件将运行事件查询并显示更多信息,双击事件将跳至TTD跟踪文件中的该位置。

异常

当你加载跟踪文件并且时间线处于活动状态时,它将自动显示记录中的任何异常。当你将鼠标悬停在断点上时,将显示诸如异常类型和异常代码之类的信息。

你可以使用可选的异常代码字段进一步过滤特定的异常代码:

你还可以为特定的异常类型添加新的时间线。

断点

添加断点后,会将断点的时间线自动添加到时间线。例如,可以使用bp Set Breakpoint命令完成此操作。当你将鼠标悬停在断点上时,将显示地址和与断点关联的指令指针。

清除断点后,关联的断点时间线将自动删除。

函数调用

你可以在时间线上显示函数调用的位置。为此,就要以module!function的形式提供搜索,例如TimelineTestCode!multiplyTwo。你还可以指定通配符,例如TimelineTestCode!m*。

将鼠标悬停在函数上时,将显示函数名称、输入参数及其值和返回值。此示例显示缓冲区和大小,因为这些是DisplayGreeting!GetCppConGreeting的参数。

内存访问

使用内存访问时间线显示何时已读取或写入特定范围的内存,或在何处执行了代码。起始地址和终止地址用于定义两个存储器地址之间的范围。

将鼠标悬停在内存访问项上时,将显示值和指令指针。

使用时间线

当将鼠标悬停在时间线上时,一条垂直的灰色线将跟随鼠标,蓝色竖线表示跟踪中的当前位置,点击放大镜图标可放大和缩小时间线。

在顶部时间线控制区域中,使用矩形来平移时间线的视图。拖动矩形的外部定界符以调整当前时间线视图的大小。

鼠标移动

使用Ctrl +滚轮放大和缩小,使用Shift +滚轮可左右滚动。

时间线调试技术

为了演示调试时间线技术,此处重用了“时间旅行调试演练(Time Travel Debugging Walkthrough)”。本演示假设你已经完成了构建样例代码的前两个步骤,并使用前面描述的前两个步骤创建了TTD记录。

第1部分:构建示例代码;

第二部分:记录“DisplayGreeting”示例的踪迹;

在本示例中,第一步是在时间旅行跟踪中查找异常,这可以通过双击时间线上唯一的异常来实现。

在命令窗口中,我们看到点击异常时发出了以下命令。

(2dcc.6600): Break instruction exception - code 80000003 (first/second chance not available)

Time Travel Position: CC:0

@$curprocess.TTD.Events.Where(t => t.Type == "Exception")[0x0].Position.SeekTo()

选择查看>>寄存器以在时间线上显示寄存器,开始我们的调查。

在命令输出中,请注意堆栈(esp)和基本指针(ebp)指向两个截然不同的地址。这可能表明堆栈已损坏,可能是返回的函数损坏了堆栈。为了验证这一点,我们需要返回到CPU状态被损坏之前的状态,并查看是否可以确定何时发生堆栈损坏。在此过程中,我们将检查局部变量和堆栈的值。选择查看>>当地,以显示本地值,选择查看>>堆栈以显示代码执行堆栈。

在跟踪失败时,通常会在错误处理代码的真正原因之后结束几个步骤。通过时间旅行,我们可以一次返回一条指令,找出真正的根本原因。

从主页功能区中,使用“后退一步”命令后退三步指令。执行此操作时,请继续检查堆栈,本地变量和注册窗口。

当你使用“后退一步”命令后,命令窗口将显示时间行进位置和寄存器。

0:000> t-

Time Travel Position: CB:41

eax=00000000 ebx=00564000 ecx=c0d21d62 edx=7a1e4a6c esi=00061299 edi=00061299

eip=00540020 esp=003cf7d0 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: CB:40

eax=00000000 ebx=00564000 ecx=c0d21d62 edx=7a1e4a6c esi=00061299 edi=00061299

eip=00061767 esp=003cf7cc 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+0x57:

00061767 c3              ret

0:000> t-

Time Travel Position: CB:3A

eax=0000004c ebx=00564000 ecx=c0d21d62 edx=7a1e4a6c esi=00061299 edi=00061299

eip=0006175f esp=003cf718 ebp=003cf7c8 iopl=0         nv up ei pl nz na pe nc

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206

DisplayGreeting!main+0x4f:

0006175f 33c0            xor     eax,eax

在跟踪时,我们的堆栈和基本指针具有更有意义的值,因此看来我们越来越接近代码中发生损坏的位置。

esp=003cf718 ebp=003cf7c8

另一个有趣的地方是,本地窗口包含来自我们的目标应用程序的值,而源代码窗口则高亮显示在跟踪中的源代码中准备执行的代码行。

为了进一步研究,我们可以打开一个内存窗口来查看堆栈指针(esp)内存地址附近的内容。在此示例中,其值为003cf7c8。选择内存>>文本>> ASCII以显示存储在该地址的ASCII文本。

内存访问时间线

确定了感兴趣的内存位置后,使用该值添加内存访问时间线。点击+添加时间线,然后填写起始地址。我们将查看4个字节,因此将其添加到003cf7c8的起始地址中,即得到003cf7cb。默认设置是查看所有内存写入,但是你也可以仅查看该地址处的写入或代码执行。

现在,我们可以反向遍历时间线,以检查这段时间在此行的跟踪记录的哪一点被写入,以查看可以找到的内容。点击时间线上的此位置,我们看到本地人为要复制的字符串取不同的值。目标值似乎不完整,好像我们的字符串长度不正确。

断点时间线

使用断点是在某些情况下暂停代码执行的常用方法,TTD允许你设置一个断点并及时返回,直到在记录跟踪之后找到该断点为止。在问题发生后检查过程状态,确定断点的最佳位置的能力启用了TTD特有的其他调试工作流。

要探索替代的时间线调试技术,请点击时间线中的异常,然后使用Home功能区上的“后退一步”命令再次前进三步。

在这个示例中,仅查看代码将非常容易,但是如果有数百行代码和数十个子例程,则可以使用此处描述的技术来减少定位问题所需的时间。

如前所述,基本指针(esp)并非指向指令,而是指向我们的消息文本。

使用ba命令在内存访问上设置断点,我们将设置一个w - write断点,以查看何时写入此内存区域。

0:000> ba w4 003cf7c8

尽管我们将使用简单的内存访问断点,但可以将断点构造为更复杂的条件语句。有关更多信息,请参见bp,bu,bm(设置断点)。

从“主页”菜单中,选择“返回”以返回到断点之前的时间。此时,我们可以检查程序堆栈以查看哪些代码处于活动状态。

由于Microsoft提供的wscpy_s()函数不太可能出现这样的代码错误,因此我们在堆栈中进行了进一步的研究。堆栈显示Greeting!main调用Greeting!GetCppConGreeting。在这个非常小的代码示例中,我们可以在此时打开代码,并且很容易发现错误。但是,为了说明可以用于更大、更复杂的程序的技术,为此我们将设置添加一个函数调用时间线。

       函数调用时间线

点击+添加时间线,然后填写DisplayGreeting!GetCppConGreeting作为函数搜索字符串。

“开始”和“结束位置”复选框表示跟踪中函数调用的开始和结束位置。

我们可以使用dx命令显示函数调用对象,以查看关联的TimeStart和TimeEnd字段,它们与函数调用的“开始位置”和“结束位置”相对应。

dx @$cursession.TTD.Calls("DisplayGreeting!GetCppConGreeting")[0x0]

EventType        : 0x0

ThreadId         : 0x6600

UniqueThreadId   : 0x2

TimeStart        : 6D:BD [Time Travel]

SystemTimeStart  : Thursday, October 31, 2019 23:36:05

TimeEnd          : 6D:742 [Time Travel]

SystemTimeEnd    : Thursday, October 31, 2019 23:36:05

Function         : DisplayGreeting!GetCppConGreeting

FunctionAddress  : 0x615a0

ReturnAddress    : 0x61746

Parameters

必须选中“开始”或“结束”,或者同时选中“开始”和“结束”位置框。

由于我们的代码既不是递归代码也不是可重入代码,因此调用GetCppConGreeting方法时,很容易在时间线上定位。对GetCppConGreeting的调用也与我们的断点以及我们定义的内存访问事件同时发生。因此,似乎我们已经缩小了代码范围,仔细研究了导致应用程序崩溃的根本原因。

通过查看多个时间线来探索代码执行

尽管我们的代码示例很小,但是使用多个时间线的技术可以对时间旅行轨迹进行可视化探索。你可以查看跟踪文件以询问问题,例如“何时在命中断点之前访问内存区域?”。

本文翻译自:https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/windbg-timeline-preview

new失败跟踪函数_WinDbg预览时间线:调试器中的时间线可以允许用户记录跟踪相关推荐

  1. YDOOK:Python3.9: breakpoint(*args, **kws) 函数:在调用时进入调试器中 详细用法

    YDOOK:Python3.9: breakpoint(*args, **kws) 函数:在调用时进入调试器中 详细用法 © YDOOK JY Lin 1. 原理: 该函数会调用 sys.breakp ...

  2. android自定义相机预览尺寸,相机在Android中,如何获得最佳尺寸,预览尺寸,图片尺寸,视图尺寸,图像扭曲...

    混合来自OpenGL和 Android相机的视图时图像失真,以便在使用takepicture方法时获取两者的图像.我查了一下,发现相机图片设置为640X480,openGL视图和相机预览都设置为128 ...

  3. H5 下载word文件时预览失败,提示无法预览此文件,它可能已损坏,有部分可可以查看预览

    移动端H5下载文件功能时,发现部分word文件可以在线打开 有些无法打开,提示"无法预览此文件,它可能已损坏": 但是在Pc端下载是可以正常打开的,移动端是不行. 代码如下: by ...

  4. bootstrap上传之后的处理_bootstrap-fileinput 进阶 -- 实现上传失败清除之前的预览图且可以继续上传...

    最终实现的 GIF 效果图 Animation44.gif 资料 正文 需求:在文件上传之后(接口可以正常的访问,只是返回结果是失败的情况下),这个时候需要将原来生成的缩略图清除掉(因为展示的样式会让 ...

  5. php DOS word在线预览,如何在 Zoho Docs 中在线预览文件

    文件预览 简介 预览让您可以概要了解您的长文档.视频或图册.通过预览让您可以一览文件中的内容. 关于 Zoho Docs 中的预览的以下信息将帮助您:使用预览工具栏. 编辑 MS Office 文件. ...

  6. 浏览器预览html网址,在浏览器中预览网页

    在浏览器中预览网页 10/11/2017 本文内容 为了便于在 Microsoft Expression Web 中设计网页,您可以在不同 Web 浏览器和不同大小的窗口中预览网页的外观.可以选择的窗 ...

  7. 微信小程序文件下载预览 真机调试可以 但直接预览打不开 小程序文件下载 小程序文件预览

    只要确保真机调试和调试状态下可以下载并预览文件即可,上线后即可预览成功 文件预览代码: 小程序预览的前提需要先调用下载接口,下方代码未处理下载和预览失败事件哟,此处我使用的是uniapp框架,如果使用 ...

  8. 预览窗格无法预览word_使用Word 2010中的导航窗格轻松重组文档

    预览窗格无法预览word Microsoft Word has a zillion features, and even after using it for a while, you're alwa ...

  9. 文档预览 OfficeWebViewer:在浏览器中查看Office文档

    Office Web Viewer:在浏览器中查看Office文档 由办公室团队 即使您的读者没有安装Office,您的网站或博客上是否也有要阅读的Office文档?您宁愿先查看文档再下载吗?为了给您 ...

最新文章

  1. 重装操作系统的20条原则(转载)
  2. 无需用户输入!Adobe提出自动生成高质量合成图像新方法
  3. 最新版ffmpeg 提取视频关键帧
  4. POJ - 3700 Missile Defence System.(dfs+最优性剪枝)
  5. notepad: 怎么在notepad里面,将字符串替换成换行
  6. (译)如何使用cocos2d制作一个塔防游戏:第三部分
  7. javaee7 中文帮助文档_怎么将阿拉伯语翻译成中文?这里有两种翻译方法
  8. Overture打谱软件免费安装下载版介绍
  9. 【分享】使用快递鸟接入圆通电子面单详解
  10. GBase 8a - 开启防火墙安装集群添加端口策略
  11. 看我如何破解一台自动售货机
  12. 机器学习实践系列(二)----达观杯--轴承故障检测训练赛
  13. Base64编码/解码原理及实现
  14. 【PHP】 解决报错:Error: php71w-common conflicts with php-common-5.4.16-43.el7_4.x86_64
  15. KONG网关和KONGA界面的入门使用,快速上手
  16. android 自定义抽屉,android – 动作栏抽屉切换自定义图标
  17. 丘成桐大学生数学竞赛数学物理
  18. javacv 视频转换
  19. ceph-mimic版本的安装使用1
  20. 怎么批量下载Onedrive分享文件_【软件分享】简单易用的照片批量处理软件,有需求的下载用用!...

热门文章

  1. 谷歌浏览器flash_谷歌浏览器不支持Flash Player的问题
  2. 产品经理晋升后如何带团队?
  3. windows server 2008 oracle 10g,一次不太愉快的Windows Server 2008 R2 SP1上安装ORACLE 10G经历...
  4. java中大数开方_大数开方(Java版)
  5. php 中间代码,PHP内核中用户函数、内部函数和中间代码的转换
  6. Angularjs总结(五)指令运用及常用控件的赋值操作
  7. CSS未知宽高元素水平垂直居中
  8. 小程序左右标签滑块排行榜
  9. 上下div高度动态自适应--另类处理方案
  10. cd1101d 树形dp