以下是完整的第8章调试驱动程序的 Markdown 文档,可直接复制保存为 .md 文件使用:
第8章:调试驱动程序
以下章节将介绍如何调试硬件访问应用程序代码。
8.1 用户模式调试
由于 WinDriver 从用户模式访问,我们建议你首先使用标准调试软件(如编译器的调试器)调试代码。
调试监视器(Debug Monitor)是一款功能强大的图形模式和控制台模式工具,用于监控 WinDriver 内核处理的所有活动。你可以使用该工具监控发送到内核的每个命令的执行方式。
此外,WinDriver 允许你使用 WD_DebugAdd() 函数或高级 PrintDbgMessage() 函数,将自定义调试信息输出到调试监视器。注意,该函数可从用户模式和内核模式代码(使用 WinDriver 的内核插件功能创建)中调用,也可在高 IRQL 运行的函数(如内核插件 KP_IntAtIrql() 函数)中调用。
调试监视器有两个版本:
-
wddebug_gui— 图形界面(GUI)版本 -
wddebug— 控制台模式版本
注意,wddebug_gui 适用于所有受支持的桌面操作系统,但目前不适用于 Linux ARM/ARM64 平台。对于这些平台,请使用控制台模式的 wddebug。
两个版本的调试监视器均位于 WinDriver/util 目录中。
WD_DebugAdd() 函数可从用户模式和内核模式代码(使用 WinDriver 的内核插件功能创建)中调用,也可在高 IRQL 运行的函数(如内核插件 KP_IntAtIrql() 函数)中调用。
你也可以选择将调试信息发送到内核调试器,而非调试监视器日志(下文将详细说明)。例如,若开发电脑出现系统崩溃(蓝屏死机/BSOD)或挂起,你可以在另一台电脑上记录调试信息。
大多数 WinDriver 函数都有返回值,用于指示成功状态或相关错误代码,这有助于调试过程。返回状态码定义在 WD_ERROR_CODES 枚举中。
使用内核插件(Kernel PlugIn)在核内开发代码时,你也可以在调试过程中使用任何内核调试器(例如,WinDbg — 随 Windows 驱动程序工具包(WDK)分发,是 Windows 调试工具包的一部分,可通过 Microsoft 网站获取)。如前所述,你也可以选择将调试监视器的调试信息定向到所选的内核调试器。
8.2 调试监视器
调试监视器工具会记录来自 WinDriver 内核模式和用户模式 API 的调试信息。你也可以使用 WinDriver API 将自定义调试信息发送到调试监视器日志。
当调试监视器处于激活状态时,使用 WinDriver 的 API(如 WD_Transfer())在核内读写卡上的内存范围时,WinDriver 内核模块会验证内存范围,即检查内存读写操作是否在为该卡定义的范围内。
在调试过程中,使用 DriverWizard 检查内存、寄存器和配置的值。
8.2.1 wddebug_gui 工具
wddebug_gui 是适用于 Windows 和 Linux 的调试监视器工具的全图形界面(GUI)版本。
通过以下任一方法运行调试监视器:
-
运行
WinDriver/util/wddebug_gui。 -
从 DriverWizard 的“工具”菜单中运行调试监视器。
-
在 Windows 上,选择“开始 | 程序 | WinDriver | Debug Monitor”。
启动调试监视器

通过“调试选项”对话框设置调试监视器的状态、跟踪级别和调试章节信息,可通过以下方式激活该对话框:
-
调试监视器的“视图 | 调试选项”菜单
-
调试选项工具栏按钮
调试选项

