2016-07-07 3 views
5

मुझे आशा है कि यह प्रश्न बहुत खुला नहीं है। मैं जंग के साथ एक स्मृति मुद्दा में भाग गया, जहां मुझे an "out of memory" from calling next on an Iterator trait object मिला। मुझे यकीन है कि इसे कैसे डिबग करना है। प्रिंट्स ने मुझे केवल उस बिंदु पर लाया है जहां विफलता होती है। मैं ltrace जैसे अन्य उपकरणों से बहुत परिचित नहीं हूं, इसलिए हालांकि मैं एक ट्रेस (231 एमआईबी, पीएफ) बना सकता हूं, मुझे वास्तव में पता नहीं था कि इसके साथ क्या करना है। क्या यह एक उपयोगी निशान है? क्या मैं gdb/lldb को पकड़ने के लिए बेहतर करूँगा? या वालग्रिंड?मैं जंग में एक स्मृति समस्या कैसे डीबग कर सकता हूं?

+0

वालग्रिंड हमेशा एक अच्छी शुरुआत है। अपने कोड को अनुकूलित करने का भी प्रयास करें। –

+2

@EliSadoff स्मृति समस्याओं को डीबग करने के साथ मेरी कोड सहायता को अनुकूलित करने में कैसे मदद करता है? – Apanatshka

उत्तर

3

सामान्य तौर पर मैं निम्नलिखित दृष्टिकोण करने की कोशिश करेंगे:

  1. बॉयलरप्लेट कमी: इतना है कि आप बहुत ज्यादा अतिरिक्त कोड के आसपास नहीं है OOM की समस्या को कम करने के लिए प्रयास करें। दूसरे शब्दों में: जितना जल्दी आपका प्रोग्राम दुर्घटनाग्रस्त हो जाता है, उतना ही बेहतर। कभी-कभी कोड के एक विशिष्ट टुकड़े को तोड़ना और जांच के लिए इसे अतिरिक्त बाइनरी में रखना भी संभव है।

  2. समस्या आकार में कमी: लोअर एक साधारण "बहुत अधिक स्मृति" करने के लिए OOM से इतना है कि आप वास्तव में कुछ हिस्सा कचरे कुछ लेकिन है कि यह एक OOM लिए नेतृत्व नहीं करता बता सकते हैं समस्या। यदि गीलेर को बताना मुश्किल है तो आप समस्या देखते हैं या नहीं, आप स्मृति सीमा को कम कर सकते हैं। लिनक्स पर, इस ulimit का उपयोग किया जा सकता है:

    ulimit -Sv 500000 # that's 500MB 
    ./path/to/exe --foo 
    
  3. सूचना सभा: यदि आप समस्या काफी छोटा है, तो आप जानकारी जो एक कम शोर स्तर है इकट्ठा करने के लिए तैयार हैं। ऐसे कई तरीके हैं जिन्हें आप आजमा सकते हैं। बस अपने प्रोग्राम को डीबग प्रतीकों के साथ संकलित करना याद रखें। ऑप्टिमाइज़ेशन को बंद करने के लिए यह एक लाभ भी हो सकता है क्योंकि इससे आमतौर पर सूचना हानि होती है। दोनों संकलन के दौरान --release ध्वज का उपयोग न करके संग्रहीत किया जा सकता है।

    • ढेर रूपरेखा: एक तरीका यह भी gperftools का उपयोग किया जाता है:

      LD_PRELOAD="/usr/lib/libtcmalloc.so" HEAPPROFILE=/tmp/profile ./path/to/exe --foo 
      pprof --gv ./path/to/exe /tmp/profile/profile.0100.heap 
      

      यह आपको एक ग्राफ जो प्रतीक है जो अपने कार्यक्रम के हिस्सों को स्मृति की जो मात्रा में खाते को दर्शाता है। अधिक जानकारी के लिए official docs देखें।

    • आरआर: कभी-कभी यह पता लगाना बहुत मुश्किल होता है कि वास्तव में क्या हो रहा है, खासकर जब आप प्रोफ़ाइल बनाते हैं। मान लिया जाये कि चरण 2 में एक अच्छा काम किया है, तो आप rr उपयोग कर सकते हैं:

      rr record ./path/to/exe --foo 
      rr replay 
      

      यह महाशक्तियों के साथ एक GDB अंडे जाएगा। सामान्य डीबग सत्र में अंतर यह है कि आप केवल continue नहीं बल्कि reverse-continue भी कर सकते हैं। असल में आपका प्रोग्राम एक रिकॉर्डिंग से निष्पादित किया जाता है जहां आप चाहते हैं कि आगे और आगे कूद सकते हैं। This wiki page आपको कुछ अतिरिक्त उदाहरण प्रदान करता है। एक बात यह इंगित करने के लिए है कि आरआर केवल जीडीबी के साथ काम करता प्रतीत होता है।

    • अच्छी पुरानी डीबगिंग: कभी-कभी आपको निशान और रिकॉर्डिंग मिलती है जो अभी भी बहुत बड़ी हैं। उस मामले में आप (ulimit चाल के साथ संयोजन में) बस GDB का उपयोग करें और जब तक कार्यक्रम दुर्घटनाओं इंतजार कर सकते हैं:

      gdb --args ./path/to/exe --foo 
      

      अब आप एक सामान्य डिबगिंग सत्र जहां जांच कर सकते हैं क्या कार्यक्रम की वर्तमान स्थिति था मिलना चाहिए । जीडीबी को भीड़ के साथ लॉन्च किया जा सकता है। उस दृष्टिकोण के साथ सामान्य समस्या यह है कि आप समय पर वापस नहीं जा सकते हैं और आप निष्पादन के साथ जारी नहीं रख सकते हैं। तो आप केवल सभी स्टेट फ्रेम और चर सहित वर्तमान स्थिति देखते हैं। यदि आप चाहें तो एलएलडीबी का उपयोग भी कर सकते हैं।

  4. (संभावित) + दोहराने को ठीक: आप एक गोंद क्या गलत आप अपने कोड को बदलने की कोशिश कर सकते हैं हो सकता है के बाद। फिर पुन: प्रयास करें। यदि यह अभी भी काम नहीं कर रहा है, तो चरण 3 पर वापस जाएं और पुनः प्रयास करें।

