स्मृति भ्रष्टाचार को समाप्त करना


23

सबसे पहले, मुझे लगता है कि यह एक पूर्ण प्रश्न के साथ एक सही प्रश्नोत्तर शैली सवाल नहीं है, लेकिन मैं इसे बेहतर बनाने के लिए किसी भी शब्द के बारे में नहीं सोच सकता। मुझे नहीं लगता कि इसका कोई पूर्ण समाधान है और यही एक कारण है कि मैं इसे स्टैक ओवरफ्लो के बजाय यहां पोस्ट कर रहा हूं।

पिछले महीने मैं सर्वर कोड (mmorpg) के एक काफी पुराने टुकड़े को फिर से लिखना शुरू कर रहा हूं, जो आधुनिक / विस्तारित / आधुनिक होने के लिए आसान है। मैंने नेटवर्क भाग के साथ शुरुआत की और मेरे लिए सामान को संभालने के लिए एक 3 पार्टी लाइब्रेरी (लीबवेंट) लागू किया। सभी री-फैक्टरिंग और कोड परिवर्तनों के साथ मैंने कहीं न कहीं स्मृति भ्रष्टाचार की शुरुआत की और मैं यह पता लगाने के लिए संघर्ष कर रहा हूं कि ऐसा कहां होता है।

मैं अपने देव / परीक्षण वातावरण पर इसे मज़बूती से पुन: पेश नहीं कर सकता, यहां तक ​​कि जब कुछ लोड को अनुकरण करने के लिए आदिम बॉट्स को लागू करने से मुझे कोई भी दुर्घटना नहीं होती है (मैंने एक कामचलाऊ मुद्दा तय किया जो कुछ सामान का कारण बनता है)

मैंने अब तक कोशिश की है:

इससे बाहर नरक को स्वीकार करते हुए - कोई भी अमान्य नहीं लिखता जब तक कि दुर्घटनाग्रस्त न हो जाए (जो उत्पादन में 1+ दिन ले सकता है .. या सिर्फ एक घंटा) जो वास्तव में मुझे चकित कर रहा है, निश्चित रूप से कुछ बिंदु पर यह अमान्य मेमोरी तक पहुंच जाएगा और इसके द्वारा सामान को अधिलेखित नहीं करेगा मोका? (क्या पता सीमा "फैलाने" का कोई तरीका है?)

कोड-विश्लेषण उपकरण, अर्थात् आवरण और कैपचेक। हालांकि उन्होंने कुछ ओर इशारा किया था .. कोड में कुछ नस्टनेस और एज के मामले गंभीर नहीं थे।

जब तक यह gdb (undodb के माध्यम से) के साथ क्रैश नहीं हो जाता है तब तक प्रक्रिया को रिकॉर्ड करना और फिर पीछे की ओर मेरा काम करना। यह / लगता है / जैसे यह संभव होना चाहिए, लेकिन मैं या तो ऑटो-पूर्ण सुविधा का उपयोग करके क्रैशिंग जीडीबी को समाप्त करता हूं या मैं कुछ आंतरिक परिवाद संरचना में समाप्त होता हूं जहां मैं खो जाता हूं क्योंकि बहुत अधिक संभावित शाखाएं हैं (एक भ्रष्टाचार एक और कारण बनता है) पर)। मुझे लगता है कि यह अच्छा होगा यदि मैं देख सकता हूं कि एक सूचक मूल रूप से क्या है / जहां इसे आवंटित किया गया था, जो कि अधिकांश शाखाओं-मुद्दों को समाप्त कर देगा। हालांकि, मैं undodb के साथ वेलग्रिंड नहीं चला सकता, और मैं सामान्य gdb रिकॉर्ड असामान्य रूप से धीमा है (यदि वह भी वेलग्रिंड के संयोजन में काम करता है)।

को़ड समीक्षा! अपने आप से (पूरी तरह से) और कुछ दोस्तों ने मेरे कोड को देखा, हालांकि मुझे संदेह है कि यह पूरी तरह से पर्याप्त था। मैं शायद कुछ कोड की समीक्षा / मेरे साथ डिबगिंग करने के लिए एक देवता को नियुक्त करने के बारे में सोच रहा था, लेकिन मैं इसमें बहुत अधिक पैसा लगाने का जोखिम नहीं उठा सकता हूं और मुझे नहीं पता होगा कि किसी ऐसे व्यक्ति की तलाश कैसे की जाए जो थोड़ा काम करने के लिए तैयार हो। अगर वह इस मुद्दे या किसी को भी योग्य नहीं पाता है तो कोई पैसा नहीं।

