什么是时间旅行调试?

时间旅行调试是一种工具,可用于在进程执行时捕获进程的跟踪,并在以后向前和向后重播它。 时间旅行调试 (TTD) 可让你“倒退”调试器会话,而无需重现问题,直到找到 bug,从而帮助你更轻松地调试问题。

TTD 使你能够及时返回,以便更好地了解导致 Bug 的条件,并多次重播它,以了解如何以最佳方式解决问题。

TTD 比故障转储文件具有优势,后者通常会错过导致最终失败的状态和执行路径。

如果自己无法找出问题,可以与同事共享跟踪,他们可以准确查看你正在查看的内容。 这比实时调试更容易进行协作,因为记录的说明是相同的,而地址位置和代码执行在不同的电脑上会有所不同。 还可以共享特定时间点,以帮助同事确定从何处开始。

TTD 非常高效,可以尽可能少地增加开销,因为它捕获跟踪文件中的代码执行。

TTD 包括一组调试器数据模型对象,可用于使用 LINQ 查询跟踪。 例如,可以使用 TTD 对象来查找加载特定代码模块的日期或查找所有异常。

时间旅行调试与 WinDbg 集成,提供无缝录制和重播体验。

若要使用 TTD,需要运行提升的调试器。 使用具有管理员权限的帐户安装 WinDbg,并在调试器中录制时使用该帐户。 若要运行提升的调试器,请选择并按住 (或右键单击“开始”菜单中) WinDbg 图标,然后选择“更多 > 以管理员身份运行”。

TTD.exe 命令行录制实用工具

除了在 WinDbg UI 中记录跟踪外,还有一个可用于记录跟踪的 TTD.exe 命令行实用工具。

你可能在以下情况下只需要 TTD 命令行记录器:在电脑上录制而无需安装调试器、高级录制方案、测试自动化等。在这些方案中,可以通过 URL 仅安装 TTD 命令行记录器。 有关详细信息,请参阅 Time Travel Debugging - TTD.exe 命令行实用工具

调试工具的比较

下表总结了可用的不同调试解决方案的优缺点。

