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