10

オーディオデバイスドライバー用のOSXカーネル拡張機能を作成しています(これはソフトウェアですが、ハードウェアデバイスをエミュレートします)。

開発中は、既存の古いバージョンを完全にアンインストールしてから、新しいバージョンを最初からビルドしてインストールすると便利です。ただし、これはシステムを再起動しないと不可能な場合があります。

プログラム自体が実行されておらず、ソースファイルがディレクトリから削除されています/System/Library/Extensions/

しかしkextstat、単一のインスタンスを明らかにします:

$ kextstat | grep 'com.foo.driver.bar'
219 0 0xfff123 0x5000 0x5000 com.foo.driver.bar (0.0.1) <102 5 4 3>

(...意味:)

Index Refs Address Size Wired Name (Version) <Linked Against>

したがって、私のドライバーインスタンスには0の参照がありますがkextunload、既存のインスタンスに不平を言って失敗することがあります。

$ sudo kextunload -b com.foo.driver.bar
(kernel) Can't unload kext com.foo.driver.bar; classes have instances:
(kernel)     Kext com.foo.driver.bar class FooBarDriver has 1 instance.
(kernel)     Kext com.foo.driver.bar class com_foo_driver_bar has 1 instance.
Failed to unload com.foo.driver.bar - (libkern/kext) kext is in use or retained (cannot unload).

これが発生した場合、(私が知っている)kextを「強制的にアンロード」する方法はありません。

実行中のOSカーネルによってメモリに保持されている参照のために、この単一のインスタンスがまだ存在していると推測するのは正しいですか?それは正しくないようです。なぜなら、それkextunloadは常に失敗するからです。では、なぜkextunloadすべてのドライバインスタンスを「完全に」アンロードするためにシステムの再起動が必要になることがあるのでしょうか。

4

1 に答える 1

11

kextunloadIOKit kextに対して実行すると、(他のkextがそれに依存していない場合)カーネルは、I /OKitレジストリにあるそのkext内のクラスのインスタンスを試行しますterminate()。次に、少し待って、そのkextのクラスのいずれかにまだインスタンスがあるかどうかを確認します。そうでない場合は、kextをアンロードします。インスタンスが残っている場合はkextunload失敗します(ただし、終了したインスタンスは終了したままです。これは、I / Oキットのマッチングがプロバイダーで再実行されないことを意味します)。

どういうわけか、あなたはまだライブインスタンスで終わっています。

  • 1つの可能性は、オブジェクトがを拒否していることterminate()です。これは、制御を放棄しないクライアントがある場合に発生する可能性があります。たとえば、ファイルシステムがマウントされているディスクのドライバーをアンロードできない場合などです。終了メッセージに応答しないユーザースペースクライアントは、別の例です。

  • それ以外の場合、インスタンスは終了しますが、解放されません。それらは2つの主要なドライバークラスのように見えるので、彼らの主張を放棄しないユーザークライアントがいない場合は、私は手足に出て、循環参照があるかもしれないことを提案します。そうでない場合は、がretain()一致しないsを探す必要がありますrelease()この回答では、これらを追跡する方法についていくつかのヒントを示します。

インスタンスが終了して登録が解除されると、コマンドラインツールの出力に表示されなくなるioregため、ここで2つのケースのどちらが当てはまるかを簡単に確認できます。

于 2012-11-24T17:11:21.290 に答える