-
状态(Status)—— 设置跟踪开启或关闭。
-
章节(Section)—— 选择要监控的 WinDriver API 部分。例如,若 PCI 卡的中断处理程序出现问题,选择“PCI”和“中断(Interrupts)”章节;USB 开发人员应选择“USB”章节。请谨慎选择要监控的章节,勾选过多不必要的选项可能导致信息溢出,难以定位问题。
-
级别(Level)—— 选择为已定义资源显示的信息级别。“错误(Error)”是最低跟踪级别,屏幕输出最少;“跟踪(Trace)”是最高跟踪级别,会显示 WinDriver 内核执行的每一项操作。
-
向操作系统内核调试器发送调试信息—— 勾选此选项可将来自 WinDriver 内核模块的调试信息除发送到调试监视器外,还发送到外部内核调试器。
在 Windows 上,首次启用此选项时需要重启电脑。免费的 Windows 内核调试器 WinDbg 随 Windows 驱动程序工具包(WDK)分发,是 Windows 调试工具包的一部分,可通过 Microsoft 网站获取。
- 驱动程序名称(Driver Name)—— 此字段显示当前正在调试的驱动程序名称,修改该名称可调试重命名后的 WinDriver 驱动程序。
定义好要跟踪的内容和级别后,点击“确定(OK)”关闭“调试选项”窗口。
可通过调试监视器的菜单和工具栏进行其他配置。调试系统崩溃或挂起时,除了将调试信息发送到操作系统内核调试器外,还可通过“文件 | 切换自动保存(File | Toggle Auto-Save)”菜单选项(也可通过工具栏图标)自动保存调试监视器日志,这非常有用。
运行应用程序(分步运行或一次性运行)。
你可以使用“编辑 | 添加自定义信息(Edit | Add Custom Message...)”菜单选项(也可通过工具栏图标)向日志中添加自定义信息,这对于在日志中清晰标记不同的执行章节特别有用。
查看调试监视器日志(或内核调试器日志,若已启用),查找错误或任何意外信息。
8.2.1.1 在 wddebug_gui 中搜索
wddebug_gui 提供 4 种方式在调试输出中查找表达式:
-
用键盘输入表达式时,会立即在调试输出中搜索该表达式。
-
按下
CTRL+F显示工具栏中的“查找(Find)”字段。 -
点击工具栏中的“查找(Find)”图标。
-
选择“编辑 | 查找(Edit | Find...)”。
找到表达式后会对其进行标记,可使用“上一个(Prev,F2)”和“下一个(Next,F3)”浏览表达式的多个匹配项。

