Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In gdb, I can call some class functions, but others "cannot be resolved". Why?

I have not worked on shared pointers yet .. I just know the concept. I'm trying to debug functions in the following c++ class, which stores data of an XML file (read-in via the xerces library).

// 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_; } 

Now if I'm debugging a piece of code in which I have an instance of the pointer to the class ParamNode, and it's called 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 

Using gdb I'm inspecting the paramNode_ object:

(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, } 

and print its members:

(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); 

However, I can only call the functions HasChildren or GetChildren, whereas calling Get from gdb results in an error:

(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. 

In the code, executing the Get("domain") function works just fine. Why is that? I'm thankful if you include explanations in your answer, due to my limited knowledge of shared pointers.

like image 278
Sebastian Avatar asked May 24 '13 12:05

Sebastian


People also ask

Can you call functions in gdb?

To call a function in the program, GDB has to temporarily modify the state of the inferior. This has potentially undesired side effects. Also, having GDB call nested functions is likely to be erroneous and may even crash the program being debugged.

How do I go to a specific function in gdb?

To execute one line of code, type "step" or "s". If the line to be executed is a function call, gdb will step into that function and start executing its code one line at a time. If you want to execute the entire function with one keypress, type "next" or "n".


2 Answers

gdb is not a compiler, it will not do the (not-so-)nice user-defined type conversions for you. If you wish to call a function that wants a string, you need to give it a string, not a const char*.

Unfortunately, gdb cannot construct an std::string for you on the command line, again because it is not a compiler and object creation is not a simple function call.

So you will have to add a little helper function to your program, that would take a const char* and return an std::string&. Note the reference here. It cannot return by value, because then gdb will not be able to pass the result by const reference (it's not a compiler!) You can choose to return a reference to a static object, or to an object allocated on the heap. In the latter case it will leak memory, but this is not a big deal since the function is meant to be called only from the debugger anyway.

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

Then in gdb

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

should work.

like image 73
n. 1.8e9-where's-my-share m. Avatar answered Sep 28 '22 17:09

n. 1.8e9-where's-my-share m.


In such a situation I just had success after giving the command

set overload-resolution off 
like image 27
rwst Avatar answered Sep 28 '22 15:09

rwst