Xcode / LLDB: एक अपवाद के बारे में जानकारी कैसे प्राप्त करें जो अभी-अभी फेंका गया था?


83

ठीक है, तो कल्पना कीजिए कि मेरा ब्रेकपाइंट objc_exception_throwअभी शुरू हुआ है। मैं डिबगर प्रॉम्प्ट पर बैठा हूं, और मैं अपवाद ऑब्जेक्ट के बारे में कुछ और जानकारी प्राप्त करना चाहता हूं। मैं उसे कहाँ ढूँढू?


2
याद रखें, अपवाद अभी उठाया गया है, इसका विवरण अभी तक कंसोल पर मुद्रित नहीं किया गया है।
कारोई लोरेंटे जूल

इस सवाल की जाँच करें: stackoverflow.com/questions/711650
निकोलाई Fetissov

जवाबों:


162

अपवाद ऑब्जेक्ट को पहले तर्क के रूप में पास किया जाता है objc_exception_throw। LLDB प्रदान करता है $arg1.. $argnसही कॉलिंग कन्वेंशन में तर्कों को संदर्भित करने के लिए चर, अपवाद विवरण प्रिंट करना सरल बनाता है:

(lldb) po $arg1
(lldb) po [$arg1 name]
(lldb) po [$arg1 reason]

objc_exception_throwइन आदेशों को निष्पादित करने से पहले कॉल स्टैक में फ़्रेम का चयन करना सुनिश्चित करें । WWDC15 सत्र के वीडियो में "उन्नत डिबगिंग और एड्रेस सैनिटाइज़र" देखें, इसे मंच पर प्रदर्शित किया जाए।

आउटडेटेड जानकारी

यदि आप GDB पर हैं, तो पहले तर्क को संदर्भित करने वाला सिंटैक्स आपके द्वारा चलाए जा रहे आर्किटेक्चर के कॉलिंग सम्मेलनों पर निर्भर करता है। यदि आप वास्तविक iOS डिवाइस पर डिबगिंग कर रहे हैं, तो ऑब्जेक्ट का पॉइंटर रजिस्टर में है r0। इसे मुद्रित करने या इसे संदेश भेजने के लिए, निम्नलिखित सरल वाक्यविन्यास का उपयोग करें:

(gdb) po $r0
(gdb) po [$r0 name]
(gdb) po [$r0 reason]

IPhone सिम्युलेटर पर, सभी फ़ंक्शन तर्क स्टैक पर पारित किए जाते हैं, इसलिए वाक्यविन्यास काफी भयानक है। सबसे छोटी अभिव्यक्ति जो मैं बना सकता था, वह है *(id *)($ebp + 8)। चीजों को कम दर्दनाक बनाने के लिए, मैं एक सुविधा चर का उपयोग करने का सुझाव देता हूं:

(gdb) set $exception = *(id *)($ebp + 8)
(gdb) po $exception
(gdb) po [$exception name]
(gdb) po [$exception reason]

$exceptionजब भी ब्रेकपॉइंट पर कमांड की सूची जोड़कर ब्रेकपाइंट को ट्रिगर किया जाता है, तो आप स्वचालित रूप से सेट कर सकते हैं objc_exception_throw

(ध्यान दें कि मैंने जितने भी मामलों में परीक्षण किया था , ब्रेकप्वाइंट के हिट होने के समय अपवाद ऑब्जेक्ट भी मौजूद था eaxऔर edxपंजीकृत करता है। मुझे यकीन नहीं है कि मैं हमेशा मामला बना रहूंगा, हालांकि।)

नीचे टिप्पणी से जोड़ा गया:

Lldb में , इसके लिए स्टैक फ्रेम का चयन करें objc_exception_throwऔर फिर इस कमांड को दर्ज करें:

(lldb) po *(id *)($esp + 4)

6
कोई इसे lldb में कैसे करेगा? मुझे एक त्रुटि "त्रुटि: 'आईडी' के संदर्भ अस्पष्ट है"
ऑफेक्स

2
क्या आप इस जानकारी का स्रोत प्रदान कर सकते हैं? मैं इसके बारे में और अधिक पढ़ना चाहूंगा
जोओ नून्स

