2013-08-20 4 views
11

पर लटकता है हमारा ऐप अर्ध-यादृच्छिक रूप से psynch_mutexwait पर लटका लगता है। ऐसा लगता है कि यह एक पृष्ठभूमि प्रक्रिया से संबंधित है जो CoreData में संग्रहीत डेटा का एक समूह अद्यतन करता है - लेकिन मैं यह पता लगाने में पूरी तरह असमर्थ हूं कि डेडलॉक का कारण क्या है।ऐप __psynch_mutexwait

एलएलडीबी मुझे पूरा स्टैक ट्रेस है जो स्पष्ट रूप से अपूर्ण है, और थ्रेड 1 का अंतिम फ्रेम फर्जी है। उस विधि में मेरे पास कुछ पंक्तियां थीं, और इससे कभी हिट नहीं हुई थी।

क्या यह पता लगाने का कोई तरीका है कि किस लॉक की प्रतीक्षा की जा रही है? (या यहां तक ​​कि सही स्टैक निशान भी प्राप्त करें?) बेशक इसमें बहुत सारे कोड शामिल हैं, जो यादृच्छिक एनएसएलओजी कथन को बड़े पैमाने पर उपक्रम बनाता है।

(lldb) bt all 
* thread #1: tid = 0x2503, 0x39da20fc libsystem_kernel.dylib`__psynch_mutexwait + 24, stop reason = signal SIGSTOP 
    frame #0: 0x39da20fc libsystem_kernel.dylib`__psynch_mutexwait + 24 
    frame #1: 0x39ceb128 libsystem_c.dylib`pthread_mutex_lock + 392 
    frame #2: 0x00022068 OnDeck`-[AttendanceWorkoutsController buildTable](self=0x00000003, _cmd=0x00000000) + 508 at AttendanceWorkoutsController.m:100 

    thread #2: tid = 0x2803, 0x39d92648 libsystem_kernel.dylib`kevent64 + 24 
    frame #0: 0x39d92648 libsystem_kernel.dylib`kevent64 + 24 
    frame #1: 0x39ccb4f0 libdispatch.dylib`_dispatch_mgr_invoke + 796 

    thread #5: tid = 0x2b03, 0x39d91eb4 libsystem_kernel.dylib`mach_msg_trap + 20 
    frame #0: 0x39d91eb4 libsystem_kernel.dylib`mach_msg_trap + 20 
    frame #1: 0x39d9204c libsystem_kernel.dylib`mach_msg + 40 

    thread #6: tid = 0x242f, 0x39d91eb4 libsystem_kernel.dylib`mach_msg_trap + 20 
    frame #0: 0x39d91eb4 libsystem_kernel.dylib`mach_msg_trap + 20 
    frame #1: 0x39d9204c libsystem_kernel.dylib`mach_msg + 40 

    thread #7: tid = 0x2c03, 0x39da2594 libsystem_kernel.dylib`select$DARWIN_EXTSN + 20 
    frame #0: 0x39da2594 libsystem_kernel.dylib`select$DARWIN_EXTSN + 20 
    frame #1: 0x31bff1f6 CoreFoundation`__CFSocketManager + 678 

    thread #8: tid = 0x2d03, 0x39da2d98 libsystem_kernel.dylib`__workq_kernreturn + 8 
    frame #0: 0x39da2d98 libsystem_kernel.dylib`__workq_kernreturn + 8 
    frame #1: 0x39cf0cfa libsystem_c.dylib`_pthread_workq_return + 18 
(lldb) 

उत्तर

2

यह एक संबंधित है जब एक और संदर्भ (और एक अन्य धागे पर) संशोधित किया गया है, लेकिन अभी तक कायम नहीं में इकाई देखा गया है।

परिदृश्य:

A --> B

एक बग B के कारण परिवर्तन लंबित था, एक और संदर्भ में, एक और धागा पर। बग ने B को वापस सहेजने या इसे वापस रोल करने के बजाय आसपास लटका दिया। वर्तमान संदर्भ/थ्रेड में A को सहेजने का प्रयास करने से अन्य थ्रेड के लिए B पर लॉक जारी करने का इंतजार होगा।

शूट करने में केवल सफल तरीका सभी लंबित इकाइयों को सूचीबद्ध करना और अवरुद्ध धागे में से तुलना करना था। थोड़ी देर :(

मैं अभी भी कुछ है कि डेटाबेस पर सभी ताले और संस्थाओं की सूची के लिए देख रहा हूँ।

12

ले लिया होने कई लोगों कोड को देखो, और लंबे समय से जटिल कोड रास्तों के माध्यम से पता लगाने के द्वारा, हम पाया क्या अपराधी किया गया प्रतीत होता है करने के लिए है। एक विधि एक पृष्ठभूमि धागा में चल पाने के किया गया था और कुछ कोर डाटा वस्तुओं का उपयोग करने और मुख्य-धागे संदर्भ का उपयोग करते हुए।

ज़रूर बहुत मदद की है | अगर आईओएस उपयोगी स्टैक ट्रेस देना होगा।

+2

कोशिश कोर डेटा को सक्षम करने के बहु-क्रम दावे ट्रिगर। यह इन परिस्थितियों के लिए पेश किया गया था। – Mazyod

2

आमतौर पर ऐसा होता है जब कोई कोर तक पहुंचने का प्रयास करता है मुख्य थ्रेड संदर्भ या का उपयोग करके पृष्ठभूमि थ्रेड पर डेटा ऑब्जेक्ट्स एक ही समय में विभिन्न थ्रेड (पृष्ठभूमि या मुख्य) पर समान प्रबंधित ऑब्जेक्ट संदर्भ का उपयोग करते हुए। अधिक जानकारी के लिए Core Data concurrency rules देखें।

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

उदाहरण के लिए:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 

    // 
    // Prepare your background core data context 
    // 

    if (self.privateContext == nil) 
    { 
     self.privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
     [self.privateContext setParentContext: - main managed object context - ]; 
     [self.privateContext setUndoManager:nil]; // this context should not manage undo actions. 
    } 

    // 
    // Do any Core Data requests using this thread-save context 
    // 

    . 
    . 
    . 

});