在 KMDF 和 UMDF 2 驱动程序中使用即时跟踪记录器 (IFR)

从 Windows 10 开始,可以生成 KMDF 或 UMDF 驱动程序,以便它通过 Windows 软件跟踪预处理获取额外的驱动程序调试信息。 此功能称为 INflight Trace Recorder (IFR) ,从 KMDF 版本 1.15 和 UMDF 版本 2.15 开始可用。

飞行跟踪记录器是 WPP 软件跟踪的扩展。 与 WPP 跟踪不同,在飞行跟踪记录器没有附加的跟踪使用者的情况下继续工作。 框架将消息写入循环缓冲区,驱动程序还可以添加自己的消息。 每个驱动程序都有自己的日志,因此与驱动程序关联的多个设备共享单个日志。

如果在驱动程序二进制文件中启用 IFR,则在驱动程序的生命周期内,IFR 会始终存在并处于运行状态。 不需启动显式跟踪收集会话。

日志存储在不可分页的内存中,因此可以在系统崩溃后恢复日志。 此外,在微型转储文件中还包含 Inflight Trace Recorder 日志,除非责任驱动程序不确定或崩溃是主机超时。

如何启用机上跟踪记录器并从驱动程序发送消息

  1. 在 Microsoft Visual Studio 中,执行以下步骤:

    • 打开驱动程序项目的“属性页”。 在“解决方案资源管理器”中右键单击驱动程序项目,并选择“属性” 。 在驱动程序的“属性页”中,选择“ 配置属性”,然后选择 “Wpp 跟踪”。 在“ 常规 ”菜单上,将 “运行 WPP 跟踪 ”设置为 “是”。

    • 导航到 “属性”->Wpp Tracing-Function> 和“宏选项” ,然后选择 “启用 WPP 记录器”。

    • 在同一菜单上,将 “扫描配置数据 ”设置为包含跟踪信息的文件,例如 Trace.h。

  2. 在每个调用 WPP 宏的源文件中,添加 一个 #include 指令,用于标识 TMH) 文件的跟踪消息头 (。 文件名的格式必须为 <driver-source-file-name.tmh。>

    例如,如果驱动程序包含两个名为 MyDriver1.c 和 MyDriver2.c源文件,则 MyDriver1.c 必须包含:

    #include“MyDriver1.tmh”

    MyDriver2.c 必须包含:

    #include“MyDriver2.tmh”

    在 Visual Studio 中生成驱动程序时,WPP 预处理器将生成 。tmh 文件。

  3. 在头文件中定义 WPP_CONTROL_GUIDS 宏。 此宏为驱动程序的跟踪消息定义 GUID 和跟踪 标志

    Osrusbfx2 驱动程序示例在 Trace.h 头文件中定义了一个控件 GUID 和七个跟踪标志,如以下示例所示:

    #define WPP_CONTROL_GUIDS \
    WPP_DEFINE_CONTROL_GUID(OsrUsbFxTraceGuid, \
      (d23a0c5a,d307,4f0e,ae8e,E2A355AD5DAB), \
      WPP_DEFINE_BIT(DBG_INIT)          /* bit  0 = 0x00000001 */ \
      WPP_DEFINE_BIT(DBG_PNP)           /* bit  1 = 0x00000002 */ \
      WPP_DEFINE_BIT(DBG_POWER)         /* bit  2 = 0x00000004 */ \
      WPP_DEFINE_BIT(DBG_WMI)           /* bit  3 = 0x00000008 */ \
      WPP_DEFINE_BIT(DBG_CREATE_CLOSE)  /* bit  4 = 0x00000010 */ \
      WPP_DEFINE_BIT(DBG_IOCTL)         /* bit  5 = 0x00000020 */ \
      WPP_DEFINE_BIT(DBG_WRITE)         /* bit  6 = 0x00000040 */ \
      WPP_DEFINE_BIT(DBG_READ)          /* bit  7 = 0x00000080 */ \
    )
    

    在本示例中:

    • OsrUsbFxTraceGuid 是 {d23a0c5a-d307-4f0e-ae8e-E2A355AD5DAB} GUID 的友好名称。
    • 跟踪标志用于区分在驱动程序处理不同类型的 I/O 请求时生成的跟踪消息。
  4. 驱动程序 (KMDF 和 UMDF 2) 必须使用驱动程序对象和注册表路径(通常来自 DriverEntry调用 Kernel-Mode 驱动程序的WPP_INIT_TRACING

    WPP_INIT_TRACING( DriverObject, RegistryPath );
    

    若要停用跟踪,KMDF 和 UMDF 2 驱动程序从 EvtCleanupCallbackEvtDriverUnload 调用 Kernel-Mode 驱动程序的WPP_CLEANUP

    WPP_CLEANUP( WdfDriverWdmGetDriverObject( Driver ));
    

    WPP_CLEANUP 宏采用 PDRIVER_OBJECT 类型的参数,因此,如果驱动程序的 DriverEntry 失败,可以跳过调用 WdfDriverWdmGetDriverObject,而是使用指向 WDM 驱动程序对象的指针调用 WPP_CLEANUP

    由于 UMDF 驱动程序使用这些宏的内核模式签名来初始化和清理跟踪,因此 KMDF 和 UMDF 的调用看起来完全相同。

  5. 在驱动程序中使用 DoTraceMessage 宏或 宏的自定义版本 来创建跟踪消息。

    以下示例演示 Osrusbfx2 驱动程序在专用于处理读取请求的代码的一部分如何使用其 TraceEvents 函数:

    if (Length > TEST_BOARD_TRANSFER_BUFFER_SIZE) {
        TraceEvents(TRACE_LEVEL_ERROR,
                    DBG_READ,
                    "Transfer exceeds %d\n",
                    TEST_BOARD_TRANSFER_BUFFER_SIZE);
    
        status = STATUS_INVALID_PARAMETER;
    }
    

    如果跟踪控制器启用TRACE_LEVEL_ERROR级别和DBG_READ跟踪标志,则对 TraceEvents 的调用将生成跟踪消息。 该消息包含驱动程序定义的常 量TEST_BOARD_TRANSFER_BUFFER_SIZE的值。

  6. 若要更改驱动程序日志使用的循环缓冲区的大小,请修改以下注册表位置中的 LogPages 注册表值:

    对于 UMDF:

    SOFTWARE\Microsoft\Windows NT\CurrentVersion\WUDF\Services\<YourDriver>\Parameters\Wdf

    对于 KMDF:

    <HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\YourDriver>\Parameters\Wdf

    这是 REG_DWORD 类型的值,包含分配的日志缓冲区的大小(以页为单位)。 有效值介于 0x1 和 0x10 之间。

对于 KMDF 驱动程序

  1. 通过在调试器中键入 .load rcdrkd.dll ,加载 RCDRKD 命令。
  2. 使用 !wdfkd.wdfldr 扩展可显示有关当前动态绑定到 Windows 驱动程序框架 (WDF) 的驱动程序的信息。
  3. 使用 !rcdrkd.rcdrlogdump!rcdrkd.rcdrcrashdump 查看驱动程序提供的消息。
  4. 使用 !wdfkd.wdflogdump!wdfkd.wdfcrashdump 查看框架提供的消息。

UMDF 驱动程序的实时调试

  1. 使用 !wdfkd.wdfldr 扩展可显示有关当前动态绑定到 WDF 的驱动程序的信息。 查找用户模式驱动程序。 输入关联的主机进程。

  2. 键入 !wdfkd.wdflogdump<YourDriverName.dll><Flag> ,其中 <Flag> 为:

    • 0x1 - 合并的框架和驱动程序日志
    • 0x2 - 驱动程序日志
    • 0x3 – 框架日志

    如果没有指定驱动程序的驱动程序日志,则扩展仅显示框架日志。

在 UMDF 驱动程序崩溃后查看机内跟踪记录器日志

  1. 在 WinDbg 中,选择“ 文件打开>故障转储”,并指定要调试的小型转储文件。

  2. 键入 !wdfkd.wdfcrashdump <YourDriverName.dll><驱动程序主机><选项>的进程 ID,其中 <Option> 为:

    • 0x1 - 合并的框架和驱动程序日志
    • 0x2 - 驱动程序日志
    • 0x3 – 框架日志

    如果未指定驱动程序, !wdfcrashdump 将显示所有驱动程序的信息。 如果未指定主机进程,并且只有一个,则扩展将使用单个主机进程。 如果未指定主机进程并且有多个,则扩展会列出活动主机进程。

    如果存储在小型转储中的日志信息与输入的名称不匹配,则小型转储不包含驱动程序的日志。

如果未连接调试器,仍可访问驱动程序和框架日志。 若要了解具体方法,请观看视频:在没有调试程序的情况下访问驱动程序 IFR 日志

有关向驱动程序添加跟踪消息的详细信息,请参阅 将 WPP 宏添加到驱动程序

如何启用对 UMDF 驱动程序的调试

RCDRKD 扩展

使用框架的事件记录器

在 UMDF 驱动程序中使用 WPP 软件跟踪