2016-09-24 7 views
20

के साथ libC++ एसटीएल प्रिंटिंग/डिबगिंग मैं बहुत बुनियादी एसटीएल डीबग करने के लिए एक्सकोड 8 के भीतर एलएलडीबी का उपयोग करने की कोशिश कर रहा हूं। मैं इस तरह एक वेक्टर मुद्रित करने में सक्षम होता था:एक्सकोड/एलएलडीबी

p myvector[0] 

जो पहले वेक्टर इंडेक्स में था, देखने के लिए।

error: Couldn't lookup symbols: 
    __ZNSt3__16vectorI9my_classNS_9allocatorIS1_EEEixEm 

इसके बजाय, मैं इस टाइप करना होगा:: अब जब मैं ऐसा, मैं इस त्रुटि मिलती है

p myvector.__begin_[0] in order to get any output. 

मैं LLDB SVN भंडार से libcxx.py और unordered_multi.py लिपियों आयात करने की कोशिश की लेकिन ऐसा कुछ भी नहीं लगता है।

क्या कोई भी एलएलडीबी से libC++ के साथ कोई उपयोगी आउटपुट प्राप्त करने में सक्षम है ??

+0

क्या आपने डीबग जानकारी के साथ संकलित किया था? क्या आप स्वयं निहित प्रजनन प्रदान कर सकते हैं? – EricWF

+1

बेशक डीबग जानकारी सक्षम है। :) यहां एक गूंगा परियोजना है जो इस मुद्दे को पुन: उत्पन्न कर सकती है। बस std :: cout लाइन पर ब्रेकपॉइंट सेट करें और जब यह हिट हो जाए तो lldb कमांड "p myVector [0]" चलाएं। आपको एक त्रुटि मिलेगी। यदि आप "p myVector .__ start_ [0]" करते हैं तो इसके बजाय यह अच्छी तरह प्रिंट करेगा। https://www.dropbox.com/s/ntjywxabxj3e4mc/Crap.zip?dl=0 – cjserio

उत्तर

47

[]std::vector पर ऑपरेटर विधि है, इसलिए अपनी इच्छित अभिव्यक्ति को मुद्रित करने के लिए, lldb को [] विधि को कॉल करने में सक्षम होना होगा। यहां समस्या यह है कि ओएस एक्स पर एसटीएल यह सब कुछ रेखांकित करने के बारे में आक्रामक है, और उसी कार्य की लाइन प्रतियों से उत्पन्न अंतरिक्ष को बर्बाद नहीं कर रहा है। यह अनुकूलित कोड के लिए बहुत अच्छा है, लेकिन डीबगिंग के लिए इतना अच्छा नहीं है क्योंकि यह कॉल करने के लिए [] ऑपरेटर के साथ डीबगर छोड़ देता है। वह त्रुटि संदेश है जिसे आप देख रहे हैं।

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

(lldb) expr my_vec[0] 
error: Couldn't lookup symbols: 
    __ZNSt3__16vectorI3FooNS_9allocatorIS1_EEEixEm 

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

(lldb) expr my_vec 
(std::__1::vector<Foo, std::__1::allocator<Foo> >) $0 = size=2 { 
    [0] = (var1 = 10, var2 = 20) 
    [1] = (var1 = 10, var2 = 20) 
} 

वहाँ भी एक और आदेश "फ्रेम चर" जो स्थिर वस्तुओं का निरीक्षण कर सकते हैं, और हुक डेटा formatters में है। यह कार्यों कॉल कर सकते हैं नहीं और अन्य अधिक जटिल अभिव्यक्ति पार्सर कार्य करते हैं, लेकिन यह कैसे अलग-अलग तत्वों को पुनः प्राप्त करने एसटीएल डेटा formatters उपयोग करने के लिए पता है:

(lldb) frame var my_vec[1] 
(Foo) my_vec[1] = (var1 = 10, var2 = 20) 

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

: डिबगिंग के लिए इससे बचने के लिए

(lldb) frame var -L my_vec[1] 
0x0000000100100348: (Foo) my_vec[1] = { 
0x0000000100100348: var1 = 10 
0x000000010010034c: var2 = 20 
} 
(lldb) expr printf("%d\n", ((class Foo *) 0x0000000100100348)->var1) 
10 
(int) $3 = 3 

एक और तरीका है - - अगर आप सी ++ 11 का उपयोग कर रहे डालकर है

template class std::vector<MyClass> 

कहीं भी आपके कोड में। यह संकलक को इस विशेषज्ञता के लिए सभी टेम्पलेट कार्यों की आउट-ऑफ-लाइन प्रतियों को निकालने का निर्देश देगा। यह एक अच्छा सामान्य समाधान नहीं है, और आप केवल डीबग बिल्ड के लिए इसे करना चाहते हैं, लेकिन यह आपको इन कार्यों को कॉल करने और जटिल अभिव्यक्तियों में उनका उपयोग करने देता है।

+1

जिम का बहुत गहन उत्तर, मैं इसकी सराहना करता हूं! – cjserio

+0

इसे बुकमार्क करना। बहुत उपयोगी! –

+0

मैं लिनक्स (उबंटू 16.10) पर क्लैंग/एलएलडीबी 3.9 के साथ एक ही व्यवहार देख रहा हूं। लेकिन जीसीसी/जीडीबी को '(gdb) p my_vec [0] 'के साथ कोई परेशानी नहीं है। मुझे आश्चर्य है कि वे अलग-अलग क्या कर रहे हैं। –