Xcode 4.2 डीबग स्टैक कॉल का प्रतीक नहीं है


140

मुझे iOS 5 सिम्युलेटर / डिवाइस में Xcode 4.2 डिबगिंग की समस्या है। निम्नलिखित कोड दुर्घटना की उम्मीद के अनुसार:

NSArray *arr=[NSArray array];
[arr objectAtIndex:100];

IOS 4 में, मुझे हेक्स संख्या का एक उपयोगी स्टैक ट्रेस मिलता है। लेकिन iOS 5 में, यह सिर्फ मुझे देता है:

*** First throw call stack:
(0x16b4052 0x1845d0a 0x16a0674 0x294c 0x6f89d6 0x6f98a6 0x708743 0x7091f8 0x7fcaa9 0x2257fa9 0x16881c5 0x15ed022 0x15eb90a 0x15eadb4 0x15eaccb 0x6f02a7 0x6faa93 0x2889 0x2805)

धन्यवाद।

जवाबों:


256

कुछ भी नहीं मैंने इसे ठीक करने की कोशिश की (दोनों संकलक, दोनों डिबगर, आदि की कोशिश की) IOS 5 अपडेट के लिए XCode को अपग्रेड करने के बाद, कोई भी स्टैक निशान काम नहीं कर रहा था।

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

void uncaughtExceptionHandler(NSException *exception) {
    NSLog(@"CRASH: %@", exception);
    NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
    // Internal error reporting
}

इसके बाद, अपने एप्लिकेशन प्रतिनिधि को अपवाद हैंडलर जोड़ें:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{   
    NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
    // Normal launch stuff
}

बस!

यदि यह काम नहीं करता है, तो केवल दो संभावित कारण हैं :

  1. कुछ आपके NSSetUncaughtExceptionHandlerकॉल को ओवरराइट कर रहा है (आपके पूरे ऐप के लिए केवल एक हैंडलर हो सकता है)। उदाहरण के लिए, कुछ तीसरे पक्ष के पुस्तकालयों ने अपने स्वयं के अनजाने अपवादहैंडलर को सेट किया। इसलिए, इसे अपने didFinishLaunchingWithOptionsफ़ंक्शन के अंत में स्थापित करने का प्रयास करें (या चुनिंदा 3 पार्टी पुस्तकालयों को अक्षम करने)। या बेहतर अभी तक, NSSetUncaughtExceptionHandlerजल्दी से यह देखने के लिए एक प्रतीकात्मक विराम बिंदु सेट करें कि कौन इसे कॉल कर रहा है। आप जो करना चाहते हैं वह एक और जोड़ने के बजाय अपने वर्तमान को संशोधित करना है।
  2. (उदाहरण के लिए, आप वास्तव में एक अपवाद का सामना कर रहे नहीं EXC_BAD_ACCESSहै नहीं ;, @Erik बी की टिप्पणी को ऋण नीचे एक अपवाद)

1
इसे सुनकर खुशी हुई :) मुझे लगता है कि क्रैश लॉग को किसी फ़ाइल में लिखना उपयोगी होगा और उपयोगकर्ता को इसे अगले लॉन्च पर (केवल रिलीज़ मोड में, डीबगिंग के तरीके से नहीं मिलने के लिए) सबमिट करने के लिए प्रेरित करना होगा। इससे मुझे बड़ी बग रिपोर्ट मिल सकती है ... और उपयोगकर्ताओं को पता है कि उनकी समस्या का समाधान किया जा रहा है :)
Zane Claes

2
यह काम करने के लिए प्रतीत नहीं होता है - uncaughtExceptionHandlerदिनचर्या कभी भी लागू नहीं होती है।
हॉट लिक्स

1
क्या आप कृपया इसका उपयोग करने के तरीके के बारे में अधिक विशिष्ट हो सकते हैं? यह मेरे लिए काम करने के लिए प्रतीत नहीं होता है।
दानुत प्रालि

1
बहुत दुख की बात है xCode हमारे लिए यह प्रदर्शित नहीं करता है।
लेखक आपतिरा

1
बहुत सराहना की! यह चौंकाने वाला है कि Apple इस तरह की अल्पविकसित कार्यक्षमता को IDE में लागू नहीं करता है।
devios1

110

एक अपवाद ब्रेकपॉइंट (ब्रेकपॉइंट नेविगेटर के नीचे + का उपयोग करके) जोड़ने का एक उपयोगी विकल्प है। यह किसी भी अपवाद पर टूट जाएगा (या आप स्थितियां निर्धारित कर सकते हैं)। मुझे नहीं पता कि यह विकल्प 4.2 में नया है या यदि मैंने केवल इसे देखा है तो यह लापता प्रतीकों की समस्या को हल करने की कोशिश कर रहा है।

