调试失败的驱动程序卸载
如果存在对 DeviceObject 或 DriverObject 的引用泄漏, 驱动程序将不会卸载。 这是驱动程序卸载失败的常见原因。
除了 IoCreateDevice,还有几个函数引用 DriverObject 和 DeviceObject。 如果不遵循使用函数的准则,最终会泄漏引用。
下面是如何调试此问题的示例。 尽管本示例使用 DeviceObject ,但此方法适用于所有对象。
修复无法卸载的驱动程序
在驱动程序调用 IoCreateDevice 后立即放置断点。 获取 DeviceObject 地址。
使用此对象地址上的 !object 扩展查找对象标头:
kd> !object 81a578c0 Object: 81a578c0 Type: (81bd0e70) Device ObjectHeader: 81a578a8 HandleCount: 0 PointerCount: 3 Directory Object: e1001208 Name: Serial0
ObjectHeader 中的第一个变量是指针计数或引用计数。
使用 ObjectHeader 的地址在指针计数上放置写入断点:
kd> ba w4 81a578a8 "k;g"
使用 g (Go) 。 调试器将生成日志。
查找不匹配的引用/取消引用对 -- 具体而言,是缺少的取消引用。 (请注意, ObReferenceObject 在 kernel.)