2012-11-23 3 views
9

मैं एक ऑडियो डिवाइस ड्राइवर के लिए एक ओएसएक्स कर्नेल एक्सटेंशन लिख रहा हूं (यह सॉफ्टवेयर है, लेकिन हार्डवेयर डिवाइस का अनुकरण करता है)।कर्नेल एक्सटेंशन को अनलोड नहीं कर सकता; कक्षाओं के उदाहरण हैं

विकास के दौरान, मौजूदा पुराने संस्करणों को पूरी तरह से अनइंस्टॉल करना और फिर स्क्रैच से नया संस्करण बनाना और स्थापित करना सुविधाजनक होगा। हालांकि, यह कभी-कभी सिस्टम को पुनरारंभ किए बिना संभव नहीं लगता है।

प्रोग्राम स्वयं नहीं चल रहा है और स्रोत फ़ाइलों को /System/Library/Extensions/ dir से हटा दिया गया है।

$ 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 Refs, लेकिन kextunload कभी कभी असफल हो जायेगी, की शिकायत कर रहे हैं:

लेकिन kextstat एक उदाहरण से पता चलता है मौजूदा उदाहरण:

$ 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 को अनलोड करने के लिए "बल" करने का कोई तरीका नहीं है (जिसे मैं जानता हूं)।

क्या मैं यह अनुमान लगाने में सही हूं कि यह एकल उदाहरण अभी भी चल रहा ओएस कर्नेल द्वारा स्मृति में किए गए संदर्भ के कारण मौजूद है? यह सही प्रतीत नहीं होता है, क्योंकि kextunload हमेशा असफल रहता है। तो kextunload क्यों कभी-कभी सिस्टम को सभी ड्राइवर उदाहरणों को "पूरी तरह से" अनलोड करने के लिए पुनरारंभ करने की आवश्यकता होती है?

उत्तर

10

एक आईओकिट केक्स्ट के लिए kextunload चल रहा है (यदि कोई अन्य केक्सट इस पर निर्भर नहीं है) कर्नेल को terminate() को उस केक्स्ट में कक्षाओं के किसी भी उदाहरण को I/O किट रजिस्ट्री में करने का प्रयास करने का कारण बनता है। फिर यह थोड़ी देर इंतजार करेगा और जांच करेगा कि उस केक्स्ट के किसी भी वर्ग में अभी भी उदाहरण हैं या नहीं। यदि नहीं, तो यह kext को उतार देगा। यदि उदाहरण बने रहें, kextunload विफल रहता है (समाप्त होने वाले उदाहरण समाप्त हो जाते हैं, हालांकि; इसका मतलब है कि I/O किट मिलान उनके प्रदाताओं पर फिर से नहीं चल रहा है)।

तो किसी भी तरह, आप अभी भी लाइव उदाहरणों के साथ समाप्त हो रहे हैं।

  • एक संभावना यह है कि आपकी वस्तु terminate() से इनकार कर रही है। ऐसा तब हो सकता है जब उनके पास ऐसे ग्राहक हों जो नियंत्रण नहीं छोड़ेंगे, उदा। आप डिस्क पर एक आरोहित फ़ाइल सिस्टम के साथ डिस्क के लिए ड्राइवर को अनलोड नहीं कर सकते हैं। उपयोगकर्ता स्पेस क्लाइंट जो टर्मिनेशन संदेशों का जवाब नहीं देते हैं वे एक और उदाहरण हैं।

  • अन्यथा, उदाहरण समाप्त हो जाते हैं, लेकिन मुक्त नहीं होते हैं। चूंकि वे आपके दो मुख्य ड्राइवर वर्गों में से एक हैं, यदि आपके पास कोई उपयोगकर्ता क्लाइंट नहीं है जो अपना दावा नहीं छोड़ेंगे, तो मैं एक अंग पर बाहर जा रहा हूं और सुझाव देता हूं कि आपके पास एक परिपत्र संदर्भ हो सकता है । यदि ऐसा नहीं है, तो आपको केवल retain() एस के लिए शिकार करना होगा जो release() से मेल नहीं खाते हैं। मैं इन सुझावों को in this answer पर ट्रैक करने के बारे में कुछ सुझाव देता हूं।

उदाहरणों समाप्त कर देंगे और विपंजीकृत रहे हैं, तो वे अब ioreg कमांडलाइन उपकरण के उत्पादन में प्रदर्शित होगा, ताकि जाँच के लिए एक आसान तरीका है जो दो मामलों में से यहाँ लागू होता है।

+0

सहायक। धन्यवाद! – pje

संबंधित मुद्दे

 संबंधित मुद्दे