8.2.1.2 用 wddebug_gui 打开 Windows 内核崩溃转储文件
在驱动程序开发中,内核崩溃导致蓝屏死机(BSOD)的情况并不少见。为帮助开发人员调试和解决这些崩溃问题,WinDriver 允许将其内核调试信息保存在系统崩溃时 Windows 自动创建的内存转储文件中。系统重启后,可在 wddebug_gui 中打开这些崩溃转储文件。
按以下步骤将调试信息定向到内核调试器:
-
打开所选的内核调试器。
-
运行调试监视器,并通过以下任一方法选择将 WinDriver 调试信息定向到内核调试器:
-
打开调试监视器的图形界面版本
wddebug_gui(适用于 Windows、Linux 和 MacOS),在“调试选项”窗口中勾选“向操作系统内核调试器发送调试信息”选项,然后点击“确定(OK)”。 -
运行调试监视器的控制台模式版本
wddebug(适用于所有受支持的操作系统),并附带dbg_on命令:
-
WDDEBUG [<driver_name>] dbg_on [<level>] \ [<sections>]
-
选择“文件 | 符号文件路径(File | Symbol File Path...)”,加载驱动程序的符号文件
MyDriver.pdb(默认驱动程序的文件名为lib/windrvr1650.pdb)。请勿跳过此步骤,否则内核转储文件可能无法理解。 -
选择“文件 | 处理内核转储(File | Process Kernel Dump...)”,加载内核崩溃转储文件(.dmp)。
wddebug_gui将显示崩溃转储文件的输出内容。
Windows 用户可使用 Microsoft 的 WinDbg 工具,该工具随 Windows 驱动程序工具包(WDK)分发,是 Windows 调试工具包的一部分,可通过 Microsoft 网站获取。
8.2.1.3 为已重命名的驱动程序运行 wddebug_gui
默认情况下,wddebug_gui 会记录来自默认 WinDriver 内核模块(windrvr1650.sys/.dll/.o/.ko)的信息。但你也可以通过以下两种方式,使用 wddebug_gui 记录此驱动程序重命名版本的调试信息(见第17章:驱动程序安装 — 高级问题):
-
在
wddebug_gui中,选择“视图 | 调试选项(View | Debug Options)”,将“驱动程序名称(Driver name)”字段的值修改为你重命名后的驱动程序名称。 -
在命令行中运行
wddebug_gui,并附带driver_name参数:
`wddebug_gui <driver_name>`
驱动程序名称应设置为驱动程序文件的名称(不含文件扩展名),例如 windrvr1650,而非 Windows 上的 windrvr1650.sys 或 Linux 上的 windrvr1650.o。例如,若你在 Windows 上将默认的 windrvr1650.sys 驱动程序重命名为 my_driver.sys,可通过以下命令运行调试监视器,以记录该驱动程序的信息:
`wddebug_gui my_driver`
8.2.2 wddebug 工具
8.2.2.1 控制台模式 wddebug 执行
调试监视器工具的 wddebug 版本可在所有受支持的操作系统(Windows 和 Linux)上作为控制台模式应用程序执行。要使用控制台模式的调试监视器版本,请按以下方式运行 WinDriver/util/wddebug。
wddebug 控制台模式用法
wddebug [<driver_name>] [<command>] [<level>] [<sections>]
wddebug 的参数必须按上述用法说明中的顺序提供。
<driver_name>— 要应用命令的驱动程序名称。
驱动程序名称应设置为 WinDriver 内核模块的名称(默认:windrvr1650),或该驱动程序的重命名版本(参见 17.2 重命名 WinDriver 内核驱动程序中的说明)。请注意,驱动程序名称应设置为驱动程序文件的名称(不含文件扩展名),例如 windrvr1650,而非 Windows 上的 windrvr1650.sys 或 Linux 上的 windrvr1650.o。
<command>— 要执行的调试监视器命令。
激活命令
| 命令 | 描述 |
|---|---|
on |
开启调试监视器。 |
off |
关闭调试监视器。 |
dbg_on |
将调试信息从调试监视器重定向到内核调试器,并开启调试监视器(若尚未开启)。在 Windows 上,首次启用此选项时可能需要重启电脑。on 和 dbg_on 命令可与 <level> 和 <sections> 参数一起使用。 |
dbg_off |
停止将调试信息从调试监视器重定向到内核调试器。 |
dump |
持续向命令提示符发送(转储)调试信息,直到用户选择停止(按照命令提示符中显示的说明操作)。 |
status |
显示有关运行中驱动程序(<driver_name>)、当前调试监视器状态(包括调试监视器开启时的活动调试级别和章节)以及调试信息缓冲区大小的信息。 |
clock_on |
为每条调试信息添加时间戳。时间戳相对于驱动程序加载时间或最后一次 clock_reset 命令的执行时间。 |
clock_off |
不为调试信息添加时间戳。 |
clock_reset |
重置调试信息时间戳时钟。 |
sect_info_on |
为每条调试信息添加章节信息。 |
sect_info_off |
不为调试信息添加章节信息。 |
help |
显示用法说明。 |
| 无参数(包括无命令) | 等同于运行 wddebug help。 |
仅适用于 on 或 dbg_on 命令的参数
| 参数 | 描述 |
|---|---|
<level> |
要设置的调试跟踪级别 — 以下标志之一:ERROR、WARN、INFO 或 TRACE(默认)。ERROR 是最低跟踪级别,TRACE 是最高级别(显示所有信息)。若设置了 <sections> 参数,则必须同时设置 <level> 参数(无默认值)。 |
<sections> |
要监控的调试章节(即 WinDriver API 章节)。此参数可设置为 ALL(默认,监控所有受支持的调试章节),或包含任何受支持调试章节标志组合的带引号字符串(运行 wddebug help 查看完整列表)。 |
用法流程
要使用 wddebug 记录信息,请按以下流程操作:
-
运行
wddebug并附带on或dbg_on命令,开启调试监视器;后者会在开启调试监视器之前,将调试信息重定向到操作系统内核调试器。你可以使用<level>和<sections>参数设置日志的调试级别和章节。若未明确设置这些参数,将使用默认值;(注意,若设置了章节,必须同时设置级别)。你也可以在命令前指定重命名后的 WinDriver 驱动程序名称(默认:windrvr1650),以记录该驱动程序的信息 — 见<driver_name>参数。 -
若未选择将调试信息重定向到操作系统内核调试器(使用
dbg_on命令),运行wddebug并附带dump命令,开始将调试信息转储到命令提示符。你可以随时按照命令提示符中显示的说明,关闭调试信息的显示。 -
运行使用该驱动程序的应用程序,查看正在记录到命令提示符/内核调试器的调试信息。
-
调试监视器运行期间,你可以随时运行
wddebug并附带以下命令:-
status、clock_on、clock_off、clock_reset、sect_info_on或sect_info_off -
带有不同
<level>和/或<sections>参数的on或dbg_on -
dbg_on和dbg_off— 切换是否将调试信息重定向到操作系统内核调试器 -
dump— 开始将调试日志新转储到命令提示符;(可随时按照提示符中的说明停止转储)
-
-
完成后,运行
wddebug并附带off命令,关闭调试监视器。
即使调试监视器处于关闭状态,也可使用 status 命令查看有关运行中 WinDriver 驱动程序的信息。
示例
以下是典型的 wddebug 用法流程示例。由于未设置 <driver_name>,命令将应用于默认驱动程序 windrvr1650。
- 以最高跟踪级别开启调试监视器,监控所有章节:
wddebug on TRACE ALL
这与运行 `wddebug on TRACE` 相同,因为 `ALL` 是 `<sections>` 的默认值。
- 持续将调试信息转储到命令提示符或文件,直到用户选择停止:
wddebug dump
wddebug dump <filename>
-
之后,使用该驱动程序并在命令提示符中查看调试信息。
-
关闭调试监视器:
wddebug off
8.2.2.2 在测试机器上调试
要在未安装 WinDriver 的机器上调试 WinDriver 应用程序和驱动程序,请按以下步骤操作:
-
将
WinDriver\util\wddebug.exe复制到测试机器。 -
从目标机器的命令行运行
wddebug dump。 -
在另一个窗口中运行你的应用程序。
-
使用
CTRL+C停止wddebug工具。
8.3 常见问题解答(FAQ)
8.3.1 应使用 wddebug_gui 还是 wddebug?
为什么使用 wddebug_gui?
- 图形界面版本提供更便捷的搜索选项,在现代桌面操作系统上使用更舒适。
为什么使用 wddebug?
-
图形界面版本依赖 Qt,运行速度比控制台版本慢,在某些情况下,与应用程序同时运行时可能会降低应用程序的运行速度。
-
若要在未安装 WinDriver 的机器(分发机器)上调试基于 WinDriver 的用户应用程序,在该机器上运行
wddebug_gui会更复杂,因为需要安装或复制所有 Qt DLL/.so 依赖项,调试监视器才能工作。相比之下,wddebug仅需要wdapi共享库(wdapi1650.dll/.so)。 -
wddebug的源代码位于WinDriver/samples/c/wddebug,这使你能够更灵活地修改该应用程序,以满足特定的调试需求。Jungo 不提供wddebug_gui的源代码。 -
wddebug更易于在脚本或远程控制台会话(如 PowerShell、SSH 等)中使用。
8.3.2 能否使用 MS Visual Studio(Visual C++)轻松调试基于 WinDriver 的代码?
可以!你编写的设备驱动程序代码在正常的 Win32 用户模式下运行。因此,你可以使用 MS Visual Studio 编译和调试代码。通常,基于 WinDriver 的用户代码可在任何支持在 Windows 中编译 C/C++ 应用程序的 IDE 上调试。
8.3.3 如何推荐调试基于 WinDriver 的应用程序?
除了使用本章所述的 wddebug_gui / wddebug 外,我们还建议在需要时使用以下工具:
-
基本用户模式开发:使用 IDE(如 Visual Studio / Visual Studio Code / XCode(MacOS))及其提供的调试器。其他推荐工具包括
valgrind(Linux)/Dr. Memory(Windows),用于定位内存泄漏。 -
调试对 WDAPI 共享库的调用:你可以使用其源代码(位于
WinDriver/src/wdapi)。 -
内核调试(适用于内核插件或识别 WinDriver 相关问题):在 Windows 上,可使用
WinDbg/WinDbg Preview。有关如何设置这些工具的更多信息,可在 MSDN 上获取。在 Linux/MacOS 上,可使用dmesg查看内核崩溃信息。MacOS 还会在指定目录(通常为~/Library/Logs)中为每个应用程序或内核崩溃提供崩溃转储文件。
原文链接:https://windriver.jungo.com/manual/ch8_debugging_drivers.html
(注:文档内容由 AI 生成,翻译正确性不做保证,只做参考,请参对比原文进行浏览,对于由翻译引起的问题不负任何责任 By chencarl)