2011-08-14 13 views
7

जब जीडीबी के साथ डीबगिंग करते हैं, तो मैं एक सुविधा चर को एक नए निर्मित मूल्य पर सेट करना चाहता हूं।सुंदर प्रिंटर के लिए gdb में कन्स्ट्रक्टर को कॉल करने के लिए कैसे करें

मैं क्यूटी फ्रेमवर्क का उपयोग कर प्रोग्रामिंग कर रहा हूं, इसलिए मैं एक क्यूस्ट्रिंग बनाना चाहता हूं, लेकिन यह सवाल के लिए अप्रासंगिक है, क्योंकि मैं यह जानना चाहता हूं कि किसी भी वर्ग के साथ इसे कैसे किया जाए।

मैं

(gdb) set $str = 'QString::QString("abc")' 
No symbol "QString::QString("abc")" in current context. 

(gdb) set $str = QString::QString("abc") 
Cannot resolve method QString::QString to any overloaded instance 

(gdb) set $str = QString("abc") 
A syntax error in expression, near `("abc")'. 

की कोशिश की तो मैं set overload-resolution off उपयोग करने की कोशिश है, तो निम्न में जिसके परिणामस्वरूप:

(gdb) set $str = 'QString::QString(const char*)'(malloc(sizeof(QString)), "abc") 
(gdb) p $str 
$8 = void 

ठीक है, कंस्ट्रक्टर्स:

set $str = QString::QString("abc") 
non-unique member `QString' requires type instantiation 

set $str = 'QString::QString(const char*)'("abc") 
Too few arguments in function call. 

तो मैं एक इस सूचक की जरूरत है ग्रहण वापसी शून्य, इसका मतलब है कि मुझे कहीं भी malloc के वापसी मूल्य को बचाने के लिए है:

(gdb) set $pointer = malloc(sizeof(QString)) 
(gdb) p $pointer 
$9 = 6304560 
(gdb) p/x $pointer 
$10 = 0x603330 
(gdb) set $str = 'QString::QString(const char*)'($pointer, "abc") 
(gdb) p $str 
$11 = void 
(gdb) p $pointer 
$12 = 6304560 
(gdb) p *((QString*)$pointer) 
$13 = "abc" 

ठीक है, अब इस अपेक्षा के अनुरूप है, तथापि मैं एक अजगर सुंदर प्रिंटर के लिए इस कोड को gdb.parse_and_eval में() का उपयोग करना चाहते काम करता है। अब यह कई बार मॉलोक को कॉल करेगा, मेमोरी रिसाव बनायेगा। तो बस मुफ्त() कॉल करें? अब कुछ अप्रत्याशित होता है:

(gdb) call free($pointer) 
$14 = 0 
(gdb) p *((QString*)$pointer) 
$15 = "abc" 

सूचक अभी भी मान्य है, जो निश्चित रूप से, बिल्कुल ठीक हो सकता है के बाद से स्मृति पुन: उपयोग नहीं किया गया है। हालांकि मुझे यकीन नहीं है कि यह ठीक है क्योंकि कुछ और मेमोरी ब्लॉक आवंटित करने के बाद जो ठीक उसी QString में फिट होते हैं, पॉइंटर मान को अभी भी मॉलोक द्वारा पुन: उपयोग नहीं किया गया है।

क्या मैं एक बड़ी मेमोरी-रिसाव बना रहा हूं यदि मैं इसे एक सुंदर प्रिंटर में उपयोग करता हूं, जिसे डीबग सत्र के दौरान कई बार बुलाया जा सकता है? वांछित परिणाम बनाने का कोई आसान समाधान है (यानी पायथन एपीआई का उपयोग कर)?

इससे भी असंबंधित, क्यों मुक्त (3) मुझे 0 का रिटर्न वैल्यू दे रहा है जबकि यह वास्तव में शून्य है?

उत्तर

1

मुझे नहीं पता कि पॉइंटर को कैसे मुक्त किया जाए। ऐसा असंभव प्रतीत होता है, लेकिन बनाई गई स्मृति रिसाव काफी छोटी होनी चाहिए। लेकिन मुझे पता है कि

पॉइंटर अभी भी वैध लगता है, जो निश्चित रूप से ठीक हो सकता है, क्योंकि स्मृति का पुन: उपयोग नहीं किया गया है। हालांकि मुझे यकीन नहीं है कि यह ठीक है क्योंकि कुछ और मेमोरी ब्लॉक आवंटित करने के बाद जो ठीक उसी QString में फिट होते हैं, पॉइंटर मान को अभी भी मॉलोक द्वारा पुन: उपयोग नहीं किया गया है।

इस कोड है कि कैसे एक समस्या को हल कर सकता है दिखाना चाहिए देखें (केवल जीएनयू gdb पर परीक्षण (GDB) SUSE (7.5.1-2.1.1))

(gdb) call malloc(sizeof(std::string)) 
$1 = (void *) 0x64e4d0 
(gdb) call ((std::string*)0x64e4d0)->basic_string() 
(gdb) call ((std::string*)0x64e4d0)->assign("Hello World") 
$2 = "Hello World" 
(gdb) call ((std::string*)0x64e4d0)->'~basic_string'((std::string*)0x64e4d0) 
warning: Using non-standard conversion to match method std::string::~basic_string to supplied arguments 
(gdb) print ((std::string*)0x64e4d0) 
$3 = (std::string *) 0x64e4d0 
(gdb) print *((std::string*)0x64e4d0) 
$4 = "" 
(gdb) call free(0x64e4d0) 
(gdb) print *((std::string*)0x64e4d0) 
$5 = "" 

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

किसी को पहले बनाए गए ऑब्जेक्ट के विनाशक को कॉल करने की आवश्यकता है और फिर पॉइंटर (मेरे कोड में $ 2 से नीचे की रेखा) को मुक्त करने की आवश्यकता है।

मेरे कोड के आखिरी लाइनों ($ 5) के रूप में इंगित करता है कि जीडीबी का सुंदर प्रिंटर ऑब्जेक्ट की सामग्री को पुनर्स्थापित करने में सक्षम है, भले ही ऑब्जेक्ट की स्मृति प्रक्रिया द्वारा अधिक समय तक कब्जा न हो। कारण यह हो सकता है कि प्रिंटर लगभग हर मेमोरी पते के साथ ऐसा कर सकता है और जब किसी अन्य प्रक्रिया ने इस जगह पर कुछ लिखा नहीं था (हमने पहले कुछ सेकंड पहले कब्जा कर लिया था) तो हमें वही परिणाम मिलेंगे जब मुफ्त नहीं कहा जाता था।

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

1

आप क्या करने की कोशिश कर रहे हैं? यदि आप जीडीबी के साथ क्यूस्ट्रिंग को सुंदर प्रिंट करना चाहते हैं, तो जीडीबी के पायथन सुंदर प्रिंटर एपीआई का उपयोग करें। विवरण के लिए http://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html देखें। आप निम्न प्रकार की पाइथन प्रिंटर क्लास का उपयोग कर सकते हैं:

class QStringPrinter: 
    def __init__(self, val): 
     self.val = val 

    def to_string(self): 
     if self.val['d'] == self.val['shared_null'].address: 
      return 0 

     dataptr = self.val['d']['data'].cast(gdb.lookup_type('char').pointer()) 
     size = self.val['d']['size'] 

     if sys.byteorder == 'little': 
      enc = 'utf_16_le' 
     else: 
      enc = 'utf_16_be' 
     return dataptr.string(enc, 'ignore', size * 2) 

    def display_hint(self): 
     return 'string' 
संबंधित मुद्दे