2013-05-24 6 views
19

मैंने अभी तक साझा पॉइंटर्स पर काम नहीं किया है .. मुझे बस अवधारणा पता है। मैं निम्नलिखित सी ++ वर्ग में फ़ंक्शंस डीबग करने का प्रयास कर रहा हूं, जो एक एक्सएमएल फ़ाइल का डेटा संग्रहीत करता है (xerces लाइब्रेरी के माध्यम से रीड-इन)।जीडीबी में, मैं कुछ वर्ग कार्यों को कॉल कर सकता हूं, लेकिन अन्य "हल नहीं किए जा सकते"। क्यूं कर?

// header file 
class ParamNode; 
typedef boost::shared_ptr<ParamNode> PtrParamNode; 

class ParamNode : public boost::enable_shared_from_this<ParamNode> { 
public: 
    ... 
    typedef enum { DEFAULT, EX, PASS, INSERT, APPEND } ActionType; 
    bool hasChildren() const; 
    PtrParamNode GetChildren(); 
    PtrParamNode Get(const std::string& name, ActionType = DEFAULT); 
protected: 
    .... 
    ActionType defaultAction_; 
} 

अब अगर मैं जिसमें मैं वर्ग ParamNode सूचक का एक उदाहरण है कोड का एक टुकड़ा डिबगिंग कर रहा हूँ, और यह paramNode_

PtrParamNode paramNode_; 
// read xml file with xerces 
paramNode_ = xerces->CreateParamNodeInstance(); 
// now, the xml data is stored in paramNode_. 
std::string probGeo; 
// this works in the code, but not in (gdb)!! 
paramNode_->Get("domain")->GetValue("gt",probGeo); 
cout << probGeo << endl; // <-- breakpoint HERE 

कहा जाता है gdb का उपयोग करते हुए मैं paramNode_ निरीक्षण कर रहा हूँ वस्तु:

(gdb) p paramNode_ 
$29 = {px = 0x295df70, pn = {pi_ = 0x2957ac0}} 
(gdb) p *paramNode_.px 
$30 = { 
    <boost::enable_shared_from_this<mainclass::ParamNode>> = {weak_this_ = {px = 0x295df70, pn = {pi_ = 0x2957ac0}}}, 
    _vptr.ParamNode = 0x20d5ad0 <vtable for mainclass::ParamNode+16>, 
    ... 
    name_= {...}, 
    children_ = {size_ = 6, capacity_ = 8, data_ = 0x2969798}, 
    defaultAction_ = mainclass::ParamNode::EX, } 

और प्रिंट अपने सदस्यों:

012,
(gdb) ptype *paramNode_.px 
type = class mainclass::ParamNode : public boost::enable_shared_from_this<mainclass::ParamNode> { 
    protected: 
    ... 
    mainclass::ParamNode::ActionType defaultAction_; 
    public: 
    bool HasChildren(void) const; 
    mainclass::PtrParamNode GetChildren(void); 
    mainclass::PtrParamNode Get(const std::string &, mainclass::ParamNode::ActionType); 

हालांकि, मैं केवल कार्यों HasChildren या GetChildren कॉल कर सकते हैं, एक त्रुटि में Getgdb से परिणाम बुला जबकि: कोड में

(gdb) p (paramNode_.px)->HasChildren() 
$7 = true 
(gdb) p (paramNode_.px)->GetChildren() 
$8 = (mainclass::ParamNodeList &) @0x295dfb8: { 
    size_ = 6, 
    capacity_ = 8, 
    data_ = 0x29697a8 
    } 
(gdb) p (paramNode_.px)->Get("domain") 
Cannot resolve method mainclass::ParamNode::Get to any overloaded instance 
(gdb) set overload-resolution off 
(gdb) p (paramNode_.px)->Get("domain") 
One of the arguments you tried to pass to Get could not be converted to what the function wants. 
(gdb) p (paramNode_.px)->Get("domain", (paramNode_.px).defaultAction_) 
One of the arguments you tried to pass to Get could not be converted to what the function wants. 

, Get("domain") फ़ंक्शन को निष्पादित बस ठीक काम करता है। ऐसा क्यों है? साझा प्वाइंटर्स के सीमित ज्ञान के कारण, यदि आप अपने उत्तर में स्पष्टीकरण शामिल करते हैं तो मैं आभारी हूं।

+1

शायद इसका 'साझा_ptr' से कोई लेना देना नहीं है। हो सकता है कि 'gdb'' 'डोमेन' '('const char [7]' को कन्वर्ट नहीं कर सकता है,' const std :: string & '('अस्थायी' std :: स्ट्रिंग का निर्माण करके ') रनटाइम पर। मेरे पास हाथ में 'gdb' नहीं है, लेकिन मेरा सुझाव है कि आप' std :: size_t f (const std :: string & s) {return s.length() जैसे बहुत ही सरल कोड के साथ प्रयास करें; } ', फिर gdb 'p f (" हैलो ")' और शायद 'p f (std :: string (" हैलो "))', यह देखने के लिए कि क्या आपको अभी भी त्रुटि मिलती है। –

+0

अच्छा विचार। मैंने बस कोशिश की। समारोह 'f' कोड में काम करता है, तथापि,' (gdb) पीएफ ("हैलो") '(gdb) memory.' में नहीं स्थित पर अधिभार संकल्प सेट मूल्य का पता लेने के लिए प्रयास (gdb) पीएफ (" hsdflo ") किसी भी अधिभारित उदाहरण के लिए फ़ंक्शन f को हल नहीं कर सकता है। जीडीबी में 'std: string' का उपयोग करके एक वाक्यविन्यास त्रुटि हुई ... – Sebastian

उत्तर

23

gdb एक कंपाइलर नहीं है, यह आपके लिए (उपयोगकर्ता के लिए) अच्छा उपयोगकर्ता परिभाषित प्रकार रूपांतरण नहीं करेगा। यदि आप एक ऐसा फ़ंक्शन कॉल करना चाहते हैं जो string चाहता है, तो आपको इसे देना होगा, const char* नहीं।

दुर्भाग्य से, gdb कमांड लाइन पर आप के लिए एक std::string का निर्माण नहीं कर सकते, फिर से, क्योंकि यह एक संकलक नहीं है और वस्तु निर्माण एक सरल समारोह कॉल नहीं है।

तो आपको अपने प्रोग्राम में थोड़ा सा सहायक कार्य जोड़ना होगा, जो const char* लेगा और std::string& वापस करेगा। यहां संदर्भ नोट करें। यह मूल्य से वापस नहीं आ सकता है, क्योंकि gdb परिणाम कॉन्स्ट संदर्भ द्वारा परिणाम पारित करने में सक्षम नहीं होगा (यह एक कंपाइलर नहीं है!) आप एक स्थैतिक वस्तु का संदर्भ, या ढेर पर आवंटित ऑब्जेक्ट को वापस लेना चुन सकते हैं। बाद के मामले में यह स्मृति को रिसाव करेगा, लेकिन यह एक बड़ा सौदा नहीं है क्योंकि फ़ंक्शन को केवल डीबगर से ही बुलाया जाना है।

std::string& SSS (const char* s) 
{ 
    return *(new std::string(s)); 
} 

फिर gdb

gdb> p (paramNode_.px)->Get(SSS("domain")) 

में काम करना चाहिए।

+1

हाँ, यह अच्छा सर लग रहा है। मुझे हालांकि सभी तर्कों की आपूर्ति करने की आवश्यकता है ('DEFAULT' दूसरे पैरामीटर को भी आपूर्ति की आवश्यकता है)। '(Gdb) पी (paramNode_.px) -> प्राप्त करें (एसएसएस (" डोमेन ")) समारोह call.' में बहुत कम तर्क। बहरहाल, यह काम करता है:। '(Gdb) पी (paramNode_.px) -> प्राप्त करें (एसएसएस (" डोमेन "), (paramNode_.px) .defaultAction _) पिक्सल $ 28 = (mainclass :: ParamNode *) 0x2969710'। विस्तृत टिप्पणियों के लिए धन्यवाद! इस अतिरिक्त के लिए – Sebastian

8

एक जोड़े को पिछले जवाब देने के लिए जोड़ -

gdb शायद अंत में इस तरह रूपांतरण कैसे करना सीखना होगा। अब यह नहीं हो सकता; लेकिन सी ++ अभिव्यक्ति पार्सिंग के लिए समर्थन में सुधार करने के लिए सक्रिय कार्य है।

gdb डिफ़ॉल्ट तर्कों को भी समझ में नहीं आता है। यह आंशिक रूप से gdb में एक बग है; लेकिन आंशिक रूप से g ++ में एक बग, जो उन्हें DWARF में नहीं छोड़ता है। मुझे लगता है कि डीडब्ल्यूएआरएफ गैर-मामूली डिफ़ॉल्ट तर्कों को उत्सर्जित करने का एक तरीका भी परिभाषित नहीं करता है।

+1

धन्यवाद। क्या आप किसी भी डिबगर्स से अवगत हैं जो पहले से ही ऐसा कर सकते हैं? – Sebastian

7

ऐसी स्थिति में मैं सिर्फ आदेश

set overload-resolution off 
+0

यह अच्छा होगा अगर यह उत्तर थोड़ा आगे बढ़ाया जा सके। इस पैरामीटर को सेट करने से समस्या हल हो जाती है? – allsey87

1

n.m. के जवाब महान है देने के बाद सफलता मिली है, लेकिन अपने कोड को संपादित करने और समाधान Creating C++ string in GDB में दिए गए पर एक नज़र डालें पुन: संयोजित करने के लिए होने से बचाने के।

कि समाधान वे ढेर पर एक std::string के लिए जगह आवंटित करने का प्रदर्शन और फिर एक std::string आरंभ function वे gdb से कॉल करना चाहते हैं में पारित करने के लिए

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

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