可以使用 Microsoft 网络监视器(也称为 Netmon)查看 USB ETW 事件跟踪。 Netmon 不会自动分析跟踪。 它需要 USB ETW 分析程序。 USB ETW 分析程序是用网络监视器分析程序语言 (NPL) 编写的文本文件,用于描述 USB ETW 事件跟踪的结构。 分析程序还定义 USB 特定的列和筛选器。 这些分析程序使 Netmon 成为分析 USB ETW 跟踪的最佳工具。
如何安装 Netmon 和 USB ETW 分析程序
从 Microsoft 下载中心安装 Netmon,然后从 Windows 驱动程序工具包 (WDK) 安装 USB ETW 分析程序。 Netmon 版本 3.3 及更高版本中支持 USB ETW 分析程序。
安装 Netmon 工具和 Netmon USB 分析程序
1.确定计算机是运行 32 位 Windows 还是 64 位 Windows:
a.打开“ 开始 ”菜单,右键单击“ 计算机 ”并查看 “属性”。
b.查看 “系统类型 ”字段。
如果系统类型为 32 位操作系统,则使用 x86 下载。 如果系统类型为 64 位操作系统,并且处理器为 Itanium,则使用 ia64 下载。 对于其他处理器类型,请使用 x64 或 AMD64 下载。
2.安装 Netmon:
a.导航到 Microsoft 下载中心的 “Windows 网络监视器 ”页。
b.选择“下载”按钮。
c.在下载弹出窗口中为系统选择适当的 .exe 文件 () ,然后选择“ 下载 ”按钮。
d.下载完成后,运行 .exe 文件以启动安装向导。
e.当系统要求你选择设置类型时,请选择“ 典型 ”。
3.从 Windows 驱动程序工具包安装 WDK (WDK) ) 。
4.允许执行 PowerShell 脚本:
a.在“开始”屏幕上,键入“powershell”,右键单击Windows PowerShell结果,然后选择“以管理员身份运行”。
b.在 PowerShell 窗口中,键入以下命令:
Set-ExecutionPolicy RemoteSigned -Force
c.关闭 PowerShell 窗口。
d.打开 PowerShell 窗口, (无需以 管理员 身份) 运行并运行以下命令。 如果已将工具包安装到其他位置,请调整路径:
cd "C:\Program Files (x86)\Windows Kits\10\Tools\10.0.22621.0\x86\Network Monitor Parsers\usb"
..\NplAutoProfile.ps1
e.重启 Netmon 以应用更改。
5.验证配置文件在 Netmon 中是否处于活动状态。
a.在“工具”菜单上,选择“选项”。
b.在“ 分析程序配置文件 ”选项卡上,确保“ 自动配置文件” (生成的) 设置为活动状态。 设置应与此图像类似。
c.选择“确定” 。
现在,Netmon 已配置为与 USB ETW 跟踪文件一起使用。
如何在 Netmon 中查看 USB ETW 跟踪
安装 Netmon 并将其配置为与 USB ETW 文件一起使用后,可以使用它检查跟踪文件。
若要在 Netmon 中查看跟踪文件,请在“开始”屏幕上键入“netmon”以打开 Netmon。 使用以下方法之一打开跟踪文件:
- 在“ 文件 ”菜单上,单击“ 打开”,单击“ 捕获”,然后选择 .etl 文件。
- 单击“ 打开捕获 ”按钮并选择 .etl 文件。
- 按 Ctrl+O 并选择 .etl 文件。
事件跟踪由单个事件组成,每个事件都指示驱动程序堆栈中发生的情况。 每个事件都符合驱动程序堆栈定义的多种类型之一。
观察事件是否在“ 帧摘要 ”窗格中列出。 上图显示了 USB 2.0 驱动程序堆栈的偶数。 请注意此窗格中的以下列:
- 时间偏移量:事件的时间戳,指定为与日志开始时间的偏移量。
- 协议名称:记录事件的驱动程序。 对于 USB 事件,驱动程序为 USB 集线器或 USB 端口。
- 说明:事件的描述性名称。
在“ 帧摘要 ”窗格中选择一个事件。 Netmon 在“ 帧详细信息 ”和“ 十六进制详细信息 ”窗格中显示事件的详细信息。 在“ 帧详细信息 ”窗格中,展开项目以检查事件的详细信息。
USB 3.0 驱动程序堆栈的 USB ETW 分析程序的新列
USB 2.0 驱动程序堆栈中的重要事件类型也在 USB 3.0 驱动程序堆栈中定义。 但是,这些类型之间存在细微的差异。 例如,请考虑 USB 控件传输完成事件类型 (Description : USBPort:Complete URB_FUNCTION_CONTROL_TRANSFER_EX with Data) :
对于 USB 2.0 驱动程序堆栈事件类型,“ 帧详细信息 ”窗格显示 idVendor (也称为 USB VID) 和 idProduct (也称为 USB PID) 。 此图像显示了连接到 USB 2.0 主机控制器的 USB 2.0 设备的事件跟踪。
对于 USB 3.0 驱动程序堆栈事件类型, “帧详细信息 ”窗格不包含 idVendor 或 idPid。 可通过向“ 帧摘要 ”窗格添加新列来获取该信息,如下图所示。
请注意以下新列:
- USB 设备说明
- USB Vid
- USB Pid
- USB 长度
- USB 请求持续时间
microsoft 网络监视器:
(USB 2.0 和 USB 3.0) 的所有 USB 事件跟踪现在都会在每个 URB 完成时显示有关请求的详细信息。 请注意 “USB 长度”下的值,例如“255 中的 41”。 这些值指示完成时每个 URB 的实际传输长度,以及客户端驱动程序) 指定的原始 TransferBufferLength (总请求长度的上下文。 此外,还可以在“ USB 请求持续时间 ”列下查看完成请求所花费的时间(以秒为单位)。
将筛选器添加到“显示筛选器”窗格
可以使用捕获筛选器来缩小特定方案的事件跟踪范围。 可以为 USB 2.0 和 USB 3.0 驱动程序堆栈中的事件跟踪编写新的筛选器:
USBIsError == 1 // Any error events from the USB drivers
USBIsDisconnect == 1 // Show when any device disconnected
可以筛选所有列。 若要创建筛选器,请右键单击单元格,然后选择“将”<列名>“添加到”显示筛选器”。 Netmon 基于其值和列名创建筛选器,并将其添加到 “显示筛选器 ”窗格下。
使用 ETW 事件调试 USB 设备问题
诊断设备枚举失败
可以使用与 USB 集线器枚举任务关联的 ETW 事件来确定大多数设备枚举失败的根本原因。
查看跟踪日志中与 USB 集线器枚举任务关联的事件
1.打开 Netmon 并找到枚举事件,例如“启动端口枚举”。 单击“ 帧摘要 ”窗格中的事件。
2.通过检查事件的“ 任务” 字段,确认此事件的任务是 USB 集线器枚举:
a.在“ 框架详细信息 ”窗格中,展开“ Net 事件”,展开 “标头”,再展开 “描述符”,然后找到 “任务” 字段。
b.确认“任务”域包含值 2 (USB 集线器枚举) 。
3.筛选事件以仅显示中心驱动程序中任务值为 2 的事件:
a.右键单击“ 任务” 域。
b.选择“ 添加所选值 以显示 筛选器”。
c.右键单击“帧摘要”窗格中的事件,然后选择“将”协议名称“添加到”显示筛选器”。
d.在 “显示筛选器 ”窗格中,将“OR”更改为“AND”。 以下示例显示了生成的筛选器:
NetEvent.Header.Descriptor.Task == 0x2 AND ProtocolName == "USBHub_MicrosoftWindowsUSBUSBHUB"
诊断设备启动故障
如果设备在中心驱动程序处理设备的启动 I/O 请求数据包 (IRP) 期间无法启动,则可以使用与 USB 设备启动任务关联的 ETW 事件来排查故障。 在 Netmon 中,找到设备启动事件,例如“USB 设备启动 IRP 调度”。 可以筛选事件,以仅显示中心驱动程序中的事件,其任务值为 21 (USB 设备启动) 。
分析设备插入计时
可以通过查看枚举事件的时间戳来确定在设备插入期间中心驱动程序中花费的时间。
枚举计时
中心驱动程序枚举设备所消耗的设备插入时间部分是以下两个事件之间经过的时间:
- 启动端口枚举
- 已完成端口的枚举
分析枚举任务
当 USB 集线器驱动程序枚举设备时,它将按以下顺序记录以下事件:
- 启动端口枚举
- 枚举 Debounce Completed
- 为枚举创建的 PDO
- 第一个枚举端口重置完成
- 枚举 - CreateDevice Complete
- 第二个枚举端口重置完成
- 枚举 - InitializeDevice Complete
- 枚举 - SetupDevice Complete
- 已完成端口的枚举
若要确定中心驱动程序用于每个枚举任务的时间,请计算上述事件之间经过的时间。 IoInvalidateDeviceRelations 和 IRP_MN_QUERY_DEVICE_RELATIONS 之间的运行时间
若要确定系统等待查询设备关系 IRP 时所使用的设备插入时间部分,请测量以下两个事件之间的已用时间:
- 已完成端口的枚举
- USB 中心查询设备关系 (总线关系) IRP 调度
完成IRP_MN_QUERY_DEVICE_RELATIONS到IRP_MN_START_DEVICE之间的运行时间
若要确定从向即插即用管理器报告新的物理设备对象 (PDO) 到收到启动 IRP 之间的设备插入时间部分,请测量以下两个事件之间的已用时间:
- USB 集线器查询设备关系 IRP 已完成
- 已调度 USB 设备启动 IRP
启动 IRP 计时
若要确定处理启动 IRP 的中心驱动程序所用的时间,请测量以下两个事件之间的已用时间:
- 已调度 USB 设备启动 IRP
- USB 设备启动 IRP 已完成
Software-Initiated 设备恢复计时
设备的功能驱动程序可以发送 D0 设备电源请求,使设备从挂起状态恢复。 若要确定设备从挂起恢复并准备好传输请求所需的时间,请测量以下两个事件之间的运行时间:
- USB 设备集 D0 设备电源 IRP 已调度
- USB 设备集 D0 设备电源 IRP 已完成
Hardware-Initiated 设备恢复计时
总线上的恢复信号会导致设备从挂起状态恢复。 若要确定设备恢复到已准备好传输请求的状态所需的时间,请测量以下两个事件之间的运行时间:
- 父中心未挂起:
USB 设备等待唤醒 IRP 已完成
USB 设备集 D0 设备电源 IRP 已完成
- 父中心暂停:
已启动 从选择性挂起恢复中心 (设备与主机控制器之间的任何中心的第一个事件)
USB 设备集 D0 设备电源 IRP 已完成。
中心从选择性暂停计时恢复
通过测量以下两个事件之间的运行时间,可以确定中心从选择性挂起恢复所需的时间:
- 从选择性挂起开始恢复中心
- 中心恢复已完成
注意:中心恢复计时取决于中心下方所有设备的恢复计时,并且可能取决于正在恢复的中心上方的部分或所有中心。