मुझे यह भी ध्यान देना चाहिए: मुझे आमतौर पर लगातार अंतराल मिलते हैं। कुछ स्थान ऐसे हैं जहां दुर्घटना होती है, ज्यादातर सॉकेट क्लास से संबंधित होते हैं जो किसी तरह भ्रष्ट हो जाते हैं। क्या यह एक अमान्य सूचक है जो किसी सॉकेट या सॉकेट क्लास को स्वयं अधिलेखित नहीं किया जा रहा है (आंशिक रूप से?) अस्पष्ट के साथ इंगित करता है। हालांकि मुझे संदेह है कि यह सबसे अधिक दुर्घटनाग्रस्त है क्योंकि यह सबसे अधिक उपयोग किए जाने वाले भागों में से एक है, इसलिए यह पहली दूषित स्मृति है जिसका उपयोग किया जाता है।

इन सभी मुद्दों ने मुझे लगभग 2 महीने (चालू और बंद, एक शौक परियोजना के अधिक) में व्यस्त कर दिया है और वास्तव में मुझे उस बिंदु पर निराश कर रहा है जहां मैं क्रोधी IRL बन जाता हूं और बस देने के बारे में सोचता हूं। मैं सिर्फ इस बारे में नहीं सोच सकता कि मुझे इस मुद्दे को खोजने के लिए क्या करना चाहिए।

क्या कोई उपयोगी तकनीक है जो मुझे याद है? आप इससे कैसे निपटते हैं? (यह सामान्य नहीं हो सकता है क्योंकि इस बारे में ज्यादा जानकारी नहीं है .. या मैं वास्तव में अंधा हूं?)

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

मामले में कुछ चश्मा यह मायने रखता है:

Gcc 4.7 के माध्यम से c ++ (11) का उपयोग करना (डेबियन व्हीज़ी द्वारा दिया गया संस्करण)

कोडबेस 150k लाइनों के आसपास है

David.pfx पोस्ट के जवाब में संपादित करें: (धीमी प्रतिक्रिया के लिए खेद है)

क्या आप पैटर्न को देखने के लिए क्रैश का सावधानीपूर्वक रिकॉर्ड रख रहे हैं?

हां, मेरे पास अभी भी हाल ही में हुए क्रैश के डंप हैं

क्या कुछ जगहें वास्तव में समान हैं? किस तरह से?

खैर, सबसे हालिया संस्करण में (वे जब भी मैं कोड जोड़ / हटाकर संबंधित संरचनाएँ बदलता हूँ, तो यह बदल जाता है) यह हमेशा एक आइटम टाइमर विधि में पकड़ा जाएगा। मूल रूप से किसी आइटम का एक विशिष्ट समय होता है जिसके बाद वह समाप्त हो जाता है और यह ग्राहक को अद्यतन जानकारी भेजता है। अमान्य सॉकेट पॉइंटर में होगा (अभी भी मान्य है जहाँ तक मैं बता सकता हूँ) खिलाड़ी वर्ग, ज्यादातर उसी से संबंधित है। मैं भी सफाई के चरण में दुर्घटनाओं के भार का सामना कर रहा हूं, सामान्य बंद के बाद जहां यह सभी स्थिर वर्गों को नष्ट कर रहा है जो स्पष्ट रूप से नष्ट नहीं किया गया है ( __run_exit_handlersबैकट्रेस में)। ज्यादातर std::mapएक वर्ग से जुड़े होते हैं , यह अनुमान लगाते हुए कि यह पहली बात है जो हालांकि सामने आती है।

भ्रष्ट डेटा कैसा दिखता है? शून्य? Ascii? पैटर्न?

मुझे अभी तक कोई पैटर्न नहीं मिला है, मुझे कुछ यादृच्छिक लगता है। यह बताना मुश्किल है क्योंकि मुझे नहीं पता कि भ्रष्टाचार कहां शुरू हुआ।

क्या यह ढेर से संबंधित है?

यह पूरी तरह से हीप से संबंधित है (मैंने जीसीसी के स्टैक गार्ड को सक्षम किया और वह कुछ भी पकड़ नहीं पाया)।

क्या भ्रष्टाचार एक के बाद होता है free()?

