windows显示驱动开发-调试间接显示驱动程序(二)
控制捕获的内容
在这种情况下 ,logman.exe 的 Flags 参数 (0x4f4) 控制 IddCx 记录的 WPP 消息。 此 的含义值在 Windows 版本 19041 及更高版本中已更改。
Windows 内部版本 19041 及更高版本的标志的含义
Flags 是一个位字段,其中每个位控制是否捕获该类型的消息。
标志位 | 捕获的消息类型 |
---|---|
0x001 | 未使用 |
为 0x002 | 未使用 |
0x004 | 错误 |
0x008 | 良性错误,例如在没有设置D3D11_CREATE_DEVICE_BGRA_SUPPORT的情况下启用调试覆盖时 |
0x010 | IddCx 对象 |
0x020 | UMDF 框架调用 IddCx |
0x040 | 从 IddCx 到驱动程序的 DDI 调用 |
0x080 | 从驱动程序到 IddCx 的低频率调用 |
0x100 | 从驱动程序到 IddCx 的与帧相关的高频率调用 |
0x200 | 从驱动程序到 IddCx 的与游标相关的高频率调用 |
0x400 | 从内核调用 IddCx |
0x800 | 从 IddCx 调用内核 |
0x0f4的正常日志记录方案是一个很好的起点。 如果要查看每个帧的信息,则0x1f4是一个很好的起点。
Windows 内部版本 19041 之前的标志含义
标志被视为一个级别,每个递增级别都添加了一种新的消息类型以及以前级别中的所有消息。
标志级别值 | 捕获的消息类型 |
---|---|
1 | 未使用 |
2 | 错误 |
3 | 警告 |
4 | 信息 |
5 | 详细 |
解码 IddCx WPP 跟踪
与所有 WPP 跟踪一样,WPP 信息存储在 pdb 文件中,因此需要使用该信息访问 pdbs 才能解码。 从 Windows 内部版本 19560 开始,公共符号服务器上的 IddCx.pdb 包含解码 WPP 消息所需的 WPP 信息。 在 Windows 内部版本 19560 之前,公共符号服务器上的 IddCx.pdb不包含 启用 WPP 解码所需的 WPP 信息。
任何标准 WPP 解码工具都可用于解码和显示消息。
调试 IddCx 错误
在开发间接显示驱动程序时,当 IddCx 检测到错误时,获取其他信息通常很有用。 如上所述,可以将 IddCx 配置为在 IddCx 检测到错误时闯入调试器,但在最后几个跟踪消息中显示 IddCx 错误消息来了解错误的上下文也很有用。
使用上一部分,可以使用 logman.exe 启用 WPP 跟踪,并结合以下信息在发生故障时在内核调试器中显示内存中的 WPP 缓冲区。
为此,需要使用内核调试器 (而不是用户模式调试器) 和 Windows 版本 19560 或更高版本,以便调试器获取包含 WPP 解码信息的 IddCx.pdb 。
在下面的示例中,间接显示驱动程序调用 IddCxMonitorArrival。 作为处理的一部分,IddCx 调用驱动程序的 EvtIddCxMonitorQueryTargetModes DDI。 在此示例中,驱动程序返回了具有DISPLAYCONFIG_VIDEO_SIGNAL_INFO的模式。AdditionalSignalInfo.vSyncFreqDivider 设置为零,这无效并导致错误。
下面是使用的调试器命令的列表:
命令 | 含义 |
---|---|
!wmitrace.bufdump | 列出所有日志记录缓冲区以及名称,IddCx 是我们的名称,来自 logman.exe 命令行 |
!wmitrace.logdump LogBufferName | 解码并显示指定日志记录缓冲区的内容,该缓冲区在下面的示例中为 IddCx |
最后一行提供了失败的原因。
0: kd> !wmitrace.logdump IddCx
(WmiTrace) LogDump for Logger Id 0x13
Found Buffers: 5 Messages: 537, sorting entries
[1]0EF8.0CF0::04/24/2020-09:43:36.894 [cx][IddCx]DriverEntry: Enter
[1]0EF8.0CF0::04/24/2020-09:43:36.897 [cx][IddCx]?IddCxLibraryInitialize@@YAJXZ: Enter
[1]0EF8.0CF0::04/24/2020-09:43:36.897 [cx][IddCx]?IddCxLibraryInitialize@@YAJXZ: Exit...[0]0EF8.1588::04/24/2020-09:43:36.936 [cx][IddCx]?QueryModes@IddMonitor@@AEAAXAEAV?$vector@UIDDCX_TARGET_MODE@@V?$allocator@UIDDCX_TARGET_MODE@@@std@@@std@@@Z: DDI: Return successfully from EvtIddCxMonitorQueryTargetModes DDI
[0]0EF8.1588::04/24/2020-09:43:36.936 [cx][IddCx]?StartWatchInternal@IddWatchdog@@AEAAXK@Z: IddWatchdog 0x000001642F5E77F0, still has pending watch not started by watchdog thread.
[0]0EF8.1588::04/24/2020-09:43:36.936 [cx][IddCx]?AddTargetModes@IddMonitor@@AEAAXAEAV?$vector@UTARGET_MONITOR_MODE@@V?$allocator@UTARGET_MONITOR_MODE@@@std@@@std@@@Z: IddMonitor 0x000001642F5EF720, queryTargetModes returned 23 modes.
[0]0EF8.1588::04/24/2020-09:43:55.341 [cx][IddCx] Throwing error (Status 0xc000000d(STATUS_INVALID_PARAMETER)) from function Validate in onecoreuap\windows\core\dxkernel\indirectdisplays\classext\cx\ddivalidation.cpp:412, Msg DISPLAYCONFIG_VIDEO_SIGNAL_INFO.AdditionalSignalInfo.vSyncFreqDivider cannot be zero for target mode
Total of 537 Messages from 5 Buffers