简体   繁体   English

在gdb中,我可以调用一些类函数,但其​​他函数“无法解析”。 为什么?

[英]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: 但是,我只能调用函数HasChildrenGetChildren ,而从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.

相关问题 为什么GDB找不到一些按名字反汇编的函数? - Why can't GDB find some functions to disassemble by name? 为什么我可以从子类调用私有函数 - Why can I call private functions from a sub class 为什么 GDB 中的某些内存地址看起来比其他内存地址短? - Why do some memory addresses in GDB appear shorter than others? LNK2019在某些类函数上,但不在其他类函数上(dll中的模板类) - LNK2019 on some class functions, but not on others (template class in dll) 为什么我可以静态调用实例函数? - Why can I call instance functions statically? 我如何可移植地调用C ++函数,该函数在某些平台上采用char **而在其他平台上采用const char **? - How can I portably call a C++ function that takes a char** on some platforms and a const char** on others? 可以说爸爸类有两个子对象类。 如何将这些子项彼此调用? C ++ - Lets say dad class have two child object class. How can call functions these childs from each others ? C++ C ++无法调用某些函数 - C++ cannot call some functions 为什么在!= / ==和&amp;&amp; / ||时gdb不能评估函数 结合在一个表达式? - Why can't gdb evaulate functions when !=/== and &&/|| are combined in an expression? 无法转换某些类,但其他可以。 C ++ - Cannot convert some classes but others can. C++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM