2012-02-08 11 views
6

मेरे पास मेरे कोड में एक अजीब बग है जो इसे गायब करने का प्रयास करते समय गायब हो जाता है।ब्रेकपॉइंट सेट होने पर श्रोडिंगर बग गायब हो रहा है

मेरी टाइमर व्यवधान में (हमेशा प्रणाली टिकर चल) मैं कुछ इस तरह है: अपने मुख्य पाश में

if (a && lot && of && conditions) 
{ 
    some_global_flag = 1;     // breakpoint 2 
} 

मैं

if (some_global_flag) 
{ 
    some_global_flag = 0; 
    do_something_very_important(); // breakpoint 1 
} 

है मुख्य पाश में यह स्थिति कभी नहीं जब कहा जाता है टाइमर में स्थितियां (मुझे लगता है) पूर्ण हैं। शर्तें बाहरी हैं (पोर्टपिन, एडीसी परिणाम, आदि)। सबसे पहले मैंने स्थिति 1 पर ब्रेकपॉइंट लगाया, और यह कभी ट्रिगर नहीं हुआ।

इसे जांचने के लिए, मैंने ब्रेकपॉइंट एनआर रखा। 2 some_global_flag = 1; पर लाइन, और इस मामले में कोड काम करता है: दोनों शर्तों को सत्य होने पर ब्रेकपॉइंट ट्रिगर किए जाते हैं।

अद्यतन 1:

if (a && lot && of && conditions) 
{ 
    some_global_flag = 1;     // breakpoint 2 
} 


if (some_global_flag) 
{ 
    #asm("NOP"); // breakpoint 3 
} 
:

कि क्या कुछ समय हालत जिम्मेदार है, और टाइमर में if डिबगिंग के बिना चल रहा है, तो दर्ज नहीं किया गया है अनुसंधान करने के लिए, मैं अपने टाइमर में निम्नलिखित जोड़ा

ध्वज कोड में कहीं और नहीं उपयोग किया जाता है। यह रैम में है, और रैम शुरुआत में शून्य से साफ़ हो गया है।

अब, जब सभी ब्रेकपॉइंट अक्षम होते हैं (या मुख्य में केवल ब्रेकपॉइंट 1 सक्षम होता है), कोड सही ढंग से काम नहीं करता है, फ़ंक्शन निष्पादित नहीं होता है। हालांकि, अगर मैं एनओपी पर केवल ब्रेकपॉइंट 3 सक्षम करता हूं, तो कोड काम करता है! ब्रेकपॉइंट ट्रिगर किया गया है, और जारी रखने के बाद, फ़ंक्शन निष्पादित किया जाता है।

टाइमर बाधा व्यवधान कारक था, इसकी शुरुआत में एक "एसईआई" के माध्यम से: अद्यतन 2 (यह दिखाई और सुनाई देती आउटपुट है, तो यह स्पष्ट है अगर यह चलता है)

। मैंने उस रेखा को हटा दिया, लेकिन व्यवहार किसी भी ध्यान देने योग्य तरीके से नहीं बदला गया है।

अद्यतन 3:

मैं किसी भी बाहरी मेमोरी का उपयोग नहीं कर रहा हूँ। जैसा कि मैं फ्लैश में सीमा के बहुत करीब हूं, मेरे पास अधिकतम संकलक में आकार अनुकूलन है।

क्या संकलक (कोडविजन) जिम्मेदार हो सकता है, या मैंने कुछ गलत किया है?

+0

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

+1

कुछ_global_flag कैसे परिभाषित किया गया है? क्या आप 'volatile int some_global_flag' का उपयोग कर रहे हैं? – DipSwitch

+0

क्या आप बाहरी मेमोरी का उपयोग कर रहे हैं? या सिर्फ आंतरिक एसआरएएम? आप वास्तव में किस चिप का उपयोग कर रहे हैं? – DipSwitch

उत्तर

3

यह अजीब लग सकता है लेकिन अंततः यह इनपुट लाइनों में से एक पर मजबूत ट्रांजिस्टर के कारण साबित हुआ (जो सिस्टम को शक्ति देता है लेकिन इसके एडीसी माप को भी एक शर्त के रूप में उपयोग किया जाता है)।

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

मैंने इसे इस प्रश्न में पोस्ट नहीं किया क्योंकि मैंने सिस्टम के इस हिस्से का परीक्षण किया और पूरी तरह से काम किया, इसलिए मैं आपको निश्चित रूप से फेंकना नहीं चाहता था।

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

अंत में समस्या को समय में समायोजन के साथ हल किया गया था।