आप उस एक पर थोड़ा विस्तार करने जा रहे हैं। क्या आपका मतलब है कि पहले से ही खाली पड़ी वस्तुओं के संकेत होने चाहिए? जब वस्तु नष्ट हो जाती है, तो मैं प्रत्येक संदर्भ को शून्य करने के लिए सेट कर रहा हूं, इसलिए जब तक कि मैं कहीं चूक न जाए, नहीं। हालांकि यह मान्य नहीं था, लेकिन इसे वैग्राइंड में दिखाना चाहिए।

क्या नेटवर्क ट्रैफ़िक (बफर साइज़, रिकवरी साइकल) के बारे में कुछ विशिष्ट है?

नेटवर्क ट्रैफ़िक में कच्चे डेटा होते हैं। तो चार सरणियों, (यू) intX_t या पैक (पैडिंग को हटाने के लिए) अधिक जटिल चीजों के लिए संरचना, प्रत्येक पैकेट में एक हेडर होता है जिसमें एक आईडी और पैकेट आकार होता है जो कि अपेक्षित आकार के विरुद्ध मान्य होता है। वे कुछ एमबी के आकार वाले सबसे बड़े (आंतरिक 'बूटअप' पैकेट, स्टार्टअप पर एक बार निकाल दिए गए) के आसपास 10-60bytes हैं।

बहुत सारे और उत्पादन जोर देता है। क्षति का प्रचार करने से पहले जल्दी और अनुमानित रूप से क्रैश करें।

मेरे पास एक बार std::mapभ्रष्टाचार से संबंधित एक दुर्घटना थी , प्रत्येक इकाई के पास "दृश्य" का एक नक्शा है, प्रत्येक इकाई जो इसे देख सकती है और इसके विपरीत है। मैंने सामने और बाद में एक 200byte बफर जोड़ा, इसे 0x33 से भरा और प्रत्येक एक्सेस से पहले इसे चेक किया। भ्रष्टाचार सिर्फ जादुई रूप से गायब हो गया, मुझे कुछ ऐसा करना चाहिए जिसके बारे में कुछ और भ्रष्ट हो।

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

यह काम करता है .. एक विस्तार के लिए।

हताशा में, क्या आप राज्य और ऑटो-पुनरारंभ को बचा सकते हैं? मैं उत्पादन सॉफ्टवेयर के कुछ टुकड़ों के बारे में सोच सकता हूं जो ऐसा करते हैं।

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

Concurrency: सूत्रण, दौड़ की स्थिति, आदि

"Async" क्वेरी करने के लिए एक mysql थ्रेड है, हालांकि यह सभी अछूता है और सभी लॉक के साथ फ़ंक्शन के माध्यम से केवल डेटाबेस वर्ग को जानकारी साझा करता है।

बीच में आता है

इसमें एक अवरोध टाइमर है जो इसे लॉक करने से रोकता है, बस गर्भपात करता है यदि यह 30 सेकंड के लिए एक चक्र पूरा नहीं करता है, तो यह कोड सुरक्षित होना चाहिए:

if (!tics) {
    abort();
} else
    tics = 0;

टिक्स वह है volatile int tics = 0;जो हर बार एक चक्र पूरा होने पर बढ़ाया जाता है। पुराना कोड भी।

घटनाओं / कॉलबैक / अपवाद: राज्य को भ्रष्ट करना या अप्रत्याशित रूप से ढेर करना

बहुत सारे कॉलबैक का उपयोग किया जा रहा है (async नेटवर्क I / O, टाइमर), लेकिन उन्हें कुछ भी बुरा नहीं करना चाहिए।

असामान्य डेटा: असामान्य इनपुट डेटा / समय / स्थिति

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

एक अतुल्यकालिक बाहरी प्रक्रिया पर निर्भरता।

विस्तृत करने के लिए परवाह? यह कुछ हद तक, ऊपर उल्लिखित कैश प्रक्रिया है। केवल एक चीज जिसकी मैं कल्पना कर सकता हूं, वह यह है कि मेरे सिर के ऊपर से यह जल्दी खत्म नहीं होगा और कचरा डेटा का उपयोग नहीं किया जाएगा, लेकिन ऐसा नहीं है क्योंकि यह नेटवर्क का भी उपयोग कर रहा है। एक ही पैकेट मॉडल।


7
अफसोस की बात है कि यह गैर-तुच्छ सी ++ ऐप में आम है। यदि आप स्रोत नियंत्रण का उपयोग कर रहे हैं, तो कोड में बदलाव के कारण विभिन्न परिवर्तनों का परीक्षण करने से समस्या में मदद मिल सकती है, लेकिन शायद इस मामले में संभव नहीं है।
तेलस्टीन

हाँ, यह वास्तव में मेरे मामले में संभव नहीं है। मैं मूल रूप से 2 महीने के लिए पूरी तरह से और पूरी तरह से टूटने के लिए काम करने से चला गया और फिर डिबगिंग चरण में जहां मेरे पास कुछ काम करने वाला कोड है। पुरानी प्रणाली वास्तव में मुझे सब कुछ तोड़ने के बिना मेरे नए थोड़े लचीले नेटवर्क कोड को लागू करने की अनुमति देती है।
रॉबिन

2
इस बिंदु पर आपको प्रत्येक भाग को अलग करने का प्रयास करना होगा। समाधान के प्रत्येक वर्ग / सबसेट को लें, इसके चारों ओर एक नकली बनाएं ताकि यह कार्य कर सके, और जीवित नरक का परीक्षण तब तक कर सके जब तक कि आप उस खंड को न पा लें जो विफल रहता है।
Ampt

जब तक आपके पास क्रैश नहीं होगा तब तक कोड के कुछ हिस्सों को टिप्पणी करके शुरू करें।
cpp81

1
Valgrind, Coverity और cppcheck के अलावा, आपको अपने परीक्षण शासन में Asan और UBsan जोड़ना चाहिए। यदि आपका कोड corss-platofrm है, तो Microsoft के एंटरप्राइज एनालिसिस ( /analyze) और Apple के मॉलोक और स्क्रिबल गार्ड को भी जोड़ें। आपको यथासंभव अधिक से अधिक मानकों का उपयोग करके यथासंभव संकलक का उपयोग करना चाहिए क्योंकि संकलक चेतावनी एक निदान है और वे समय के साथ बेहतर हो जाते हैं। कोई चांदी की गोली नहीं है, और एक आकार सभी फिट नहीं है। जितने अधिक उपकरण और कंपाइलर आप उपयोग करते हैं, उतना ही अधिक कवरेज पूरा होता है क्योंकि प्रत्येक उपकरण की ताकत और कमजोरियां होती हैं।

जवाबों:


21

यह एक चुनौतीपूर्ण समस्या है लेकिन मुझे संदेह है कि आपके द्वारा पहले से देखी गई दुर्घटनाओं में बहुत अधिक सुराग मिलेंगे।

  • क्या आप पैटर्न को देखने के लिए क्रैश का सावधानीपूर्वक रिकॉर्ड रख रहे हैं?
  • क्या कुछ जगहें वास्तव में समान हैं? किस तरह से?
  • भ्रष्ट डेटा कैसा दिखता है? शून्य? Ascii? पैटर्न?
  • क्या कोई मल्टी-थ्रेडिंग शामिल है? क्या यह एक दौड़ की स्थिति हो सकती है?
  • क्या यह ढेर से संबंधित है? क्या भ्रष्टाचार मुक्त () के बाद होता है?
  • क्या यह स्टैक-संबंधित है? क्या ढेर भ्रष्ट हो जाता है?
  • झूलने का संदर्भ एक संभावना है? एक डेटा मान जो रहस्यमय तरीके से बदल गया है?
  • क्या नेटवर्क ट्रैफ़िक (बफर साइज़, रिकवरी साइकल) के बारे में कुछ विशिष्ट है?

ऐसी ही स्थितियों में हमने जिन चीजों का इस्तेमाल किया है।

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

हताशा में, क्या आप राज्य और ऑटो-पुनरारंभ को बचा सकते हैं? मैं उत्पादन सॉफ्टवेयर के कुछ टुकड़ों के बारे में सोच सकता हूं जो ऐसा करते हैं।

यदि हम सब पर मदद कर सकते हैं तो विवरण जोड़ने के लिए स्वतंत्र महसूस करें।


क्या मैं इसे गंभीरता से अनिश्चित कीड़े के रूप में जोड़ सकता हूं जैसे कि यह सब आम नहीं है, और ऐसी बहुत सी चीजें नहीं हैं जो (आमतौर पर) उन्हें पैदा कर सकती हैं। उनमे शामिल है:

  • Concurrency: सूत्रण, दौड़ की स्थिति, आदि
  • रुकावट / घटनाओं / कॉलबैक / अपवाद: भ्रष्ट स्थिति या अप्रत्याशित रूप से ढेर
  • असामान्य डेटा: असुरक्षित इनपुट डेटा / समय / स्थिति
  • एक अतुल्यकालिक बाहरी प्रक्रिया पर निर्भरता।

