第十三篇:无征不信,不信民弗从--USB-IF官方驱动BSOD案例分析

USB-IF是USB的官方组织, 从它的官方网页:www.usb.org上可以看到, 它的主要工作内容与职责:

About USB Implementers Forum, Inc.

USB Implementers Forum, Inc. is a non-profit corporation founded by the group of companies that developed the Universal Serial Bus specification. The USB-IF was formed to provide a support organization and forum for the advancement and adoption of Universal Serial Bus technology. The Forum facilitates the development of high-quality compatible USB peripherals (devices), and promotes the benefits of USB and the quality of products that have passed compliance testing. Some of the many activities that the USB-IF supports include:

  • USB Compliance Workshops
  • USB compliance test development
  • www.usb.org Web site
  • USB pavilions at CES, IDF, and other events
  • Marketing programs and collateral materials, such as retail newsletters, retail salespeople training, store end-caps, etc.
  • USB Developer Conferences
  • and many more...

记得当初开发USB Dongle TV Tuner Capture时, 为了通过USB-IF的官方认证, 笔者第一次使用了USB-IF的测试软件(USB CV- command verifier), 参考了USB-IF官方提供的InterOp测试流程, 搭建Golden Tree. 配合硬件组的同事, 完成了电气特性测试, 几经挫折, 取得了该TV Capture的USB-IF官方认证.


自2011年加入到公司USB3.0 IP的项目开发以来, 与USB-IF打交道的次数越来越多, 与USB-IF工作人员的接触交流也随之递增.

2011年有幸和领导,同事去Portland参加了两次USB Storage Device认证, 一次是在PIL lab, 一次是Workshop, 对整个认证过程有了一个感性的认识与了解.

2013年再次参加USB-IF在Portland组织的Workshop, 这一次我们验证的对象是USB Audio Device, 作为USB Audio Device项目的全程参与者与主要负责人, 加上前两次对USB-IF测试过程的了解, 这一次对USB-IF的认证过程有了更加进一步深入的了解与感受.

随着Team中对USB3.0 xHCI项目的展开, 之后又有更多的同事参与到USB-IF官方认证的过程当中.


有一段时期, 我的同事在使用USB-IF提供的USB CV(Command verify)对xHCI host进行测试的过程中, 发生了多次的BSOD.

简单对CV作一介绍, 所谓的USB CV是由USB-IF开发与提供的对USB device或者host进步测试的一套软件包, 其中包括了UI, windows driver以及相应的一些配套的测试设备.

因此, 在使用USB CV的过程中, 测试包中所附带的驱动将会替代Windows OS上所带的USB Port, miniport, xHCI, hub等一系列的驱动栈(driver stack), 完全由USB-IF的这个驱动来接管. 

坦率地讲, 无论是Windows7之前的USB2.0 USB Port, eHCI miniport, O/UHCI USB hub驱动栈,还是Windows 8所加入的xHCI, SS USB hub驱动, 要开发这样几个bus driver难度是完完全全地大于几个function driver的, 所以, USB-IF在USB2.0基础上, 提供了支持USB3.0, 又能集成USB HUB功能的驱动程序, 是不简单的.

所以, 就在使用这个测试包的过程中, 产生了如下的一个BSOD.


!analyze -v 如下:

1: kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************


PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced.  This cannot be protected by try-except,
it must be protected by a Probe.  Typically the address is just plain bad or it
is pointing at freed memory.
Arguments:
Arg1: b818b3ec, memory referenced.
Arg2: 00000000, value 0 = read operation, 1 = write operation.
Arg3: 81336cd0, If non-zero, the instruction address which referenced the bad memory
address.
Arg4: 00000000, (reserved)


Debugging Details:
------------------




READ_ADDRESS:  b818b3ec 


FAULTING_IP: 
nt!READ_REGISTER_ULONG+4
81336cd0 8b02            mov     eax,dword ptr [edx]


MM_INTERNAL_CODE:  0


DEFAULT_BUCKET_ID:  WIN8_DRIVER_FAULT


BUGCHECK_STR:  AV


PROCESS_NAME:  CVExe.exe


CURRENT_IRQL:  0


ANALYSIS_VERSION: 6.3.9600.16384 (debuggers(dbg).130821-1623) x86fre


DEVICE_OBJECT: 8a9cf020


DRIVER_OBJECT: 8a9bb040


IMAGE_NAME:  XHCIdrv.sys


DEBUG_FLR_IMAGE_TIMESTAMP:  52018433


MODULE_NAME: XHCIdrv


FAULTING_MODULE: abbd9000 XHCIdrv


TRAP_FRAME:  87fa98dc -- (.trap 0xffffffff87fa98dc)
ErrCode = 00000000
eax=b818b3ec ebx=4cb750d8 ecx=001003ec edx=b818b3ec esi=ac23a190 edi=00000000
eip=81336cd0 esp=87fa9950 ebp=87fa9994 iopl=0         nv up ei ng nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010282
nt!READ_REGISTER_ULONG+0x4:
81336cd0 8b02            mov     eax,dword ptr [edx]  ds:0023:b818b3ec=????????
Resetting default scope


LAST_CONTROL_TRANSFER:  from 813e4d2a to 813355c4


STACK_TEXT:  
87fa97ac 813e4d2a 00000050 b818b3ec 00000000 nt!KeBugCheckEx
87fa97fc 814218bb 00000000 b818b3ec 87fa98dc nt! ?? ::FNODOBFM::`string'+0x316da
87fa98c4 813aecc4 00000000 b818b3ec 00000000 nt!MmAccessFault+0x42d
87fa98c4 81336cd0 00000000 b818b3ec 00000000 nt!KiTrap0E+0xdc
87fa994c abbda6ab b818b3ec b7d94ee8 b348af20 nt!READ_REGISTER_ULONG+0x4
WARNING: Stack unwind information not available. Following frames may be wrong.
87fa9994 8582bed3 4c4ed1f8 4cb750d8 0000000c XHCIdrv+0x16ab
87fa99d4 8582b9d4 4cb750d8 87fa9a18 b348af20 Wdf01000!FxIoQueue::DispatchRequestToDriver+0x3c0
87fa99f0 85831397 b3b12e00 00000000 b3b12e00 Wdf01000!FxIoQueue::DispatchEvents+0x4af
87fa9a10 8582b509 b3b12e00 b348af20 ac2390c4 Wdf01000!FxIoQueue::QueueRequest+0x204
87fa9a44 8582e52e b7b7af48 8a9cf020 b7b7af48 Wdf01000!FxPkgIo::Dispatch+0x3ba
87fa9a6c 8582e39f 8a9cf020 b7b7af48 8a9cf020 Wdf01000!FxDevice::Dispatch+0x155
87fa9a88 81701f9b 8a9cf020 b7b7af48 00000100 Wdf01000!FxDevice::DispatchWithLock+0x77
87fa9aa8 81290066 814d4f31 a71abd90 b7b7af48 nt!IovCallDriver+0x2e3
87fa9abc 814d4f31 b7b7b000 b7b7af48 0000000c nt!IofCallDriver+0x73
87fa9b10 814d499c 8a9cf020 00000000 00000001 nt!IopSynchronousServiceTail+0x121
87fa9bb0 814d45cf 8a9cf020 b7b7af48 00000000 nt!IopXxxControlFile+0x3b1
87fa9be4 813ab978 00000340 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
87fa9be4 77587174 00000340 00000000 00000000 nt!KiSystemServicePostCall
0332f2b0 00000000 00000000 00000000 00000000 0x77587174




STACK_COMMAND:  kb


FOLLOWUP_IP: 
XHCIdrv+16ab
abbda6ab 8b4ddc          mov     ecx,dword ptr [ebp-24h]


SYMBOL_STACK_INDEX:  5


SYMBOL_NAME:  XHCIdrv+16ab


FOLLOWUP_NAME:  MachineOwner


FAILURE_BUCKET_ID:  AV_VRF_XHCIdrv+16ab


BUCKET_ID:  AV_VRF_XHCIdrv+16ab


ANALYSIS_SOURCE:  KM


FAILURE_ID_HASH_STRING:  km:av_vrf_xhcidrv+16ab


FAILURE_ID_HASH:  {d1602a9f-50f3-31ed-26c1-8a2b11efaec6}


Followup: MachineOwner
---------


这是一个驱动程序访问系统无效虚拟内存,导致的BSOD.

访问的虚拟内存地址为"b818b3ec", 访问所使用的Windows API为READ_REGISTER_ULONG.

意即, 驱动在访问一个寄存器, 而该Register或者是根本不存在,或者是它映射了一块无效的虚拟地址.


由于该地址最高位置1, 所以,  意即它只对应了系统空间, 所以不用担心这个地址当时当刻到底到对应于哪一个用户进程.

我的第一步, 是使用!process 0 0命令, 将系统空间的DirBase得到.

1: kd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS 8499fcc0  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00185000  ObjectTable: 81e03000  HandleCount: <Data Not Accessible>
    Image: System


有了DirBase, 第二步, 就是通过!ptov得到一张完整的物理地址与虚拟地址的对应表, 

由于对应表太大, 我只列出问题点处:

物理地址 虚拟地址

f7cfd000 b8188000
f7cfe000 b8189000
f7cff000 b818a000
d7b48000 b818f000
d7b49000 b8190000


第三步, 使用!arbiter 2得到xHCI host controller的物理地址范围.

 00000000f7c00000 - 00000000f7cfffff       8a8bf030  (XHCIdrv)


通过以上的两组数据, 可以非常明显地得到出问题的点(不是原因)

USB-IF驱动需要访问的虚拟地址b818b3ec, 属于的范围是b818b000-b818bfff

一方面, 该虚拟地址并没有映射到任何的物理地址, 它正好是b818a000的紧接的下一页.

另外一个方面, 我们开发的xHCI的物理地址范围是00000000f7c00000 - 00000000f7cfffff,即便b818b3ec映射到了某一个物理地址, 它也已经超出了我们开发的xHCI的物理地址的范围.

到此为止, 我已经通过Windbg将xHCI host排除到BSOD问题之怀疑对象之外, 硬件工程师至少可以松一口气了.


事实上, 问题的原因还需要寻找, 如果Windbg使用能力强, 反汇编功底深, 则自己可以动手继续探索.

另外, 也可以找USB-IF提供该驱动的symbol pdb文件, 进一步, 快速地定位代码的问题处.


不过, USB-IF是官方组织, 既不愿意提供public symbol, 更不愿意提供private symbol, 估计他们的考虑角度是不愿意透露任何一丝的驱动实现的内容.

事后, 我们的工程师,又使用USB-IF提供的最新版USB CV进步测试, 期望新版本已经解决了这个问题, 但令人失望的是, 问题仍然存在.

之后, 我们与USB-IF官方联系, 它们的要求是使用USB CV的时候,将该驱动从Driver Verifer的名单中去掉, 我们的工程师一试,果然不再出类似的问题.

这个问题, 对于我这个Windbg BSOD分析只是工作当中副业的工程师来讲, 才算是告一段落. 后续只是兴趣,时间,与心情决定要不要继续挖掘?

不过, 对于求知角度来讲, 如果哪位大牛,能通过BSOD得到ROOT CAUSE, 还是令人期望的.


后记:

USB-IF虽然是官方组织, 但大家并不必一味轻信它们的所有东西, USB专业角度不是, Windows驱动也不是, 稍有Windows Driver开发经验的工程师都知道, 驱动程序要过WHQL认证,必须通过WHCK, 与Driver Verifer的测试, 既然USB-IF明知道它的驱动在打开Driver Verifier过程中, 会有导致BSOD的问题, 就在Release用户前将这个BUG fix掉, 否则就不应该发布出来.

可惜, USB-IF的态度是, 别人帮你找到了问题, 想进一步分析, 需要public symbol pdb的时候, 答案是没有.

这样的解决问题的态度, 也只能是以前市场竞争不强, 服务意识不强的时候的态度了!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值