संपादित करें: मुझे समस्या का स्थान खोजने में क्या मदद मिली थी कि मैंने "स्थायी राम" क्षेत्र में अपने सबसे महत्वपूर्ण चर के मूल्यों को लॉग किया और देख सकता था कि उनमें से कुछ दूषित हो गए हैं।

+2

यह वास्तव में इस तरह की समस्या का एक सामान्य कारण है - डिबगिंग किसी भी तरह से परेशान करने के लिए होता है, और यदि आपके पास ऐसी स्थिति है जो समय के मुद्दों के प्रति संवेदनशील है, तो डीबगिंग निश्चित रूप से इसे प्रभावित कर सकती है। _how_ में अक्सर अधिक अर्थपूर्ण जानकारी नहीं होती है, डीबगिंग इसे प्रभावित करती है (कुछ हद तक क्योंकि यह बताना मुश्किल है कि डिबगिंग समय को कैसे प्रभावित कर रहा है)। –

+2

मुझे लगता है कि इस जवाब में थोड़ा सा जोड़ना दिलचस्प होगा कि आप समस्या का निदान कैसे करते हैं, साथ ही साथ जो भी आपको मिला है। साथ ही, चूंकि आप जानते हैं कि यह सही उत्तर है, आपको इसे पूर्णता के लिए स्वीकार करना चाहिए। :) –

+0

अच्छा है कि आपने इसे हल किया है। इससे कुछ अच्छा आया: आपने अपने वैश्विक ध्वज में अस्थिर जोड़ा (यदि आपने इसे नहीं जोड़ा है, तो कृपया, यह वास्तव में वहां होना चाहिए)। – Gauthier

1

मैं यहां गलत हो सकता हूं लेकिन यदि आप प्रश्न में बोर्ड से संलग्न करने के लिए डीबगर का उपयोग कर रहे हैं और हार्डवेयर पर प्रोग्राम को डीबग करते हैं तो मुझे लगता है कि यह चलने पर मुझे लगता है कि यह माइक्रोकंट्रोलर के व्यवहार को बदल सकता है एक अनुलग्नक .... अन्य जो कि और ऊपर वर्णित अस्थिर कीवर्ड मेरे पास कोई सुराग नहीं है।

+0

मैंने व्यवहार में कोई बदलाव नहीं होने के साथ 'अस्थिर' के साथ भी कोशिश की। – vsz

+0

अजीब बात यह है कि डीबगर का उपयोग होने पर ** सही ** कार्यक्षमता प्राप्त की जाती है। – vsz

4

यह शायद एक विशिष्ट अनुकूलन/डिबगिंग बग है। सुनिश्चित करें कि some_global_flag को अस्थिर के रूप में चिह्नित किया गया है। यह एक int uint8 uint64 हो सकता है जो आपको पसंद है ...

volatile int some_global_flag 

इस तरह से आप क्या some_global_flag का मूल्य हो जाएगा पर किसी भी मान्यताओं बनाने के लिए नहीं संकलक बताओ। आपको ऐसा करना होगा क्योंकि कंपाइलर/ऑप्टिमाइज़र आपके इंटरप्ट रूटीन पर कोई कॉल नहीं देख सकता है, इसलिए यह मानता है कि कुछ_global_flag हमेशा 0 (प्रारंभिक स्थिति) होता है और कभी नहीं बदला जाता है।

क्षमा हिस्सा है जहाँ आप पहले से ही इसे करने की कोशिश पढ़ने में भूलना ...

आप AVR-जीसीसी के साथ कोड संकलन और अगर आप एक ही व्यवहार किया है देखने के लिए कोशिश कर सकते हैं ...

+0

मैंने अस्थिरता के साथ कोशिश की, जिसके परिणामस्वरूप व्यवहार में कोई बदलाव नहीं आया। – vsz

4

Debuggers/क्या कर सकते हैं प्रोसेसर रन और कोड निष्पादित करने के तरीके को बदलें ताकि यह आश्चर्यजनक न हो।

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

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

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

1

यह एक एआरएम प्रोसेसर मानते हुए लिखा गया है।

ब्रेकपॉइंट (रैम या रॉम बीकपॉइंट) बल प्रोसेसर का उपयोग ब्रेकपॉइंट पर रन मोड से डीबग मोड में स्विच करने के लिए प्रोसेसर (या तो मोड या मॉनिटर मोड को रोकने के लिए) और इसे डीबग गति में चलाने के लिए मजबूर करें या एक निरंतर हैंडलर चलाने के लिए मजबूर करें और इसलिए जेएजी आधारित डीबगिंग मूल रूप से घुसपैठ करने वाला डिबगिंग है।

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

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