Search

1.11 — आपके program को Debug करना (stepping और breakpoints)

Syntax और semantic errors

Programming काफी मुश्किल हो सकता है, और आप programs लिखने समय कई तरह की गलतियाँ कर सकते हो । Errors मुख्यतः दो तरह के होते हैं: syntax errors, और semantic errors (logic errors) ।

Syntax error program में तब आते हैं, जब आपका लिखा हुआ कोई statement C++ के grammar के अनुसार सही ना हो । आप statement के अंत में semicolon लगाना भूल जाते हो, बिना declare किये किसी variable को use करने की कोशिश करते हो, braces या paranthesis के जोड़े में केवल एक को लिखते हो या फिर किसी string को terminate करना भूल जाते हो, ऐसे errors syntax errors की category में आते हैं । उदाहरण के लिए, नीचे दिए गए program में कुछ syntax errors हैं :

अच्छी बात ये है, की compiler साधारणतः हर syntax error को catch कर warning या error दे देता है, इसलिए आप इन्हें आसानी से fix कर सकते हो । इसलिए, ये program में जब तक सारे errors न मिल जाएँ, तब तक इसे compile करने जितना ही आसान है ।

यदि आपका program अच्छी तरह से compile हो रहा है, तो भी program से expected (वांछित) result(s) प्राप्त करना थोड़ा मुश्किल साबित हो सकता है । यदि program के syntatically (C++ के grammar के अनुसार) सही होने के बाद भी ये आपका मनचाहा result नहीं दे रहा है, तो ऐसे errors को sematic errors कहते हैं ।
कभी-कभी semanatic errors के कारण आपका program crash भी हो सकता है, उदाहरण के लिए, जब आप किसी number को 0 से divide करोगे (अर्थात् भाग दोगे), तो आपका program संभवतः crash कर जायेगा :

कभी-कभी, ये गलत values भी प्रदान कर सकते हैं:

या

दुर्भाग्यवश, compiler ऐसे errors को catch नहीं कर सकता, क्यूंकि compiler को बस इतना पता है की आपने code में क्या लिखा है, ये नहीं की आप code से क्या उम्मीद करते हो ।

ऊपर दिए गए उदाहरण में सारे errors का पता आसानी से लगाया जा सकता है । लेकिन बड़े-बड़े programs में, कई semantic errors केवल code को देखते रहने से पकड़ में नहीं आते ।

Fortunately, यहाँ debugger काफी सुविधाजनक साबित हो सकता है ।

Debugger

Debugger एक ऐसा computer program है जो programmer को ये control करने की अनुमति देता है, की program कैसे execute होगा और साथ ही ये भी दिखाता है की program run करते हुए क्या-क्या output दे रहा है । उदाहरण के लिए, programmer debugger का इस्तेमाल करते हुए किसी program को line-by-line execute करके ये देख सकता है, की प्रत्येक पड़ाव में variables के क्या-क्या values set हैं । Variable के वास्तविक value को programmer के सोचे गए value से compare कर, या फिर code के execution के path पर नज़र रखते हुए, debugger किसी semantic error को खोज निकालने में हमारी काफी मदद कर सकता है ।

पहले के debuggers, जैसे की gdb, में command-line interface होता था, जहाँ programmer को कुछ commands type कर debugging का काम करना पड़ता था । इसके बाद के debuggers, (जैसे की Borland का turbo debugger) “graphical interface” के साथ आने लगे, ताकि उनके साथ काम करना और ज्यादा आसान और मज़ेदार हो जाये । आजकल के लगभग सभी IDEs में एक integrated debugger मौजूद होता है -- ये editor में ही बना होता है या फिर ऐसा कहा जाये की editor से ही जुड़ा होता है, ताकि आप एक ही environment में codes को लिखने और debug करने का काम कर सके (इन दोनों कामों के लिए, एक से दुसरे program में जाये बिना) ।