ये कोड के कुछ भाग हैं जिन पर ध्यान देना चाहिए।


+1 सभी अच्छे सुझाव, विशेष रूप से अभिकथन, गार्ड और लॉगिंग।
andy256

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

5

मॉलॉक / मुक्त के डिबगिंग संस्करण का उपयोग करें। उन्हें लपेटें और यदि आवश्यक हो तो अपना खुद का लिखें। बहुत सारा मजा!

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

भ्रष्टाचार के सबसे खतरनाक स्रोतों में से एक को मुक्त करने के बाद एक ठग का उपयोग करना जारी है। मुक्त को एक ज्ञात पैटर्न (परंपरागत रूप से, 0xDEADBEEF) के साथ मुक्त मेमोरी को भरना चाहिए यदि आवंटित संरचनाओं में "मैजिक नंबर" तत्व शामिल है, और किसी संरचना का उपयोग करने से पहले उचित रूप से मैजिक नंबर के लिए चेक शामिल करना चाहिए।


1
Valgrind को दोहरे फ्रीज़ / फ्री होल्ड डेटा के उपयोग को पकड़ना चाहिए, हालाँकि इसे नहीं करना चाहिए?
रॉबिन

नए / हटाए जाने के लिए इस तरह के अधिभार को लिखने से मुझे कई स्मृति भ्रष्टाचार मुद्दों का पता लगाने में मदद मिली है। विशेष रूप से गार्ड बाइट्स जो डिलीट होने पर सत्यापित हो जाते हैं और एक प्रोग्राम को ट्रिगर ब्रेक प्वाइंट का कारण बनता है जो स्वचालित रूप से मुझे डिबगर में छोड़ देता है।
एमिली एल।

3

अपने प्रश्न में आप क्या कहते हैं, उसे समझने के लिए, आपको एक निश्चित उत्तर देना संभव नहीं है। हम जो सबसे अच्छा कर सकते हैं, वह है चीज़ों के सुझाव और औज़ार और तकनीक।

कुछ सुझाव भोले दिखाई देंगे, अन्य अधिक लागू हो सकते हैं, लेकिन उम्मीद है कि एक विचार आपको ट्रिगर कर सकता है। मुझे कहना होगा कि david.pfx द्वारा दिए गए उत्तर में ध्वनि सलाह और सुझाव हैं।

लक्षणों से

  • मेरे लिए यह एक बफर उग आया की तरह लगता है।

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

  • क्या यह संभव है कि आप किसी वैश्विक चर का उपयोग कर रहे हैं, या एक ही नाम के साथ एक वैश्विक और स्थानीय है, या किसी भी तरह एक खिलाड़ी का डेटा दूसरे के साथ हस्तक्षेप करता है?

कई बग के साथ, आप शायद एक अवैध धारणा बना रहे हैं। या संभवतः एक से अधिक। एकाधिक अंतःक्रियात्मक त्रुटियों का पता लगाना कठिन है।

  • क्या हर चर का वर्णन है? और क्या आप वैधता के दावे को परिभाषित कर सकते हैं?
    यदि वे नहीं जोड़ते हैं, तो कोड के माध्यम से स्कैन करके देखें कि प्रत्येक चर सही तरीके से उपयोग किया गया प्रतीत होता है। जहाँ भी यह समझ में आता है उस जोर को जोड़ें।

  • बहुत जोर डालने का सुझाव एक अच्छा है: उन्हें लगाने का पहला स्थान हर फ़ंक्शन प्रविष्टि बिंदु पर है। तर्कों और किसी भी प्रासंगिक वैश्विक स्थिति को मान्य करें।

  • मैं लंबे समय से चल रहे / असिंक्रोनस / रीयल-टाइम कोड डिबग करने के लिए बहुत सारे लॉगिंग का उपयोग करता हूं।
    फिर से, हर फंक्शन कॉल पर लॉग राइट डालें।
    यदि लॉग फ़ाइलें बहुत बड़ी हो जाती हैं, तो लॉगिंग फ़ंक्शंस फ़ाइलों को लपेट / स्विच कर सकते हैं / आदि
    यह सबसे उपयोगी है यदि लॉग संदेश फ़ंक्शन लॉन्च गहराई के साथ इंडेंट करता है।
    लॉग फ़ाइल दिखा सकती है कि बग कैसे फैलता है। उपयोगी जब कोड का एक टुकड़ा कुछ नहीं-काफी-सही करता है जो विलंबित कार्रवाई बम के रूप में कार्य करता है।

बहुत से लोगों के पास अपने घर में लॉगिंग कोड होता है। मेरे पास एक पुरानी सी मैक्रो लॉग सिस्टम कहीं है, और शायद एक सी ++ संस्करण ...


3

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

आप जो वर्णन करते हैं, उससे मेरा व्यक्तिगत अनुमान यह है कि आप एक संकेतक को कहीं न कहीं मुक्त स्मृति में रख सकते हैं और एक सूचक को मुक्त कर सकते हैं जो अब आपके पास नहीं है या इसे लिखना है। यदि आप उपरोक्त तकनीक से निगरानी करने के लिए एक आकार सीमा का अनुमान लगा सकते हैं, तो आपको लॉगिंग को काफी कम करना चाहिए। अन्यथा, एक बार जब आपको पता चलता है कि कौन सी मेमोरी दूषित हो गई है, तो आप मालॉक / फ्री पैटर्न का पता लगा सकते हैं, जिसके कारण लॉग से यह आसानी से निकल जाता है।

एक महत्वपूर्ण नोट यह है कि जैसा कि आप उल्लेख करते हैं, मेमोरी लेआउट को बदलना समस्या को छिपा सकता है। इस प्रकार यह बहुत महत्वपूर्ण है कि आपका लॉगिंग कोई आवंटन नहीं करता है (यदि आप कर सकते हैं!) या जितना संभव हो उतना कम। यदि यह स्मृति से संबंधित है तो यह प्रतिलिपि प्रस्तुत करने योग्यता में मदद करेगा। यह तब भी मदद करेगा जब यह मुद्दा जितना तेजी से संभव हो उतना ही तेजी से संबंधित हो।

यह भी महत्वपूर्ण है कि आप 3 पार्टी पुस्तकालयों से आवंटन को फंसा लें ताकि आप उन्हें ठीक से लॉग इन कर सकें। आप कभी नहीं जानते कि यह कहां से आ सकता है।

अंतिम विकल्प के रूप में, आप एक कस्टम आवंटनकर्ता भी बना सकते हैं जहाँ आप हर आवंटन के लिए कम से कम 2 पृष्ठ आवंटित करते हैं और जब आप मुक्त होते हैं तो उन्हें अनमैप कर देते हैं (आवंटन को पृष्ठ सीमा में संरेखित करते हैं, पहले एक पृष्ठ आवंटित करते हैं और इसे सुलभ या संरेखित नहीं करते हैं। एक पृष्ठ के अंत में आवंटित करें और एक पृष्ठ आवंटित करें और बाद में पहुंच योग्य नहीं है)। सुनिश्चित करें कि कम से कम कुछ समय के लिए नए आवंटन के लिए उन वर्चुअल मेमोरी एड्रेस का पुन: उपयोग न करें। इसका मतलब है कि आपको अपनी आभासी मेमोरी को स्वयं प्रबंधित करने की आवश्यकता होगी (इसे आरक्षित करें और इसका उपयोग करें जैसा आप चाहते हैं)। ध्यान दें कि यह आपके प्रदर्शन को नीचा दिखाएगा और वर्चुअल मेमोरी की महत्वपूर्ण मात्रा का उपयोग करके अंत में हो सकता है कि आप इसे कितने आवंटन पर निर्भर करते हैं। इसे कम करने के लिए यह मदद करेगा यदि आप 64 बिट में चल सकते हैं और / या आवंटन की सीमा को कम कर सकते हैं जो इसकी आवश्यकता है (आकार के आधार पर)। Valgrind बहुत पहले से ही ऐसा कर सकता है, लेकिन आपके लिए इस मुद्दे को पकड़ना बहुत धीमा हो सकता है। केवल कुछ आकारों या वस्तुओं के लिए ऐसा करना (यदि आप जानते हैं कि, आप केवल उन वस्तुओं के लिए विशेष आवंटन का उपयोग कर सकते हैं) यह सुनिश्चित करेगा कि प्रदर्शन न्यूनतम रूप से प्रभावित होता है।


0

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

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

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