Ne peut pas Décharger l'Extension du Noyau; les Classes Ont des Instances
Je suis en train d'écrire un OSX extension du noyau pour un pilote de périphérique audio (c'est un logiciel, mais émule un périphérique).
Au cours du développement, il serait commode de désinstaller complètement les versions, puis de construire et d'installer la nouvelle version à partir de zéro. Toutefois, cela semble parfois ne pas être possible sans un redémarrage du système.
Le programme lui-même n'est pas en cours d'exécution et la source des fichiers ont été supprimés de la /System/Library/Extensions/
dir.
Mais kextstat
révèle une instance unique:
$ kextstat | grep 'com.foo.driver.bar'
219 0 0xfff123 0x5000 0x5000 com.foo.driver.bar (0.0.1) <102 5 4 3>
(...sens:)
Index Refs Address Size Wired Name (Version) <Linked Against>
Donc, il y a 0 Refs à mon instance de pilote, mais kextunload
parfois échouer, de se plaindre des instances existantes:
$ 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).
Lorsque cela se produit, il n'y a aucun moyen de "forcer" décharger le kext (que je connais).
Suis-je droit à deviner que cette instance unique existe encore en raison d'une référence à la mémoire par le noyau de système d'exploitation? Cela ne semble pas juste, car alors kextunload
serait toujours voués à l'échec. Alors, pourquoi ne kextunload
que parfois nécessiter un redémarrage du système à "pleinement" décharger tous les pilote instances?
OriginalL'auteur pje | 2012-11-23
Vous devez vous connecter pour publier un commentaire.
De course
kextunload
pour un IOKit kext (si pas d'autres kexts en dépendent), le noyau pour tenter determinate()
toutes les instances de classes dans ce kext qui sont dans le I/O Kit de registre. Il faudra ensuite attendre un peu et vérifier si ce kext de classes ont encore des instances. Si non, il va décharger le kext. Si les instances restent,kextunload
échoue (les résilié en cas de séjour résilié, bien; je veux dire par là que les I/O kit de correspondance n'est pas ré-exécuter sur leurs fournisseurs).Donc, en quelque sorte, vous êtes toujours à la fin en direct instances.
Une possibilité est que vos objets sont en refusant de
terminate()
. Cela peut se produire si elles ont des clients qui ne veut pas lâcher le contrôle, par exemple, vous ne pouvez pas décharger le pilote pour un disque avec un système de fichiers monté sur le dessus. L'espace utilisateur, les clients qui ne répondent pas à la résiliation des messages sont un autre exemple.Sinon, les instances de résilier, mais ne sont pas libérés. Depuis, ils semblent être de deux de votre conducteur principal des classes, si vous n'avez pas n'importe quel utilisateur les clients qui ne renonceront pas à leur demande, je vais aller sur une branche et de suggérer que vous pourriez avoir une référence circulaire. Si ce n'est pas ça, vous aurez à chasser pour
retain()
s qui ne sont pas accompagnés par unrelease()
. Je donne quelques conseils sur la façon de suivre ces dans cette réponse.Si les instances de résilier et sont radiées, ils n'apparaîtront plus dans la sortie de la
ioreg
ligne de commande de l'outil, de sorte que c'est un moyen facile de vérifier lequel des deux cas s'applique ici.OriginalL'auteur pmdj