रनटाइम त्रुटि होने पर क्या होता है?


17

यदि किसी प्रोग्राम में रनटाइम त्रुटि होती है, तो क्या होता है? क्या कार्यक्रम का क्रियान्वयन बस रुक जाएगा? क्या कोई रास्ता है जिससे मुझे अर्डुइनो मिल जाए यह बताने के लिए कि त्रुटि क्या है?

जवाबों:


21

पहले, आइए देखें कि क्या गलत हो सकता है।

अनधिकृत स्थानीय चर

void setup() {
  int status;
  pinMode(13, OUTPUT);
  digitalWrite(13, status);
} 

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

वैश्विक और स्थिर चर के साथ चीजें थोड़ी भिन्न हैं:

वैश्विक और स्थिर चर को C मानक द्वारा 0 से आरंभ करने की गारंटी है।

स्रोत: AVR लिबक रेफरेंस मैनुअल - अक्सर पूछे जाने वाले प्रश्न - क्या मुझे अपने सभी चरों को इनिशियलाइज़ नहीं करना चाहिए?

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

स्मृति अतिप्रवाह

int array[10];
int v = array[100];
array[-100] = 10;

यहाँ पहली समस्या यह है कि आप नहीं जानते हैं कि v को क्या सौंपा जाएगा, लेकिन इससे भी बदतर यह है कि आपको पता नहीं है कि आपने असाइनमेंट के साथ स्थिति -100 में क्या गड़बड़ कर दी है array

एक अवैध निर्देश पर कूदें

void doSomething( void ) { 
    for (int i = 0; i < 1000; i++); 
}

void setup () 
{
    void (*funcPtr)( void );

    funcPtr = &doSomething;
    funcPtr(); // calls doSomething();

    funcPtr = NULL;
    funcPtr(); // undefined behavior
}

के लिए पहला कॉल funcPtr()वास्तव में एक कॉल होगा doSomething()। दूसरे की तरह कॉल अपरिभाषित व्यवहार हो सकता है।

अन्य बुरी चीजें जो हो सकती हैं

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

तरह तरह की सुरक्षा

कंप्यूटर सिस्टम में, इस तरह की समस्याओं को आमतौर पर विभिन्न स्तरों पर निपटाया जाता है:

  1. संकलक द्वारा
  2. प्रोग्रामिंग भाषा रनटाइम द्वारा (उदाहरण के लिए जावा में)।
  3. ऑपरेटिंग सिस्टम या प्रोसेसर द्वारा (यदि आपकी मेमोरी आपके प्रोग्राम के लिए आरक्षित एड्रेस स्पेस की सीमाओं के बाहर की स्थिति तक पहुंचती है, तो ओएस या प्रोसेसर के पास इसे रोकने के लिए सुरक्षा तंत्र हो सकते हैं)

Arduinos के पास केवल संकलक का सीमित संरक्षण है, और शायद कुछ और नहीं। अच्छी खबर यह है कि वे बहु-कार्य नहीं हैं, इसलिए प्रभावित होने वाला एकमात्र कार्यक्रम आपका है। किसी भी मामले में, उन बगों में से कोई भी अनिश्चित व्यवहार को जन्म देगा।

जवाब

मान्यताओं मैं ऊपर बताई गई समस्याओं के सभी रनटाइम समस्याएं हैं।

यदि किसी प्रोग्राम में रनटाइम त्रुटि होती है, तो क्या होता है?

कार्यक्रम जारी रहेगा और जो होता है वह रनटाइम त्रुटि के दुष्प्रभावों पर निर्भर करेगा। नल फ़ंक्शन पॉइंटर के लिए एक कॉल शायद कार्यक्रम को किसी अज्ञात स्थान पर कूद देगा।

क्या कार्यक्रम का क्रियान्वयन बस रुक जाएगा?

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

क्या कोई रास्ता है कि मैं Arduino पाने के लिए मुझे बताएं कि त्रुटि क्या है?

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

संरक्षण की कमी का कारण शायद यह है कि Arduino नियंत्रकों बहुत सस्ते हैं, बहुत कम स्मृति है, और कुछ भी महत्वपूर्ण नहीं चलना चाहिए (हाँ, AVR द्वारा एक अस्वीकरण प्रतीत होता है कहीं न कहीं आपके लिए MCU का उपयोग आमतौर पर नहीं किया जाता है लाइफ सपोर्ट सिस्टम में Arduino)।


1
महान! सबसे अच्छा जवाब मैंने अब तक Arduino.SE पर देखा है!
द गाइ हैट ​​विथ द हैट

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

5
@ रिकार्डो - एक टिप्पणी जो मैं करूंगा, वह यह है कि गैर-स्पष्ट रूप से आरंभिक चर जरूरी नहीं हैं कि वे असंगठित हों। आमतौर पर फ़ंक्शंस के बाहर परिभाषित चर को आमतौर पर "स्वचालित भंडारण अवधि" कहा जाता है, जो तब शून्य पर डिफ़ॉल्ट-आरंभिक हो जाता है। अधिक जानकारी के लिए en.cppreference.com/w/cpp/language/default_initialization देखें । इनिशियलाइज़ेशन व्यवहार काफी जटिल है कि शायद इस पर भरोसा करना खतरनाक है, लेकिन कंबल बयान करना शायद एक महान विचार नहीं है।
कॉनर वुल्फ

1
इसके अलावा, SRAM को रीसेट या स्टार्टअप पर 0 से आरंभिक किया जाता है, इसलिए आप खतरनाक तरीके से जीना चाहते हैं, तो आप अनइंस्टॉल किए गए चरों के बारे में कुछ सूचित अनुमान लगा सकते हैं । आपको इस व्यवहार पर भरोसा नहीं करना चाहिए , लेकिन यह दिलचस्प है।
कॉनर वुल्फ

1
जब आप यहां SRAM से बाहर निकलते हैं तो क्या होता है, इसका एक दिलचस्प उदाहरण है: Electronics.stackexchange.com/questions/42049/… । मूल रूप से, ढेर के ढेर का हिस्सा, या इसके विपरीत। यह स्टैक-फ्रेम के कुछ भाग को भ्रष्ट कर सकता है (फ़ंक्शन रिटर्न को तोड़ना, आदि), या चर को अमान्य डेटा लिखना।
कॉनर वुल्फ

9

कोई रनटाइम अपवाद नहीं हैं। केवल अपरिभाषित व्यवहार है।

वास्तव में, वहाँ कोई अपवाद नहीं हैं सब पर । यदि आप अमान्य कार्रवाई करने का प्रयास करते हैं, तो यह परिणाम अज्ञात होगा।

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


6

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

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

इस तरह आप डेटा खो रहे हैं, लेकिन यदि आप AVR WDT को इंटरप्ट मोड में चलाते हैं, तो आप MCU को रीसेट करने से पहले कुछ डेटा स्टोर कर सकते हैं।

तो वॉचडॉग टाइमर कभी-कभी अनजाने अंतहीन छोरों से आपके कोड की रक्षा कर सकता है।

दस्तावेज़ीकरण: AVR132: एन्हांस्ड वॉचडॉग टाइमर का उपयोग करना


5

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

ऐसा करने का एक सामान्य / त्वरित / आसान तरीका यह है कि आप चर के मूल्यों को प्रिंट करने के लिए प्रिंट स्टेटमेंट जोड़ सकते हैं या सिर्फ कुछ भी ताकि आप जानते हैं कि प्रोग्राम उस बिंदु पर कोड में एक समस्या के बिना प्राप्त होता है। यह आपको समस्या को और अलग करने में मदद करेगा।

मेरा मानना ​​है कि VisualMicro में कुछ डीबगिंग कार्यक्षमता है।


3

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


-2

Arduino रिबूट (यानी यह फिर से शुरू setup()और loop()) होगा।


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