3
वर्तमान में प्रस्तावना से पहले मेरे लिए निम्नलिखित काम करता है जब पर breaing objc_exception_throw में LLDB : po *(id *)($esp + 4)
wbyoung

7
यह काम किया! हालाँकि, यह तब तक काम नहीं आया जब तक मैंने स्टैक फ्रेम 0 का चयन नहीं किया । ( objc_exception_throw)।
funroll

7
po $eax$r0डिवाइस पर कब तक लटकन के रूप में सिम्युलेटर में मेरे लिए काम करता है।
बन्दुक

10

नए सिमुलेटर पर (iOS 8, 64 बिट) एक्सकोड 6 इम अपवाद फ्रेम में उपयोग कर रहा है: objc_exception_throw

po $rax

32 बिट में:

po $eax

रक्स क्या है?

रैक्स 64 बिट्स रजिस्टर है जो पुराने ईएक्सएक्स की जगह लेता है

सभी रजिस्टरों को कैसे खोजें?

register read

स्रोत विकिपीडिया


हम्म ... में Xcode 6.1, मैं हो रही है: (lldb) पो $ Rax त्रुटि: अमल में लाना नहीं कर सका: निष्पादित में बाहर errored रजिस्टर Rax का मूल्य नहीं पढ़ सकते थे, कर सकते थे नहीं PrepareToExecuteJITExpression
bradheintz

@ ब्रैडीहंट सिम्युलेटर या डिवाइस? मैंने इसे 6.0.1 के साथ आजमाया
João Nunes

क्या आप उसके लिए अपने स्रोत का लिंक प्रदान कर सकते हैं? धन्यवाद!
क्रिस कॉनोवर

मैंने सिर्फ lldb में लिखा है: रजिस्टर रीड। फिर इस जानकारी के साथ हम जानते हैं कि अपवाद फ़्रेम में पहला रजिस्टर अपवाद संदेश रखता है।
जोओ न्यून्स

ठीक है, मुझे कुछ डॉक्स मिले: rax एक 64 बिट्स रजिस्टर है: 64-बिट लॉन्ग मोड में आप 64-बिट रजिस्टरों (जैसे कि eax के बजाय rax, eBay के बजाय rbx, आदि) का उपयोग कर सकते हैं
João Nunes

6

इस लेखन के समय, यह पोस्ट मेरे लिए शीर्ष Google हिट है: lldb प्रिंट अपवाद । इस प्रकार, मैं इस उत्तर को lldb और x86_64 के लिए जोड़ रहा हूं।

के po $eaxसाथ असफल का उपयोग कर अपवाद को खोजने के लिए मेरे प्रयास error: Couldn't materialize struct: Couldn't read eax (materialize)। पहले के उत्तरों से जुड़े दस्तावेजों में वर्णित अन्य प्रयास भी विफल रहे।

कुंजी यह थी कि मुझे पहले objc_exception_throwअपने मुख्य धागे में फ्रेम पर क्लिक करना था । lldb उस फ्रेम में शुरू नहीं होता है।

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


1

यदि आपके पास एक कैच स्टेटमेंट है, तो वहां एक विराम बिंदु रखें और आप उस बिंदु पर अपवाद ऑब्जेक्ट का निरीक्षण कर सकते हैं।

यदि आपके पास कैच स्टेटमेंट नहीं है, तो जारी रखें।

आपको अपने टर्मिनल में इस तरह एक संदेश मिलेगा:

अनकैप्ड अपवाद 'NSInvalidArgumentException' अपवाद के कारण ऐप समाप्त करना, कारण: ' * - [[__ NSPlaceholderDictionary initWithObjects: forKeys: count:]: ऑब्जेक्ट से ओएल ऑब्जेक्ट डालने का प्रयास [0]'

हालाँकि , आप शायद इसे जारी रखने के बिना निरीक्षण करने के लिए एक रास्ता तलाश रहे हैं क्योंकि आवेदन समाप्त होने पर आप अपना अच्छा स्टैक ट्रेस खो देंगे।

इसके लिए ऐसा लगता है कि Fnord का जवाब सबसे अच्छा है, लेकिन मैं इसे एलएलडीबी में काम करने में सक्षम नहीं था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.