OSX Kext无法正确释放 [英] OSX Kext not being properly freed

查看:118
本文介绍了OSX Kext无法正确释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经基于

I have written a device driver kext for a hot-plug SCSI device, based somewhat on Wagerlabs code (using a driver-user client-application model) and everything works. The only remaining concern is that the driver appears not to be consistently freed, especially if the application crashes. For example, when I try to unload the kext, even with the device disconnected and the application closed, there are still outstanding instances of the driver and user client (with the driver generally outnumbering the user client).

我已经登录了像free()这样的驱动程序功能,当我关闭计算机时,可以看到它们正在执行,因此这些实例显然仍可以终止.即使主机应用程序崩溃,不正确地终止或通常不计划的事情,确保驱动程序实例终止并释放的正确"方法是什么?

I have logging in the driver functions like free(), and when I shut down the computer, I can see these being executed, so the instances can obviously still be terminated. What is the "right" way to ensure the driver instance is terminated and freed, even if the host application crashes, terminates improperly or things generally don't go to plan?

推荐答案

如果没有用户客户端应用程序在运行时有用户客户端类实例,那么您保留用户客户端实例的次数肯定会比您多释放它们.例如,您可能在主驱动程序类中保留了对客户端实例的保留引用.在用户客户端类的stop()方法中,确保从驱动程序中删除该客户端实例.

If you've got user client class instances when no user client app is running, then you're definitely retaining the user client instances more often than you're releasing them. For example, you might be keeping a retained reference to client instances in the main driver class. In your user client class's stop() method, make sure to remove that client instance from the driver.

需要注意的另一件事:确保从内置IOService方法的覆盖版本(例如stop()free()等)中调用超类实现.如果不这样做,通常会使IO Kit变得不一致状态.

Another thing to watch out for: make sure you call superclass implementations from your overridden versions of the built-in IOService methods such as stop(), free() etc. Not doing so will usually put the IO Kit into an inconsistent state.

最后,调试I/O Kit驱动程序中的保留泄漏的有用技术是通过使用日志记录版本覆盖方法来实际记录保留和释放:

Finally, a useful technique for debugging retain leaks in I/O Kit drivers, is to actually log the retains and releases by overriding the methods with logging versions:

void MyClass::taggedRetain(const void* tag) const
{
    OSReportWithBacktrace(
        "MyClass" CLASS_OBJECT_FORMAT_STRING "::taggedRetain(tag=%p)\n", CLASS_OBJECT_FORMAT(this), tag);
    IOService::taggedRetain(tag);
}
void MyClass::taggedRelease(const void * tag) const
{
    OSReportWithBacktrace(
        "MyClass" CLASS_OBJECT_FORMAT_STRING "::taggedRelease(tag=%p)\n", CLASS_OBJECT_FORMAT(this), tag);
    int count = getRetainCount();
    IOService::taggedRelease(tag);
    if (count == 1)
        printf(
            "MyClass::taggedRelease(tag=%p) final done\n", tag);
    else
        printf(
            "MyClass" CLASS_OBJECT_FORMAT_STRING "::taggedRelease(tag=%p) done\n", CLASS_OBJECT_FORMAT(this), tag);
}

此代码中的宏在标头中定义如下:

The macros in this code are defined in a header as follows:

#define CLASS_OBJECT_FORMAT_STRING "[%s@%p:%dx]"
#define CLASS_OBJECT_FORMAT(obj) myClassName(obj), obj, myRefCount(obj)

inline int myRefCount(const OSObject* obj)
{
    return obj ? obj->getRetainCount() : 0;
}

inline const char* myClassName(const OSObject* obj)
{
    if (!obj) return "(null)";
    return obj->getMetaClass()->getClassName();
}
#endif

我应该解释说taggedRetain()taggedRelease()retain()release()的实际基础实现-如果覆盖后者,您将看不到OSCollections的任何保留和发布,因为它们使用了标记版本(带有非null标签).

I should explain that taggedRetain() and taggedRelease() are the actual underlying implementation of retain() and release() - if you override the latter, you won't see any retains and releases coming from OSCollections, as they use the tagged versions (with a non-null tag).

不幸的是,由OSReportWithBacktrace()生成的回溯只是一堆十六进制指针,但是您可以使用gdb来查找它们.

The backtrace generated by OSReportWithBacktrace() is unfortunately just a bunch of hex pointers, but you can look those up using gdb.

无论如何,通过记录对象的保留和释放,您可以遍历所有保留,并确保它们在正确的位置与释放匹配.提防周期!

In any case, by logging retains and releases for your objects, you can go through all retains and make sure they are matched by a release in the right place. Watch out for cycles!

这篇关于OSX Kext无法正确释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