配置 EXDI 调试器传输
本主题介绍如何使用 EXDI 来设置内核模式调试。 扩展调试接口 (EXDI) 是软件调试器和调试目标之间的适应层。
从 Windows 版本 22000 开始,Windows 调试工具支持使用 EXDI 进行内核调试。
从版本 1.2410.11001.0 开始,调试器中提供了配置 EXDI 的用户界面。
EXDI 可用于与 QEMU 虚拟环境建立连接。 有关详细信息,请参阅 使用 EXDI 设置 QEMU 内核模式调试。
注意
EXDI 是一种针对特定环境的高级专业调试方式。 使用标准 KDNET 连接更容易配置,因此建议使用。 要自动设置网络调试,请参阅设置 KDNET 网络内核自动调试。
EXDI COM 服务器概述
EXDI 是一个接口,通过添加对硬件调试器(例如基于 JTAG 或基于 GdbServer)的支持来扩展 WinDbg。 下图说明了 EXDI-GdbServer 的作用。
COM 服务器是指实现 COM 接口的二进制组件。 在本例中,ExdiGdbSrv.dll为 Windows 调试器协议客户端实现 exdi3.idl。
ExdiGdbsrv.dll本身实现 GDB-RSP 协议的客户端,GDB 服务器端(有时称为 GDB 服务器存根)由 QEMU GDB 服务器(或 Trace32/OpenOCD/UEFI GDB 服务器存根等)实现。
由于 EXDI 连接不依赖于 Windows 或目标电脑上加载的 Windows 调试 KDNET 协议。 由于不需要这些软件调试器组件,因此 EXDI 在早期设备启动和调试 OS 启动问题中非常有用。
重要
由于 EXDI 未使用 KDNET 协议,因此连接的调试器所掌握的有关电脑上运行情况的信息要少得多,许多命令的运行方式也会不同,甚至根本无法运行。 访问被调试代码的专用符号有助于调试器更好地理解目标系统的代码执行。 有关详细信息,请参阅公共符号和专用符号。
EXDI 内核模式设备要求
运行调试器的计算机称为主计算机,正在调试的计算机称为目标计算机。
以下为必需项:
在目标和主机计算机上,有所需环境(例如 QEMU)支持的支持网卡。
目标和主机之间使用 TCP/IP 的网络连接。
Windows 10 或 Windows 11 版本 22000 或更高版本。
限制
如上所述,由于 EXDI 不使用 KDNET 协议,因此连接的调试器掌握的目标系统信息较少,并且调试器的使用不同。 如果不能访问目标代码的专用符号,许多使用符号来了解目标系统状态的命令将不起作用。 在这种情况下,可以查看内存并注册内容和反汇编代码。 如果没有私有符号,确定运行代码的位置或执行其他常见调试器任务就会非常困难和耗时。
并发 EXDI 和 KDNET 调试
在某些复杂的方案中,例如在早期设备启动中,与目标设备建立两个连接可能很有用。 一个 EXDI 和一个 KDNET。 如果目标是 Windows OS,则 KDNET 软件调试将按正常方式配置,例如连接到虚拟机。 在此设置中,两个并发调试器中的任何一个都可以中断以调试目标计算机上的代码。
进程服务器中的 WinDbg
二进制 EXDI 组件可以在 Windbg 进程或 Windbg 进程中运行。 使用 EXDI UI 或 Inproc=<EXDI COM server binary>
大幅提高可靠性,方法是减少 COM 启动错误。 因此,建议始终使用 Inproc 参数运行 EXDI 会话,该参数在使用 UI 时始终启用。
对于命令行启动,默认选项已退出进程,但应使用 InProc=ExdiGdbDrv.dll
参数启用进程内选项。
COM GDB 服务器客户端
本主题介绍实现 EXDI COM 调试器接口的 EXDI COM GDB 服务器客户端(ExdiGdbSrv.dll)。 可以使用同一 COM 接口来实现其他接口,例如 JTAG-DCI 的 EXDI COM 服务器。
使用 EXDI 连接的过程摘要
使用此过程将 EXDI 连接与 WinDbg 配合使用。
- 在主机系统中下载并安装 Windows 调试工具。
- 使用 UI 或 -kx 选项启动 WinDbg 以连接到 EXDI 服务器。
- 使用 WinDbg 使用一组可用的调试器命令调试目标系统。
有关 EXDI 使用方案的示例,请参阅 使用 EXDI 设置 QEMU 内核模式调试。
下载并安装 Windows 调试器工具
在主机系统上安装 Windows 调试工具。 有关下载和安装调试器工具的信息,请参阅适用于 Windows 的调试工具。
启动 WinDbg 并连接到 EXDI 服务器
可以在 EXDI 内核连接 UI 中配置以下选项。
目标类型
[Trace32|BMC-OpenOCD|QEMU|VMWare|UEFI]
根据要调试的目标类型选择。 以下目标类型可用。- Trace32:Lauterbach Trace32 HW 调试器 GDB 服务器配置
- BMC-OpenOCD :BMC-OpenOCD HW 调试器 GDB 服务器配置
- QEMU:QEMU SW 模拟器 GDB 服务器配置
- VMWare:VMWare GDB 服务器配置
- UEFI:UEFI 固件调试
目标体系结构
[x86 | ARM64 | x64]
- 目标处理器体系结构。 请注意,所有目标类型都可能不支持所有目标体系结构。目标 OS
[Windows|Linux]
- 根据要调试的目标 OS 进行选择。图像扫描启发式大小
[None | 0xFE - PreNT |0xFFE - NT]
- 选择三个选项之一来确定图像扫描的启发式大小。 此值配置调试器引擎如何扫描查找 PE DOS 签名的内存,该签名用于收集代码执行状态。 如果未指定属性值(或“0”),则调试器引擎不会使用快速启发法并回退到扫描整个内存以查找 PE DOS 签名的旧试探法。 为每个目标类型选择默认值,建议使用默认值。Gdb 服务器和端口
TargetIPAddress:TargetPortAddress
- 设置为包含的字符串、IPTargetAddress、冒号和目标 PortAddress。 例如LocalHost:1234
或168.82.1.5:5555
。连接中断
[on|off]
选中复选框以在建立连接后闯入目标。高级选项
显示通信数据包日志
[on|off]
- 选中复选框以显示原始 GDBServer 通信数据包日志中的十六进制值,以便进行调试和故障排除。
选择所需选项后,选择“ 确定 ”进行连接。
使用 EXDI 配置 XML 文件配置高级选项
本主题中所述的用户界面中提供了大多数必需的选项。 有关使用 EXDI 配置 XML 文件配置高级选项的信息,请参阅 EXDI XML 配置文件。
WinDbg 命令行 EXDI 示例
若要在命令提示符处启动使用 EXDI 接口的 windbg 会话,请使用这些选项。
c:\Debuggers> windbg.exe -v -kx exdi:CLSID={29f9906e-9dbe-4d4b-b0fb-6acf7fb6d014},Kd=Guess,InProc=ExdiGdbDrv.dll,DataBreaks=Exdi
要显示用于诊断目的的其他输出,可以使用 -v: 详细会话。 有关 WinDbg 选项的一般信息,请参阅 WinDbg 命令行选项。 有关详细信息,请参阅下方的 EXDI WinDbg 加载参数。
调试器控制台将显示 EXDI 传输初始化。
EXDI: DbgCoInitialize returned 0x00000001
EXDI: CoCreateInstance() returned 0x00000000
EXDI: QueryInterface(IExdiServer3) returned 0x00000000
EXDI: Server::GetTargetInfo() returned 0x00000000
EXDI: Server::SetKeepaliveInterface() returned 0x00000000
EXDI: Server::GetNbCodeBpAvail() returned 0x00000000
EXDI: ExdiNotifyRunChange::Initialize() returned 0x00000000
EXDI: LiveKernelTargetInfo::Initialize() returned 0x00000000
EXDI: Target initialization succeeded
Kernel Debugger connection established
EXDIGdbServer 控制台窗口还可以显示有关 EXDI 连接状态的信息。 有关控制台的详细信息,请参阅故障排除。
EXDI WinDbg 加载参数
以下参数用于 WinDbg 来启动 EXDI 内核会话。
-kx EXDI:Options
以下 EXDI 选项可用于 -kx 选项。 应使用逗号分隔每个选项。
参数 | 说明 |
---|---|
CLSID | 分配给 LiveExdiGdbSrvServer 的类 ID(如 ExdiGdbSrv.idl 文件中定义)。 |
Kd=Guess -or- NtBaseAddr | 调试器引擎将使用常规启发式机制 -或 - 查找 NT 基址。 |
ForceX86 | 强制调试器引擎使用 IeXdiX86Context3 接口获取/设置 CPU 上下文。 |
DataBreaks=Exdi | 允许使用数据断点。 |
Inproc | 允许使用 inproc Exdi-Server。 建议使用此选项 - InProc=ExdiGdbDrv.dll |
PathToSrvCfgFiles | EXDI 的 XML 配置文件的路径。 |
控制启发式搜索和启发式大小
如前所述,调试器使用启发式算法来查找 NT 基址。 若要取消启发式搜索,请在通过命令行启动 WinDbg 时完成以下步骤。
- 将要附加到的目标服务器的exdiconfigdata.xml文件中的启发式ScanSize 设置为 0。
- 在
kd=NtBaseAddr
Windbg 命令行上使用启发式类型。
有关使用 XML 配置文件的详细信息,请参阅 EXDI XML 配置文件。
使用 WinDbg 调试目标系统 - 断点
dbgeng.dll 使用启发式算法来查找中断命令发生时 NT 基本加载地址的位置。 如果没有专用符号,此过程将失败。
这意味着在许多连接序列下,中断将无法发挥预期的功能。 如果手动侵入代码,它将是 Windows 当时正在执行的一个随机位置。 由于可能无法获得目标代码的符号,因此很难使用符号设置断点。
调试器命令
以下直接访问内存的命令可以正常使用。
d、da、db、dc、dd、dD、df、dp、dq、du、dw(显示内存)
可以使用 p (Step) 单步执行代码。
还可以使用一些命令来尝试查找要调试的代码。
Imgscan 对 EDXI 调试很有帮助,因为与传统的基于 KDNET 的内核调试不同,它可能无法根据符号设置断点。 定位所需的目标图像,可以方便地使用其位置来设置内存访问断点。
.exdicmd(EXDI 命令)
.exdicmd 使用活动 EXDI 调试连接向目标系统发送 EXDI 命令。 有关详细信息,请参阅 .exdicmd(EXDI 命令)。
故障排除
使用 ExdiGdbServer 窗口中的输出监视连接序列。
问题:错误:无法与 GbDServer 建立连接。 验证连接字符串 <hostname/ip>:portnumber
此问题可能是由以下原因造成的:
- ExdiGdbSrv.dll无法连接到目标 GDB 服务器。
- GDB 服务器尚未在目标上运行。
- 防火墙问题,使用 ping、tracert 或其他工具验证 GDB 流量是否可以通过防火墙,以确保两个 IP 地址都可以访问。
问题:目标系统的错误方案不可用 - DbgCoInitialize 返回 0x00000001
如果目标系统未加载或无法使用,可能会返回以下输出结果。
Microsoft (R) Windows Debugger Version 10.0.20317.1 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
EXDI: DbgCoInitialize returned 0x00000001
当 ExdiGdbSrv.dll COM 服务器无法连接到 QEMU GDServer 时,这是一个常见错误,因此可能会由于以下原因而失败:
ExdiGdbSrv.dll 的上一个会话仍由 dllhost.exe 进程托管,因此需要终止 dllhost.exe 进程。 在命令提示符下使用
TaskList
,找到承载ExdiGdbSrv.dll的dllhost.exe的 PID。 使用TaskKill /PID <PID ID> /f
并终止关联的 PID。 有关使用 PID 的详细信息,请参阅 查找进程 ID。QEMU gdbserver 尚未启动,或者 exdiconfigdata.xml 文件包含无效的 IP:Port 值。 如果 WinDbg 会话是在与 QEMU Windows 虚拟机相同的主机上启动的,则 IP=LocalHost.
通过 dllhost.exe 进程(COM 相关)启动 EXDI COM 服务器 (ExdiGDbSrv.dll) 时失败。 要解决此问题,请重启主机调试器电脑或注销 Windows 并再次登录。 如果这不起作用,请在再次重启/登录后重新注册 EXDI COM 服务器。
regsvr32.exe <full path to the ExdiGdbSrv.dll)
问题:无法启动调试会话:FAILURE HR=0x80004005:Failed to AttachKernel。
此问题可能是由以下原因造成的:
- 如上所述,ExdiGdbSrv.dll 的上一个会话可能仍然处于活动状态。 如上所述,找到并终止相关的 DLL 主机。
问题:无法使用 EXDI 启动内核调试。
此问题可能是由以下原因造成的:
- 在主机调试器计算机上运行 ExdiGdbSrv.dll(由 dllhost.exe 托管)的另一个实例。
- 终止托管 ExdiGdbSrv.dll 的 COM 服务的额外实例。
- 首先使用主机电脑上的实用工具(如 TList)列出进程。 承载 ExdiGdbSrv.dll 的 DLLHost 将显示 ExdiGdbServer。
tlist 261928 dllhost.exe ExdiGdbServer
- 在调试器命令提示符处使用
kill -f XXXXX
通过进程编号终止进程。
- 首先使用主机电脑上的实用工具(如 TList)列出进程。 承载 ExdiGdbSrv.dll 的 DLLHost 将显示 ExdiGdbServer。
问题:错误:无法配置 GdbServer 会话。
此问题可能是由以下原因造成的:
- 查找会话信息时出错,例如 XML 配置文件的路径。
问题:错误:未定义 EXDI_GDBSRV_XML_CONFIG_FILE 环境变量。
此问题可能是由以下原因造成的:
- ExdiGdbSrv.dll 环境变量未设置或在环境中不可用。
问题:错误:未定义EXDI_GDBSRV_XML_CONFIG_FILE环境变量。 Exdi-GdbServer 示例目前不会继续。 设置 Exdi XML 配置文件的完整路径。
此问题可能是由以下原因造成的:
- 未设置 EXDI_GDBSRV_XML_CONFIG_FILE 环境变量。 在某些情况下,如果按“OK”键,ExdiGDbSrv.dll 将继续工作,但 windbg.exe 将无法查询系统寄存器(例如通过 rdmsr/wrmsr 函数)。