交互式体验,查看执行流,可以更改目标状态,熟悉的工具在熟悉的设置。 中断用户体验,可能需要努力重复重现问题,可能会影响安全性,而不是始终是生产系统上的选项。 具有重现很难从故障点返回以确定原因。 没有前期编码,低侵入性,基于触发器。 连续快照或实时转储提供简单的“随时间推移”视图。 如果不使用,则开销实质上为零。 遥测 & 日志 轻量级,通常与业务方案/用户操作相关联,机器学习友好。 在没有遥测) 的情况下, (意外的代码路径中会出现问题。 缺少静态编译到代码中的数据深度。 时间行程调试 (TTD) 非常适合复杂的 bug,无需前期编码,脱机可重复调试,分析友好,捕获一切。 记录时开销较大。 可能会收集更多所需的数据。 数据文件可能会变大。

若要了解有关 TTD 的详细信息,请参阅这些视频。

碎片整理工具 185 - Ivette 和 JamesP 了解 TTD 的基础知识并演示 WinDbg 中的一些功能

碎片整理工具 186 - Jordi 和 JCAB 演示 WinDbg 中 TTD 的更多出色功能

CppCon (YouTube) - Jordi、Ken 和 JamesM 在 CppCon 2017 上在 WinDbg 中展示了 TTD

跟踪文件基础知识

跟踪文件大小

跟踪文件可能会变得很大,TTD 的用户需要确保有足够的可用空间。 如果录制程序数分钟,跟踪文件可能会迅速增长到几 GB。 TTD 不会设置跟踪文件的最大大小,以允许复杂的长时间运行方案。 快速重新创建问题,将使跟踪文件大小尽可能小。

跟踪和索引文件

( .run ) 跟踪文件存储录制过程中的代码执行。

停止录制后,将创建一个索引文件 ( .idx ) ,以优化对跟踪信息的访问。 当 WinDbg 打开跟踪文件时,也会自动创建索引文件。

索引文件也可以很大,通常为跟踪文件的两倍。

可以使用 命令从跟踪文件重新创建索引文件 !tt.index

0:000> !tt.index
Successfully created the index in 10ms.

记录错误和其他录制输出将写入 WinDbg 日志文件。

所有输出文件都存储在用户配置的位置。 默认位置位于用户文档文件夹中。 例如,对于 User1,TTD 文件将存储在以下位置:

C:\Users\User1\Documents

有关处理跟踪文件的详细信息,请参阅 时间行程调试 - 使用跟踪文件

需要注意的事项

防病毒不兼容

由于 TTD 如何挂钩到进程来记录它们,因此可能会遇到不兼容问题。 尝试跟踪和隐藏系统内存调用的防病毒或其他系统软件通常会出现问题。 如果遇到录制问题(例如权限不足消息),请尝试暂时禁用任何防病毒软件。

尝试阻止内存访问的其他实用程序也可能出现问题,例如 Microsoft 增强的缓解体验工具包。

与 TTD 冲突的环境的另一个示例是电子应用框架。 在这种情况下,跟踪可能会进行记录,但也可能发生所记录进程的死锁或崩溃。

仅限用户模式

TTD 目前仅支持用户模式操作,因此无法跟踪内核模式进程。

你可以及时返回,但无法更改历史记录。 可以使用读取内存命令,但不能使用修改或写入内存的命令。

系统保护的进程

某些受 Windows 系统保护的进程(如受保护的进程灯 (PPL) 进程)受到保护,因此 TTD 无法将自身注入受保护的进程,以允许记录代码执行。

录制对性能的影响

记录应用程序或进程会影响电脑的性能。 实际性能开销因录制期间执行的代码的数量和类型而异。 在典型录制方案中,性能命中率大约为 10-20 倍。 有时不会有明显的减速,但对于资源密集型操作 (,即“文件打开”对话框) 可以看到录制的影响。

跟踪文件错误

在某些情况下,可能会出现跟踪文件错误。 有关详细信息,请参阅 时间行程调试 - 故障排除

时间行程调试的高级功能

下面是一些最值得注意的 TTD 高级功能。

时间线是执行期间发生的事件的可视表示形式。 这些事件可以是以下位置:断点、内存读/写、函数调用和返回以及异常。 有关时间线的详细信息,请参阅 WinDbg - 时间线

调试器数据模型支持

  • 内置数据模型支持 - TTD 包括数据模型支持。 使用 LINQ 查询分析应用程序故障可能是一个功能强大的工具。 可以使用 WinDbg 中的数据模型窗口来处理可展开和可浏览的“dx”和“dx -g”版本,使你能够使用 NatVis、JavaScript 和 LINQ 查询创建表。
  • 有关调试器数据模型的常规信息,请参阅 WinDbg - 数据模型。 有关使用 TTD 调试器对象模型的信息,请参阅 时间行程调试 - 时间旅行调试对象简介

  • 脚本自动化 - 对 JavaScript 和 NatVis 的脚本支持允许问题调查的自动化。 有关详细信息,请参阅 时间旅行调试 - JavaScript 自动化
  • 有关使用 JavaScript 和 NatVis 的一般信息,请参阅 WinDbg - 脚本。

    TTD.exe 命令行实用工具

    可以使用用于记录跟踪的 TTD.exe 命令行实用工具。 有关详细信息,请参阅 Time Travel Debugging - TTD.exe 命令行实用工具

    托管代码 TTD 支持

    可以使用在 64 位模式下运行的 SOS 调试扩展 (sos.dll) 在 WinDbg 中使用 TTD 调试托管代码。 有关详细信息,请参阅 使用 Windows 调试器调试托管代码

    TTD 入门

    查看这些主题以记录和重播跟踪文件,以及有关使用跟踪文件和进行故障排除的信息。

  • 时间旅行调试 - 记录跟踪
  • 时光穿越调试 - 重放跟踪
  • 时光穿越调试 - 使用跟踪文件
  • 时光穿越调试 - 故障排除
  • 时光穿越调试 - 示例应用演练
  • 这些主题介绍时旅行调试的其他高级功能。

  • 时光穿越调试 - 时光穿越调试对象简介
  • 时光穿越调试 - JavaScript 自动化
  •