使用单个服务器设置完整的 Windows 内核调试环境,用于 Windows 内核驱动程序






3.41/5 (11投票s)
本文旨在帮助用户使用虚拟机(VMware)为 Windows 设备驱动程序设置一个功能齐全的调试环境。用户无需配置调试器和被调试器,也无需使用零调制解调器电缆连接它们。
引言
Windows 内核开发人员传统上使用 WinDbg(Windows Debugger,有时也称为 Windbag),这是 Microsoft 提供的一个免费的 32 位和 64 位平台调试器(http://www.microsoft.com/whdc/devtools/debugging/default.mspx)。该调试器提供了不错的图形界面,并具有一套丰富的命令,用于调试内核模式驱动程序。开发人员甚至可以编写自己的自定义调试库,并将其与 WinDbg 一起使用(作为资源 DLL 或扩展)。虽然 WinDbg 对 Windows 内核模式调试非常有用,但它也可以用于调试用户模式应用程序。然而,传统上,开发人员使用 Visual Studio 集成调试器来调试他们的用户模式代码。我一直使用 WinDbg 来调试用户模式服务和模块,因为它相当轻量级,可以快速安装在任何系统上并开始工作。您只需要调试符号文件,即 *.PDB 文件、相应的二进制文件以及构建它的源文件。我发现它特别有助于调试服务和检测内存泄漏(这将在另一篇文章中介绍)。对于 Windows 内核模式调试,我们不能使用 Visual Studio 中集成的传统调试器。WinDbg 是 Microsoft 推荐的用于内核模式驱动程序调试的工具。有一些第三方调试工具,但 WinDbg 是免费的,并且大多数时候都能完成工作。
当我开始为 Windows NT 编写 Windows 设备驱动程序,然后是 Win2K 时,我的桌子上总是有两台系统:一台调试器和一台被调试器。这是我唯一能使用 WinDbg 调试驱动程序的方法。这相当麻烦,特别是两台机器通过 COM 端口(串行端口)的零调制解调器电缆连接。速度非常慢,有时甚至难以让两台系统通信。不过,后来波特率有所提高,一旦有了始终配置为调试器的笔记本电脑,事情就没那么难了。然而,这种方法仍然需要开发人员携带笔记本电脑并进行连接设置;现在的好消息是,您可以使用更快的火线连接进行调试,而不是串行电缆。但是,提及两台系统会让许多习惯使用 Visual Studio 等工具在单系统上调试应用程序的人望而却步。我这里展示的方法可以在单台机器上设置 Windows 内核调试环境,并且不需要复杂的设置或花哨的电缆和接口。
随着虚拟机技术的出现,使用一台服务器并通过主机到虚拟机客户机进行调试变得更加容易,无需设置任何电缆或进行花哨的设置。我在我的环境中大量使用虚拟机进行调试,我觉得与社区分享如何轻松设置 Windows 设备驱动程序调试环境会很棒。
设置调试环境的步骤
大多数想要调试和学习 Windows 设备驱动程序的开发者通常会面临需要两台物理机器(一台调试器和一台被调试器),然后使用零调制解调器电缆连接它们的需求。通常,购买了电缆并确定了两台机器后,您还会遇到波特率和同步两台系统的问题;此外,电缆故障也可能阻止通信。您无法简单地使用笔记本电脑调试系统这一事实就让大多数人望而却步。
在本文中,我将重点介绍一个可以在独立系统(笔记本电脑)上完成的简单设置,它将帮助您调试任何 Windows 设备驱动程序。
为了在同一台机器上同时设置调试器和被调试器,您需要让目标(被调试器)运行在虚拟机上。为此,最简单的选择是免费下载 VMware Workstation 并安装一个 Windows 客户操作系统。所以,您的被调试器将是 VMware 客户机,而主机操作系统将充当您的调试器。在主机上,您需要安装 WinDbg(从 Microsoft 免费下载最新版本)。以下是帮助您完成设置的分步过程。
- 确保您已在主机系统上下载并安装了相应的 WinDbg 版本。
- 在被调试器系统(客户操作系统)上,为系统添加一个串行端口。在串行端口设置中,执行以下操作 [参考图片]
- 确保选择了“使用命名管道”选项。
- 为命名管道定义一个合适的名称,或者直接使用提供的名称。
- 选择“此端是服务器”。
- 选择“另一端是应用程序”。
- 勾选“轮询时让出 CPU”选项。
下图显示了虚拟机上的设置应该是什么样子。
- 在客户操作系统(被调试器)上,您需要修改引导选项,以便在客户机重新启动时能够切换到调试模式。以下是修改引导选项的步骤:
- Bcdedit /copy {current} /d DebugEntry
- Bcdedit /displayorder {current} {copied entry's GUID: will be generated by the previous command}
(通过此操作,我们在现有的引导顺序中创建了一个名为 DebugEntry 的新条目。)要更改调试设置:
- Bcdedit /set {GUID} debugport 1
- Bcdedit /set {GUID} debugtype serial
- Bcdedit /set {GUID} baudrate 115200
- bcdedit /debug {}
- 完成上述步骤后,您应该会有一个新的引导顺序,其中包含 DebugEntry – 基本上,下次重新启动时,您可以以调试模式启动操作系统。
- 在主机方面,启动 WinDbg 调试器,然后转到“文件”->“内核调试”选项,设置以下选项:
- 选择“COM”选项卡,因为我们正在设置一个用于调试的 COM 端口。
- 将端口名称设置为我们在虚拟机中创建的命名管道。
- 选择“Pipe”复选框,因为我们通过命名管道模拟 COM 端口。
- 将波特率设置为 115200(这与我们在引导选项中设置的相同)。
下图显示了安装在主机机器上的调试器上的设置。
- 转到“文件”->“符号文件路径”,并设置指向您的符号目录(您的 PDB 文件)的路径;同时转到“源文件路径”,并将其设置为您的源代码树的顶级目录 [确保符号、源文件和驱动程序映像彼此匹配]。
- 完成所有这些操作后,您应该已经准备就绪,可以在代码中设置适当的断点。
脚注
本文的主要重点是如何快速设置调试环境。我假设您已经知道您的驱动程序是如何工作的,并且可能已经在双机设置上进行过调试。在未来的帖子中,我将介绍调试器的其他方面,包括编写 WinDbg 扩展。