2010-10-12 21 views
33

ब्रेकपॉइंट्स सी ++ कोड में कैसे काम करते हैं? क्या कोड संकलित होने पर वे कुछ असेंबलर निर्देशों के बीच डाले गए विशेष निर्देश हैं? या जगह में कुछ और है? साथ ही, चरण-दर-कोड-कोड कैसे कार्यान्वित किए जाते हैं? ब्रेकपॉइंट्स के समान ही ...?ब्रेकपॉइंट्स सी ++ कोड में कैसे काम करते हैं?

+0

ब्रेकपॉइंट्स प्रक्रिया के रनटाइम पर डीबगर द्वारा गतिशील रूप से इंजेक्शन दिए जाते हैं। और मैं उम्मीद करता हूं कि यह कोड के माध्यम से कदम उठाने के लिए भी गिना जाता है। हालांकि मैं इस बारे में 100% सकारात्मक नहीं हूं। – Vinzenz

+0

@ गैब्लिन, क्या आपको दिमाग होगा यदि हमने "सी ++" के बजाय "मूल" कोड के बारे में पूछने के लिए प्रश्न संपादित किया है? यह एक ही समस्या है और आपके द्वारा प्राप्त उत्तरों को बेहतर ढंग से प्रतिबिंबित करता है। –

+0

@StevenFisher: नहीं, आगे बढ़ें। =) – gablin

उत्तर

35

यह सीपीयू और डीबगर पर भारी निर्भर करता है।

उदाहरण के लिए, 86 CPU पर संभव समाधान में से एक:

  • सम्मिलित एक-बाइट INT3 आवश्यक जगह पर शिक्षा
  • ब्रेकप्वाइंट अपवाद तक इंतजार हिट
  • की सूची में अपवाद पते की तुलना करें ब्रेकपॉइंट यह निर्धारित करने के लिए कि कौन सा
  • ब्रेकपॉइंट क्रियाएं
  • मूल बाइट के साथ INT3 को बदलें और डीबग प्रक्रिया को ट्रेस मोड में स्विच करें (CPU I के चरण-दर-चरण निष्पादन को स्विच करें I nstructions)
  • डिबग जारी रखें प्रक्रिया
  • तुरंत आप अपवाद का पता लगाने को पकड़ने - अनुदेश
  • रखो INT3 मार डाला गया था वापस

watchpoints समान तरीके से लागू किया जा सकता है, लेकिन INT3 के बजाय आप स्मृति डाल पृष्ठ जहां देखा गया चर केवल पढ़ने में है, या कोई एक्सेस मोड में नहीं है, और सेगमेंटेशन अपवाद की प्रतीक्षा करें।

ट्रेस मोड का उपयोग करके असेंबली के माध्यम से कदम भी किया जा सकता है। डीबग डेटा के आधार पर, ब्रेकपॉइंट्स को अगले निर्देशों पर रखकर स्रोत लाइनों के माध्यम से कदम उठाया जा सकता है।

इसके अलावा कुछ CPU में हार्डवेयर ब्रेकपॉइंट समर्थन होता है, जब आप कुछ रजिस्टर में पता लोड करते हैं।

+0

मुझे "मूल बाइट के साथ INT3 को प्रतिस्थापित करें" भाग नहीं समझा जाता है ... हमें ऐसा करने की आवश्यकता क्यों है? – gablin

+0

ब्रेकपॉइंट से फिर से शुरू करने के बाद, आपको सीपीयू निर्देश निष्पादित करने की आवश्यकता है जहां आपने रोका था, लेकिन आपने इसे दूषित कर दिया - INT3 ऑपोड के साथ पहले बाइट को प्रतिस्थापित किया। इसलिए आपको इसे पुनर्स्थापित करने की आवश्यकता है, निर्देश को सीपीयू द्वारा संसाधित करने दें, और उसके बाद INT3 को वापस रखें - अगली बार जब यह निर्देश निष्पादित हो जाता है, तो आप फिर से – Xeor