1

सामान्य रूप से, डीबग करने के लिए, आप या तो लॉग-आधारित दृष्टिकोण (या तो स्वयं को लॉग डालकर, या ltrace, ptrace, ... आपके लिए लॉग जेनरेट करने के लिए टूल का उपयोग कर सकते हैं) या आप कर सकते हैं एक डीबगर का प्रयोग करें।

ध्यान दें कि ltrace, ptrace या डीबगर-आधारित दृष्टिकोणों की आवश्यकता है कि आप समस्या को पुन: उत्पन्न कर सकें; मैं मैन्युअल लॉग का पक्ष लेता हूं क्योंकि मैं ऐसे उद्योग में काम करता हूं जहां बग रिपोर्ट आम तौर पर तत्काल प्रजनन की अनुमति देने के लिए बहुत ही कमजोर होती है (और इस प्रकार हम पुनरुत्पादक परिदृश्य बनाने के लिए लॉग का उपयोग करते हैं)।

जंग दोनों दृष्टिकोणों का समर्थन करता है, और मानक टूलसेट जो सी या सी ++ प्रोग्राम के लिए उपयोग करता है, उसके लिए अच्छा काम करता है।

मेरा व्यक्तिगत दृष्टिकोण कुछ है जहां समस्या उत्पन्न होती है, इसे तुरंत संकीर्ण करने के लिए लॉग इन किया जा रहा है, और अगर लॉगिंग अधिक जुर्माना निरीक्षण के लिए डीबगर को आग लगने के लिए अपर्याप्त है। इस मामले में मैं डीबगर के लिए सीधे जाने की सलाह दूंगा।

panic जेनरेट किया गया है, जिसका अर्थ है कि पैनिक हुक पर कॉल को तोड़कर, आप इस समय कॉल स्टैक और मेमोरी स्टेट दोनों को देख सकते हैं जहां चीजें घबराती हैं।

अपने प्रोग्राम को डीबगर के साथ लॉन्च करें, पैनिक हुक पर ब्रेक पॉइंट सेट करें, प्रोग्राम चलाएं, लाभ।

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