आज के लगभग हर debugger, basic features के बिलकुल एक जैसे standard के साथ आते हैं -- फिर भी, इनमें दिए गए menus कैसे arrange किये गए हैं और इनके लिए keyboard shortcuts क्या-क्या हैं, ये अलग-अलग IDEs में एक दुसरे से थोड़े अलग हो सकते हैं । हमारे examples Microsoft Visual Studio 2005 Express के अनुसार लिखे गए हैं, फिर भी आपको अपने IDE में, यहाँ दिए गए features को ढूंढने के लिए काफी ज्यादा मेहनत करने की ज़रूरत नहीं पड़ेगी ।

आगे बढ़ने से पहले: ये पक्का कर ले की आपका program debug build configuration का इस्तेमाल करने के लिए set है ।

Stepping

Stepping debugger का एक feature है, जो आपको codes को line-by-line (step through) execute करने की अनुमति देता है । इस तरह से आपको ये पता चलेगा, की आपका code किसी पड़ाव पर आपके सोचे गए अनुसार काम कर रहा है या नहीं ।

Stepping commands 3 हैं : step into, step over, और step out । हम एक-एक कर के इनके बारे में जानेंगे ।

Step into

Step into command, code के अगले line को execute करता है । यदि इस line में किसी function को call किया गया है, तो step into उस function में चला जायेगा और इसके बाद सारा control, function में सबसे ऊपर चला जायेगा ।

आइये एक आसान से program पर नज़र डालते हैं:

जैसा की आप जानते हो, जब कोई program run होता है, तो execution की शुरुआत main() function के call होने के साथ होती है । क्यूंकि हमे main के अन्दर से debug करना है, आइये हम “Step into” command का प्रयोग करते हैं ।

Visual Studio 2005 Express में, debug menu में जाकर “Step into” का चुनाव कर ले, या फिर F11 key press करें ।
यदि आप किसी दुसरे IDE का प्रयोग कर रहे हैं, तो इसके Menu में कहीं “Step Into” command खोजने की कोशिश कीजिये ।