+1

तोड़ते हैं, ओह, मैं देखता हूं। तो _that's_ डीबगर कोड में ब्रेकपॉइंट "इंजेक्ट" कैसे करता है। धन्यवाद! – gablin

8

this blog entry technochakra.com पर के अनुसार आप सही हैं:

सॉफ्टवेयर breakpoints कार्यक्रम में एक विशेष निर्देश डालने डिबग किया जा रहा द्वारा काम करते हैं। इंटेल प्लेटफ़ॉर्म पर यह विशेष निर्देश "int 3" है। निष्पादित होने पर यह डीबगर के अपवाद हैंडलर को कॉल करता है।

मुझे यकीन नहीं है कि अगले निर्देश में या आगे बढ़ने के तरीके को कैसे लागू किया गया है। हालांकि, लेख जोड़ने के लिए आगे बढ़ता है:

व्यावहारिक कारणों से, ब्रेकपॉइंट जोड़े जाने या हटाए जाने पर पुन: संकलन के लिए पूछना मूर्ख नहीं है। डिबगर्स निष्पादन योग्य की लोड की गई छवि को स्मृति में बदलते हैं और रनटाइम पर "int 3" निर्देश डालते हैं।

हालांकि, इसका उपयोग केवल "वर्तमान लाइन विकल्प पर चलाने" के लिए किया जाएगा।

4

सिंगल स्टेपिंग को (असेंबलर) कोड स्तर पर लागू किया गया है जो सी ++ स्तर पर नहीं है। डीबगर जानता है कि कोड पते पर सी ++ कोड लाइनों को कैसे मैप करना है।

विभिन्न कार्यान्वयन हैं। ऐसे CPUs हैं जो ब्रेकपॉइंट रजिस्टरों के साथ डिबगिंग का समर्थन करते हैं। जब निष्पादन ब्रेकपॉइंट रजिस्टर में पते तक पहुंच जाता है, तो CPU एक ब्रेकपॉइंट अपवाद निष्पादित करता है।

एक अलग निर्देश एक विशेष निर्देश के साथ निष्पादन के समय कोड को पैच करना है, सर्वोत्तम एक-बाइट निर्देश पर। X86 सिस्टम पर आमतौर पर int 3.

पहला दृष्टिकोण रोम में ब्रेकपॉइंट्स की अनुमति देता है, दूसरा एक ही समय में अधिक ब्रेकपॉइंट्स की अनुमति देता है।

1

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

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

नोट भी, कि डिबगिंग स्वयं-संशोधित कोड ठीक से विफल हो सकता है क्योंकि डीबगर क्षणिक रूप से कोड को संशोधित करता है। (बेशक, कोई भी स्वयं को संशोधित नहीं करेगा, अब वे?> ;-)

इन कारणों से, यह महत्वपूर्ण है कि डीबगर को डिबगिंग सत्र को समाप्त करने से पहले सेट किए गए सभी ब्रेकपॉइंट्स को हटाने का अवसर दिया जाए ।

+0

"यह महत्वपूर्ण है कि डीबगर को डिबगिंग सत्र को समाप्त करने से पहले सेट किए गए सभी ब्रेकपॉइंट्स को हटाने का मौका दिया जाए।" नहीं - डीबगर केवल छवि में स्मृति को संशोधित करता है, डिस्क पर मूल फ़ाइल नहीं। –

+0

दरअसल, लेकिन यदि आप डीबगर को समाप्त करते हैं और प्रोग्राम जारी रखते हैं, तो प्रोग्राम को – smirkingman

+0

पर जाने से पहले इन-मेमोरी ब्रेकपॉइंट्स को हटाना होगा यदि आपका प्रोग्राम कोड आपकी स्मृति से बड़ा है तो क्या होगा? शायद gdb डिस्क को मारने से ब्रेकपॉइंट्स को रखने के लिए MAP_PRIVATE के साथ mmap का उपयोग करता है ... –

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