डिबगर क्या है और यह मुझे समस्याओं के निदान में कैसे मदद कर सकता है?


107

यह नए प्रोग्रामर की सहायता करने के लिए एक सामान्य उद्देश्य वाला प्रश्न है, जिनके पास एक कार्यक्रम की समस्या है, लेकिन समस्या के कारण का निदान करने के लिए डिबगर का उपयोग करना नहीं जानते हैं।

यह प्रश्न तीन और वर्गों को शामिल करता है:

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

3
अच्छा काम - डिबगिंग तकनीकों के लिए संबंधित "गो" से "क्यू एंड ए" होना भी अच्छा होगा , उदाहरण के लिए डीबगर, अन्य डीबग टूल (जैसे वेलग्रिंड), रणनीतिक प्रिंटफ़्स, तनाव परीक्षण, विभाजन और जीत, आदि का उपयोग करना
पॉल R

1
मैं @PaRR से सहमत हूं, FAQ में इस तरह से सामान होना चाहिए।
निकु स्टियुरका

जवाबों:


73

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

डिबगर का उपयोग करना एक अपेक्षित बुनियादी कौशल है

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

कैसे एक डिबगर आपकी मदद कर सकता है

डिबगर का उपयोग करके आप यह पता लगा सकते हैं कि एक चर का गलत मान है या नहीं, और आपके कार्यक्रम में इसका मान गलत मान में कहां बदल गया।

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

डिबगर का उपयोग करने पर सामान्य नोट्स

डीबगर का उपयोग करने की बारीकियाँ डीबगर पर निर्भर करती हैं और कुछ हद तक, जिस प्रोग्रामिंग भाषा का आप उपयोग कर रहे हैं।

  • आप डिबगर को एक प्रक्रिया से जोड़ सकते हैं जो पहले से ही आपके प्रोग्राम को चला रही है। यदि आपका प्रोग्राम अटका हुआ है तो आप ऐसा कर सकते हैं।

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

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

  • अधिकांश आधुनिक डिबगर एक IDE का हिस्सा होते हैं और आपको अपने प्रोग्राम के स्रोत कोड और चर की जांच करने के लिए एक सुविधाजनक GUI प्रदान करते हैं, जो ब्रेकपॉइंट्स सेट करने के लिए एक बिंदु और क्लिक इंटरफेस के साथ, आपके प्रोग्राम को चलाने और इसे एकल करने के लिए।

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


4
यह अधूरा है क्योंकि यह सभी के सबसे महत्वपूर्ण डिबगर को याद करता है, एक जिसमें स्टैकओवरफ्लो पर प्रश्नों की संख्या को काफी कम करने की क्षमता है (मैं कम से कम 20% की भविष्यवाणी करता हूं) - जावास्क्रिप्ट डिबगर्स: फायरबग, क्रोम, फ़ायरफ़ॉक्स, IE9 + एकीकृत डिबगर , IE8- विज़ुअल स्टूडियो, इत्यादि
स्लीपबेटमैन

1
नोड.जेएस के लिए भी - नोड इंस्पेक्टर। लेकिन नोड। जेएस प्रोग्रामर सामान्य जावास्क्रिप्ट प्रोग्रामर के रूप में कई बुनियादी और / या फिक्स-माय-कोड प्रश्न नहीं पूछते हैं।
स्लीपबेटमैन

40

मैं जोड़ना चाहता हूं कि एक डिबगर हमेशा सही समाधान नहीं होता है, और हमेशा डिबगिंग के लिए समाधान नहीं होना चाहिए। यहां कुछ मामले हैं जहां एक डिबगर आपके लिए काम नहीं कर सकता है:

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

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

तो फिर विकल्प क्या हैं?

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

गलत मूल्यों को फंसाने के लिए दावे का इस्तेमाल किया जा सकता है, बजाय इसके कि एक बार अंत-उपयोगकर्ता को दिखाई देने वाला प्रभाव दिखाई दे। जितनी जल्दी आप एक गलत मूल्य पकड़ते हैं, उतने ही करीब आप इसे पैदा करने वाली रेखा के करीब होते हैं।

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

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

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


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

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

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

"आप बता सकते हैं कि आपका बग फ़ंक्शन X पर आने वाले गलत मानों के कारण है, लेकिन आपको नहीं पता कि ये मान कहाँ से आते हैं" यह विशेष रूप से डीबग करना कठिन है। आप आमतौर पर इस तरह से कुछ तय करने के बारे में कैसे जाते हैं?
अयक्सन हक्वेर्डिली

3
@Ayxan कुछ हद तक, यदि आप फ़ंक्शन को मुखर बनाने में कामयाब रहे हैं, तो आप कॉलर प्राप्त करने के लिए कॉल स्टैक का उपयोग कर सकते हैं। लेकिन यह अकेला आपको मूल्य का स्रोत नहीं देता है, क्योंकि मूल्य पहले की रेखा से सबसे अधिक संभावना है। आपको मूल रूप से वैल्यू बैक का पालन करना होगा, विभिन्न चर के माध्यम से यह गुजरता है। यदि आपके पास डेटा को ले जाने वाले मार्ग का एक अच्छा विचार है, तो आप बस लॉग प्रिंट का एक गुच्छा बना सकते हैं, और जहां इसे "गलत हो जाता है" संकीर्ण करने का प्रयास करें। यदि नहीं, तो आपको मूल रूप से हर चरण के लिए प्रोग्राम के एक अलग रन (त्रुटि को पुन: प्रस्तुत करना) की आवश्यकता होगी।
स्लगफिलर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.