जब आप ये करोगे, दो चीजें होनी चाहिए । पहला, क्यूंकि हमारा application एक console program है, तो सबसे पहले console output window खुलना चाहिए । ये अभी बिलकुल खाली होगा क्यूंकि हमने अभी तक कुछ भी output नहीं किया है । दूसरा, आपको main function की बायीं ओर, opening brace ( { ) में एक marker दिखाई देना चाहिए । Visual Studio 2005 Express में, ये marker एक पीला arrow होता है । यदि आप किसी दुसरे IDE का प्रयोग कर रहे हो, तो फिर इस जगह पर कुछ न कुछ ज़रूर दिखना चाहिए ।

ये पीला marker ये बता रहा है की अगले execution में pointed line (वो line जिसपे marker है) ही execute होगा । यहाँ पे, हमारा debugger हमे ये बता रहा है की अगला line जो execute होने वाला है, वो main() function के opening brace वाला line है । इसके बाद “Step into” को फिर से चुन लें ताकि opening brace वाला line execute हो जाये, और arrow अगले line में चला जाये ।

अब अगला line जो execute होगा, वो printValue() को call करने वाला line है । “Step into” को फिर से चुन लें । क्यूंकि printValue() एक function call statement है, हमलोग इस function (printValue()) पर पहुँच जायेंगे , और arrow printValue() में सबसे ऊपर दिखाई देने लगेगा ।

फिर से “Step into” को चुन ले ताकि printValue() का opening brace execute हो जाये ।

इसके बाद marker std::cout << nValue; वाले line पर चला जायेगा ।

अब यहाँ "Step over" को चुने (ये आपके code में केवल इसी line को execute करेगा, न की operator << के code में पहुँच जायेगा) । क्यूंकि cout statement अब execute हो चूका है, आप देखोगे की output window में 5 print हो गया है ।

इस function के closing brace को execute करने के लिए एक बार फिर से "Step into" को चुन लें । इसी के साथ, printValue() का execution अब ख़त्म हो गया है और control वापस main() पर चला गया गया है ।

आप देखोगे की arrow फिर से printValue() को point कर रहा है!

यहाँ आप ये सोच सकते हो की debugger फिर से printValue() को call करने वाला है, असल में debugger ऐसा इसलिए कर रहा है, ताकि आपको पता चल सके की ये इस function से लौट चूका है ।

इस बार "Step into" को दो बार select करें । अब हमने program के हर एक line को execute कर लिया है और इसलिए इस program में हमारा (debugging का) काम ख़त्म हो गया है । कुछ debuggers program के ख़त्म होने पर debugging के process को अपने आप बंद कर देंगे । पर Visual Studio ऐसा नहीं करता और इसलिए यदि आप Visual Studio इस्तेमाल कर रहे हो, तो debugging session ख़त्म करने के लिए debug menu में से "Stop Debugging" के option को चुन लो ।

ध्यान दे की "Stop Debugging" option का इस्तेमाल, debugging के process को खत्म करने के लिए किसी भी जगह पर किया जा सकता है ।

Step over

"Step into" की तरह, Step over command भी code के next line को ही execute करता है । यदि इस line में कोई function call है, तो "Step over" function के सारे codes को execute कर के control आप पे छोड़ देता है ।

ध्यान दे की Code::Blocks में "Step over" को "Next Line" कहा जाता ।

आइये ऊपर दिए गए program में Step Over के असर को देखें:

Program को तब तक "Step into" करते जाइये जब तक marker printValue() को call करने वाले statement तक नहीं पहुँचता । कहने का मतलब है, program को तब तक “Step into” करते जाइये, जब तक execute होने वाला अगला statement function printValue() को एक call ना हो ।

अब printValue() में , “Step into” की जगह "Step over" select करें । अब debugger इस function को execute करेगा (जिसके परिणाम स्वरुप console window पर 5 print होगा) और फिर अगले line में control आपको सौंप देगा (return 0;) ।

Debugging करते वक़्त जब आपको पता हो की किसी function में कोई खराबी नहीं है, तो इसे छोड़कर आगे बढ़ने में Step over काफी उपयोगी साबित हो सकता है ।

Step out

ऊपर दिए गये दो stepping commands से अलग, "Step out" केवल अगले line को execute नहीं करता । बल्कि, आप अभी जिस function में हो, “Step out” उसके codes को भी execute करता है और जब function पूरी तरह से execute हो जाये, तो आपको control सौंप देता है ।

आइये इसका एक उदाहरण देखे:

जब तक आप printValue() में ना चले जाये, program को "Step into" करते जाइये ।

इसके बाद "Step out" चुन लीजिये । आप देखोगे की console window पर 5 print हो चूका होगा, और function के ख़त्म होने के बाद debugger फिर से आपको control सौंप देगा ।

Run to cursor

जहाँ stepping out code के एक-एक line को रूक-रुक कर test करने में काफी उपयोगी है, किसी बड़े program में, इन commands का इस्तेमाल करते हुए ज्यादा गहरायी से जाँच की आवश्यकता वाली जगह पर पहुंचना काफी समय ले सकता है ।

हमारी किस्मत अच्छी है क्यूंकि modern debuggers codes को अच्छी तरह से debug करने के लिए कुछ और tools प्रदान करते हैं।
इनमे से पहले command को Run to cursor के नाम से जाना जाता है । ये command, codes को तब तक normally execute करता है जब तक execution आपके cursor द्वारा selected code तक नहीं पहुँच जाता । इसके बाद ये आपको control return कर देता है, ताकि आप इसके आगे debugging का काम कर सके ।

आइये इसका भी एक उदाहरण देखें:

अपने cursor को printValue() function में line std::cout << nValue; पर रखें, और इसके बाद right click करके, यहाँ से "Run to cursor" option चुन ले ।

आप देखोगे की arrow, जो execution के अगले line को दर्शाता है, वो आपके selected line पर चला जायेगा । अब debugger यहाँ से debug करने के लिए आपके commands का इंतज़ार कर रहा है ।

Run

जब आप किसी program को debug कर रहे होते हो, आप debugger को program के अंत तक (या फिर अगले breakpoint तक, जिसके बारे में हम थोड़ी ही देर में जानेंगे), run करने का instruction दे सकते हो । Visual Studio 2005 Express में, इस command को "Continue" कहा जाता है । दुसरे IDEs में, “Continue” की जगह "Run" या "Go" शब्द का इस्तेमाल किया जा सकता है ।

यदि आप ऊपर दिए गए examples को क्रमानुसार follow करते गए हो, तो आपको अभी function printValue() में होना चाहिए । यहाँ से run command चुन लीजिये और आपका program इसके अंत तक execute होता चला जायेगा ।

Breakpoints

Breakpoint इस section का अंतिम topic है । Breakpoint एक ख़ास तरह का marker है, जो debug mode active होने पर, debugger को breakpoint की जगह पर रूकने की आज्ञा देता है ।

Visual Studio 2005 Express में breakpoint set करने के लिए, Debug menu में जाकर "Toggle Breakpoint" को select कर ले (आप right click कर Breakpoint -> Insert Breakpoint भी चुन सकते हैं) ।

आगे बढ़ते हुए std::cout << nValue; line पर एक break point set कीजिये ।

अब यहाँ से "Step into" select कर debugging session की शुरुआत कीजिये, और फिर debugger को program के अंत तक run करने के लिए “Continue” command का इस्तेमाल कीजिये । अब आप breakpoint को यहाँ काम करते हुए देख सकते हैं । आपको देखने को मिलेगा की program को अंत तक run करने के बजाय, debugger breakpoint की जगह पर रूक गया है !

Breakpoints code के किसी हिस्से को test करने करने में बहुत ज्यादा उपयोगी हैं । आपको जहाँ भी code में गड़बड़ी का आभास होता है, वहाँ सबसे ऊपर बस एक breakpoint set कर दीजिये, यहाँ से debugger को run कीजिये, और debugger अपने आप breakpoint पर execution रोक कर आपको control return कर देगा । इसके बाद आप यहाँ से stepping commands का इस्तेमाल कर के अपने program के एक-एक line को run होते हुए देख सकते हो ।

एक आखरी note: अभी तक, हमने debugging session start करने के लिए सिर्फ और सिर्फ "step into" command का इस्तेमाल किया है । लेकिन debugger को एक ही बार में program के end तक run करने का instruction भी दिया जा सकता है । Visual Studio 2005 Express में, इसे Debug menu में से "Start debugging" option को चुनकर किया जा सकता है । दुसरे debuggers में भी ऐसे commands होते हैं, लेकिन इनके नाम अलग हो सकते हैं । इनका उपयोग जब breakpoints के साथ किया जाता है, तो ये आपको code के उन हिस्सों, जहाँ गहरायी से जाँच-पड़ताल की ज़रूरत है, में बहुत ही जल्द और commands लिखने के झंझट को कम करते हुए पहुंचा देते हैं, ताकि आप यहाँ से आगे debug कर सके ।

निष्कर्ष

बधाई हो, अब आप debugging के सारे मुख्य तरीकों के बारे में जान चुके हो । इन commands का प्रयोग करके आप debugger को आसानी से अपने code में इस्तेमाल कर सकते हो । फिर भी, यहाँ debuggers के सिर्फ आधे फायदों का ज़िक्र किया गया है । अगले lesson में हम ये देखेंगे की debugging के दौरान किसी variable के value की जाँच कैसे की जाये । इसके साथ-साथ हम कुछ अन्य information windows के बारे में भी जानेंगे जिनका प्रयोग हम debugging के क्रम में अपनी सुविधा के लिए कर सकते हैं ।

1.11a -- आपके program को debug करना (variables और call stack पर नज़र रखना )
Index
1.10a -- आपका पहला program कैसे design किया जाये

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter