[英]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).
我正在尝试调试以下c ++类中的函数,该类存储XML文件的数据(通过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_;
}
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_
现在,如果我正在调试一段代码,其中我有一个指向类
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
Using gdb
I'm inspecting the paramNode_
object: 使用
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, }
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: 但是,我只能调用函数
HasChildren
或GetChildren
,而从gdb
调用Get
导致错误:
(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. 在代码中,执行
Get("domain")
函数可以正常工作。 Why is that? 这是为什么? I'm thankful if you include explanations in your answer, due to my limited knowledge of shared pointers.
如果你在答案中包含解释,我很感谢,因为我对共享指针的了解有限。
gdb
is not a compiler, it will not do the (not-so-)nice user-defined type conversions for you. gdb
不是编译器,它不会为您执行(不那么)良好的用户定义类型转换。 If you wish to call a function that wants a string
, you need to give it a string
, not a const char*
. 如果你想调用一个想要
string
的函数,你需要给它一个string
,而不是一个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. 不幸的是,
gdb
不能在命令行上为你构造一个std::string
,因为它不是一个编译器而且对象创建不是一个简单的函数调用。
So you will have to add a little helper function to your program, that would take a const char*
and return an std::string&
. 所以你必须为你的程序添加一个小辅助函数,这将需要一个
const char*
并返回一个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. 它不能按值返回,因为
gdb
将无法通过const引用传递结果(它不是编译器!)您可以选择返回对静态对象的引用,或者返回到堆上分配的对象。 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
gdb> p (paramNode_.px)->Get(SSS("domain"))
should work. 应该管用。
在这种情况下,我只是在发出命令后取得了成功
set overload-resolution off
A couple additions to the previous answer -- 前一个答案的几个补充 -
gdb will probably eventually learn how to do conversions like this. gdb最终可能会学习如何进行这样的转换。 It can't now;
它现在不能; but there is active work on improving support for C++ expression parsing.
但是正在积极努力改进对C ++表达式解析的支持。
gdb doesn't understand default arguments, either. gdb也不了解默认参数。 This is partly a bug in gdb;
这部分是gdb中的一个错误; but also partly a bug in g++, which doesn't emit them into the DWARF.
但也部分是g ++中的一个错误,它不会将它们发送到DWARF中。 I think DWARF doesn't even define a way to emit non-trivial default arguments.
我认为DWARF甚至没有定义一种发出非平凡的默认参数的方法。
nm's answer is great, but to avoid having to edit your code and recompile take a look at the solution given in Creating C++ string in GDB . nm的答案很棒,但为了避免编辑代码并重新编译,请查看GDB中创建C ++字符串中给出的解决方案。
In that solution they demonstrate allocating space for a std::string
on the heap and then initializing a std::string
to pass into the function
they'd like to call from gdb
. 在该解决方案中,他们演示了在堆上为
std::string
分配空间,然后初始化std::string
以传递给他们想要从gdb
调用的function
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.