एक बार जब आप इस ब्रेकपॉइंट को मारते हैं, तो आप कॉल स्टैक को नेविगेट करने के लिए डिबग नेविगेटर का उपयोग कर सकते हैं, चर की जांच कर सकते हैं, आदि।

यदि आप प्रतिलिपि / चिपकाने या पसंद के लिए उपयुक्त एक प्रतीकात्मक कॉल स्टैक चाहते हैं, तो वहां से gdb बैकट्रेस ठीक काम करेगा:

(gdb) bt
#0  0x01f84cf0 in objc_exception_throw ()
#1  0x019efced in -[NSObject doesNotRecognizeSelector:] ()

(आदि)


3
यह मेरे लिए अब तक पूरी तरह से काम करता है। डिबगर दुर्घटनाग्रस्त लाइन पर अब रुकता है, बैकट्रेस की कोई आवश्यकता नहीं है।
टिम

1
यह पूरी तरह से मेरे लिए भी काम करता है। बहुत बहुत धन्यवाद, मैं इस विराम बिंदु के बिना पागल हो रहा था ...
विलियम डेनिस

इसके लिए +1 काम किया। यह आपको अपवाद का कारण बताते हुए इतनी अच्छी त्रुटि संदेश नहीं देता है, लेकिन यह एक शुरुआत है ...
निकु सुरदु

आप मेरे हॉटड @ वॉयसओल्डडक हैं।
Maverick1st

यह मेरे लिए अपेक्षित व्यवहार को पुनर्स्थापित करता है। नोट: इसके अलावा नई परियोजनाओं पर इस ब्रेकप्वाइंट को फिर से जोड़ना याद रखें!
१:09

46

डीबगर पर एक नई सुविधा है। जब भी कोई अपवाद फेंका जाता है तो आप एक विराम बिंदु सेट कर सकते हैं और निष्पादन को वहीं रोक सकते हैं, जैसा कि 4.0 पर हुआ करता था।

"ब्रेकपॉइंट नेविगेटर" पर, एक "अपवाद ब्रेकपॉइंट" जोड़ें और बस विकल्प पॉपअप पर "पूर्ण" दबाएं।

बस इतना ही!

पुनश्च: कुछ मामलों में केवल वस्तुनिष्ठ-सी अपवादों को तोड़ना बेहतर होगा।


निश्चित रूप से यह मेरे लिए समाधान है।
ब्रैडगोनसर्फिंग

यह मेरे लिए मुद्दा था। एक सहकर्मी और मैं एक ही एक्सकोड परियोजना साझा करते हैं और मैंने उनसे पूछा कि क्या उन्हें समस्या हो रही है, और वह नहीं थे। अंतर यह था कि उनका प्रोजेक्ट ऑब्जेक्टिव-सी अपवाद (objc_exception_throw) पर टूट रहा था
horseshoe7

आपने बस एक अप्राप्य बग ढूंढने में मदद की। बहुत बहुत धन्यवाद। मैं इस तरह से कुछ के लिए हर जगह देख रहा था।
रजगंजो

1
यह एक आकर्षण की तरह काम करता है! ठीक यही मैं देख रहा था, यह अपवाद हैंडलर को जोड़ने से बेहतर है क्योंकि ब्रेकपॉइंट को जोड़ने से आप सही ले सकते हैं जहां अपवाद फेंक दिया गया था, अपवाद हैंडलर काम करता है, लेकिन सिर्फ आपको एक विचार देता है।
im8bit

21

यहां एक और समाधान है, जो पहले की तरह सुरुचिपूर्ण नहीं है, लेकिन यदि आपने अपवाद ब्रेकप्वाइंट या हैंडलर को नहीं जोड़ा है, तो यह केवल एक ही रास्ता हो सकता है।
जब ऐप क्रैश हो जाता है, और आपको अपना कच्चा पहला थ्रो कॉल स्टैक (हेक्स संख्या में) मिलता है, info line *hexतो Xcode कंसोल में टाइप करें (स्टार और 0xहेक्स स्पेसर को न भूलें ), उदाहरण के लिए:

(gdb) info line *0x2658
Line 15 of "path/to/file/main.m" starts at address 0x25f2 <main+50>
and ends at 0x267e <main+190>.

यदि आप lldb का उपयोग कर रहे हैं , तो आप टाइप कर सकते हैं image lookup -a hex(इस स्थिति में स्टार के बिना), और आपको समान आउटपुट मिलता है।

इस पद्धति के साथ, आप अपने फ़ंक्शन को फेंक स्टैक (ऊपर लगभग 5-7 सिस्टम अपवाद प्रचारक होंगे) से पार कर सकते हैं जो एक दुर्घटना का कारण बना, और सटीक फ़ाइल और कोड की लाइन निर्धारित करता है।

इसके अलावा, इसी तरह के प्रभाव के लिए आप टर्मिनल में एटोस उपयोगिता का उपयोग कर सकते हैं, बस टाइप करें:

atos -o path/to/AplicationBundle.app/Executable 0xAdress1 0xAdress2 0xAdress3 ...

और आपको प्रतीकात्मक स्टैक ट्रेस मिलता है (कम से कम फ़ंक्शंस के लिए आपके पास डीबग प्रतीक हैं)। यह विधि अधिक बेहतर है, क्योंकि आपके पास प्रत्येक info lineएड्रेस कॉल के लिए नहीं है , बस कंसोल आउटपुट से एड्रेसों को कॉपी करें और उन्हें टर्मिनल में पेस्ट करें।


9

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


6

यह एक सामान्य समस्या है, 4.2 में स्टैक के निशान न मिलना। बेहतर परिणाम प्राप्त करने के लिए आप LLDB और GDB के बीच स्वैपिंग का प्रयास कर सकते हैं।

यहां बग रिपोर्ट दर्ज करें।

http://developer.apple.com/bugreporter/

संपादित करें:

मेरा मानना ​​है कि यदि आप LLV GCC 4.2 पर वापस स्वैप करते हैं तो आप ऐसा नहीं देखेंगे। हालांकि आपको उन सुविधाओं को खोना पड़ सकता है जिनकी आपको आवश्यकता है।


हां मैंने कंपाइलरों को स्विच करने की कोशिश की, हालांकि यह मुद्दा बना हुआ है। लेकिन धन्यवाद वैसे भी :)
cisisakurek

उन्होंने डिबगर्स को स्विच करने का सुझाव दिया, न कि कंपाइलरों का।
bames53

1
FYI करें: इस उदाहरण में, यह संकलक या डीबगर के संस्करण से कोई लेना-देना नहीं है जिसका आप उपयोग कर रहे हैं। यह iOS से कंसोल आउटपुट में बदलाव है।
क्लार्कॉक्स 3

दिलचस्प है कि इसके अनुभव कितने भिन्न होते हैं - मुझे लगता है कि कुछ समस्याएं हैं। मैं अपवाद ब्रेकपॉइंट पर रुकने के लिए डिबगर प्राप्त करने में सक्षम नहीं था। GDB से LLDB पर स्विच करने से समस्या हल हो गई।
मैट

6

अपने मुख्य कार्य में इस कोड का उपयोग करें:

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    int retVal;
    @try {
        retVal = UIApplicationMain(argc, argv, nil, nil);
    }
    @catch (NSException *exception) {
        NSLog(@"CRASH: %@", exception);
        NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
    }
    @finally {
        [pool release];
    }
    return retVal;
}

यह स्टोरीबोर्ड के साथ काम नहीं करता है। 2012-06-04 20: 34: 52.211 समस्याएं [1944: 207] ऐप के प्रतिनिधि को विंडो प्रॉपर्टी को लागू करना होगा अगर वह मुख्य स्टोरीबोर्ड फ़ाइल का उपयोग करना चाहता है। 2012-06-04 20: 34: 52.213 समस्याएं [1944: 207] आवेदन लॉन्च के अंत में रूट व्यू कंट्रोलर होने की उम्मीद है
macasas

6

Xcode के डिबग कंसोल प्रॉम्प्ट प्रकार पर:

image lookup -a 0x1234

और यह आपको कुछ इस तरह दिखाएगा:

  Address: MyApp[0x00018eb0] (MyApp.__TEXT.__text + 91088)
  Summary: MyApp`-[MyViewController viewDidAppear:] + 192 at MyViewController.m:202

धन्यवाद, मैं वास्तव में इसके लिए देख रहा था। आश्चर्य की बात है कि कॉल स्टैक के रूप में पूरे "पहले थ्रो कॉल स्टैक" को प्रदर्शित करने के लिए कोई शॉर्टकट नहीं है, क्योंकि मुझे लगता है कि पायथन एलडीबी स्क्रिप्ट आसानी से लिखी जा सकती है।
इल्या

1

'थम्ब के लिए संकलन' को चालू करना (डिबग कॉन्फ़िगरेशन) मेरे लिए काम किया।

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