高度な検索
Developer Connection
Member Login ログイン | ご入会 ADC連絡先

Technical Q&A QA1195
Retain Counts of io_object_t Objects in IOKit.framework


Q: ユーザ空間の I/O Kit コード内で io_object_t オブジェクトをリークしているように思います。関数 IOObjectGetRetainCount を使用してこれらのオブジェクトの保持カウントを取得しましたが、予想よりも大きい値が戻されるのです。これはなぜですか?

A: ここで関連する保持カウントは、実際には 2 つあります。1 つは、io_object_t によって表現される、基盤のカーネルオブジェクトの保持カウントです。関数 IOObjectGetRetainCount は、カーネルを呼び出すことによって、この保持カウントを戻します。

もう 1 つは、io_object_t 自身の保持カウントです。io_object_t は、ユーザ空間とカーネルとのやり取り使われる Mach ポートのラッパーであり、Mach ポートはそれぞれ専用の保持カウントを持っています。これは、io_object_t から派生した他の型、すなわち io_service_t、io_connect_t、io_iterator_t、io_registry_entry_tio_enumerator_t にも当てはまります (これらの型は、IOKit/IOTypes.h の中で定義されています)。

IOObjectRetainIOObjectRelease は、io_object_t の Mach ポート自身の保持カウントを対象に処理を行います。これは、Darwin の IOKitUser プロジェクトの中の IOKitLib.c を調べることで確認できます。

したがって、io_object_t の保持カウントを取得する正しい方法は、Mach 関数 mach_port_get_refs を、リスト 1 のように使用することです。

#include <IOKit/IOKitLib.h>
#include <mach/mach_port.h>

kern_return_t  kr;
unsigned int    result;
io_object_t theObject;
io_name_t className;

kr = IOObjectGetClass(theObject, className);
if (KERN_SUCCESS == kr)
{
    kern_return_t  kr2;
    kr2 = mach_port_get_refs(
        mach_task_self(),
        theObject,
        MACH_PORT_RIGHT_SEND,
        &result );
    printf(
        "ID: %#X, Class: %s, Retain Count: %d, Result=%#x\n",
        theObject, className, result, kr2);
}

リスト 1 io_object_t の保持カウントの取得


よく知られているリターンコード 0x10000003 (MACH_SEND_INVALID_DEST) が IOKit.framework 関数から戻された場合、これは、基盤のカーネルオブジェクトではなく、破棄された io_object_t を参照しています。I/O Kit のエラーコードの詳細については、テクニカル Q&A 1075 を参照してください。


[2002 年 9 月 4 日]