क्या मैं GDB में 'मेमोरी एक्सेस' पर एक ब्रेकप्वाइंट सेट कर सकता हूं?


244

मैं gdb के माध्यम से एक एप्लिकेशन चला रहा हूं और मैं किसी भी समय एक विशिष्ट चर एक्सेस / परिवर्तित होने के लिए एक ब्रेकपॉइंट सेट करना चाहता हूं। क्या ऐसा करने के लिए एक अच्छी विधि है? मैं अन्य तरीकों से भी दिलचस्पी लेता हूँ कि C / C ++ में किसी वैरिएबल की निगरानी करें कि यह कब / कब बदलता है।

जवाबों:


286

घड़ी केवल लिखने पर टूटता है, rwatch आप पढ़ने पर तोड़ दें, और awatch आप पढ़ें / लिखें पर तोड़ देते हैं।

आप मेमोरी स्थानों पर वाचप्वाइंट सेट कर सकते हैं:

gdb$ rwatch *0xfeedface
Hardware read watchpoint 2: *0xfeedface

लेकिन एक सीमा राउत पर लागू होती है और कमांड को जाग्रत करती है; आप अभिव्यक्ति में gdb चर का उपयोग नहीं कर सकते हैं:

gdb$ rwatch $ebx+0xec1a04f
Expression cannot be implemented with read/access watchpoint.

इसलिए आपको उन्हें स्वयं विस्तार देना होगा:

gdb$ print $ebx 
$13 = 0x135700
gdb$ rwatch *0x135700+0xec1a04f
Hardware read watchpoint 3: *0x135700 + 0xec1a04f
gdb$ c
Hardware read watchpoint 3: *0x135700 + 0xec1a04f

Value = 0xec34daf
0x9527d6e7 in objc_msgSend ()

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

gdb$ show can-use-hw-watchpoints
Debugger's willingness to use watchpoint hardware is 1.

7
यदि आप C ++ विधि का सदस्य देखना चाहते हैं, तो मुझे यह संस्करण बेहद उपयोगी लगा watch -location mTextFormatted:।
इवान वुइका

यदि मेरे पास किसी चर का पता नहीं है तो क्या होगा? क्या मैं सिर्फ इसके नाम का उपयोग कर सकता हूं?
रफी खाचदौरेन

5
आप GDB को ऑपरेटर के एड्रेस-इन के साथ वैरिएबल का पता प्रिंट कर सकते हैं। print &variable
लडुविज्क

1
यह उत्तर मेमोरी लोकेशन के आकार के बारे में कुछ नहीं कहता है जिसे watchकमांड द्वारा देखा जा रहा है । इस बीच, यह मुट्ठी का सवाल है जो ऊपर पढ़ने के बाद दिमाग में आता है। rwatch *0xfeedfaceवास्तव में कितने बाइट्स देखेंगे?
एनटी

8
@ एएनटीटी, मैं यह मान रहा था कि यह एक एकल बाइट को देखेगा, जो मामला प्रतीत होता है, लेकिन आप इसे एक विशिष्ट प्रकार के लिए डाल सकते हैं rwatch *(int *)0xfeedfaceऔर यह sizeof(int)बाइट्स देखेगा
आस्कोल

28

आप जो देख रहे हैं उसे वॉचपॉइंट कहा जाता है ।

प्रयोग

(gdb) watch foo: चर का मान देखें foo

(gdb) watch *(int*)0x12345678: एक पते द्वारा बताए गए मूल्य को देखें, जो भी आप चाहते हैं, उसके लिए डाले गए

(gdb) watch a*b + c/d: एक मनमाने ढंग से जटिल अभिव्यक्ति देखें , जो कार्यक्रम की मूल भाषा में मान्य है

चौकीदार तीन प्रकार के होते हैं:

  • घड़ी : जब एक लेखन होता है तो जीडीबी टूट जाएगा
  • rwatch : gdb एक पाठ घटित होने पर टूट जाएगा
  • awatch : gdb दोनों मामलों में टूट जाएगा

आप अपनी आवश्यकताओं के लिए अधिक उपयुक्त चुन सकते हैं।

अधिक जानकारी के लिए, इसे देखें


5
मैंने एक और उत्तर लिखा क्योंकि मौजूदा वाले मेरे लिए बहुत सीधे नहीं थे ...
पाओलो एम

25

पहले उत्तर को मान लीजिए कि सी-जैसे सिंटैक्स का जिक्र है (char *)(0x135700 +0xec1a04f)तो करने का उत्तर rwatch *0x135700+0xec1a04fगलत है। सही सिंटैक्स है rwatch *(0x135700+0xec1a04f)

एस की कमी के ()कारण मुझे खुद को देखने की कोशिश करने में बहुत तकलीफ हुई।


9

मैंने निम्नलिखित कोशिश की:

 $ cat gdbtest.c
 int abc = 43;

 int main()
 {
   abc = 10;
 }
 $ gcc -g -o gdbtest gdbtest.c
 $ gdb gdbtest
 ...
 (gdb) watch abc
 Hardware watchpoint 1: abc
 (gdb) r
 Starting program: /home/mweerden/gdbtest 
 ...

 Old value = 43
 New value = 10
 main () at gdbtest.c:6
 6       }
 (gdb) quit

तो यह संभव लगता है, लेकिन आप कुछ हार्डवेयर समर्थन की जरूरत है।


यदि आपका प्लेटफ़ॉर्म हार्डवेयर वॉचपॉइंट का समर्थन नहीं करता है, तो gdb को एक सॉफ़्टवेयर वॉच पॉइंट पर वापस गिरना चाहिए।
टॉड

2

यह देखने के लिए घड़ी का उपयोग करें कि किसी चर को कब लिखा गया है, पढ़े जाने के समय, पढ़ने के लिए और जब इसे ऊपर से / जैसा लिखा जाए, तब इसे पढ़िए। हालाँकि, कृपया ध्यान दें कि इस कमांड का उपयोग करने के लिए, आपको प्रोग्राम को तोड़ना चाहिए, और प्रोग्राम को तोड़ने पर वेरिएबल स्कोप में होना चाहिए:

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

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