调试失败的驱动程序卸载

如果存在对 DeviceObject 或 DriverObject 的引用泄漏, 驱动程序将不会卸载。 这是驱动程序卸载失败的常见原因。

除了 IoCreateDevice,还有几个函数引用 DriverObjectDeviceObject。 如果不遵循使用函数的准则,最终会泄漏引用。

下面是如何调试此问题的示例。 尽管本示例使用 DeviceObject ,但此方法适用于所有对象。

修复无法卸载的驱动程序

  1. 在驱动程序调用 IoCreateDevice 后立即放置断点。 获取 DeviceObject 地址。

  2. 使用此对象地址上的 !object 扩展查找对象标头:

    kd> !object 81a578c0 
    Object: 81a578c0  Type: (81bd0e70) Device
        ObjectHeader: 81a578a8
        HandleCount: 0  PointerCount: 3
        Directory Object: e1001208  Name: Serial0 
    

    ObjectHeader 中的第一个变量是指针计数引用计数

  3. 使用 ObjectHeader 的地址在指针计数上放置写入断点:

    kd> ba w4 81a578a8 "k;g" 
    
  4. 使用 g (Go) 。 调试器将生成日志。

  5. 查找不匹配的引用/取消引用对 -- 具体而言,是缺少的取消引用。 (请注意, ObReferenceObject 在 kernel.)