簡體   English   中英

在gdb中,我可以調用一些類函數,但其​​他函數“無法解析”。 為什么?

[英]In gdb, I can call some class functions, but others “cannot be resolved”. Why?

我還沒有參與共享指針..我只知道這個概念。 我正在嘗試調試以下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_;
}

現在,如果我正在調試一段代碼,其中我有一個指向類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, }

並打印其成員:

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

但是,我只能調用函數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.

在代碼中,執行Get("domain")函數可以正常工作。 這是為什么? 如果你在答案中包含解釋,我很感謝,因為我對共享指針的了解有限。

gdb不是編譯器,它不會為您執行(不那么)良好的用戶定義類型轉換。 如果你想調用一個想要string的函數,你需要給它一個string ,而不是一個const char*

不幸的是, gdb不能在命令行上為你構造一個std::string ,因為它不是一個編譯器而且對象創建不是一個簡單的函數調用。

所以你必須為你的程序添加一個小輔助函數,這將需要一個const char*並返回一個std::string& 請注意這里的參考。 它不能按值返回,因為gdb將無法通過const引用傳遞結果(它不是編譯器!)您可以選擇返回對靜態對象的引用,或者返回到堆上分配的對象。 在后一種情況下,它會泄漏內存,但這不是什么大問題,因為該函數無論如何都只能從調試器調用。

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

然后在gdb

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

應該管用。

在這種情況下,我只是在發出命令后取得了成功

set overload-resolution off

前一個答案的幾個補充 -

gdb最終可能會學習如何進行這樣的轉換。 它現在不能; 但是正在積極努力改進對C ++表達式解析的支持。

gdb也不了解默認參數。 這部分是gdb中的一個錯誤; 但也部分是g ++中的一個錯誤,它不會將它們發送到DWARF中。 我認為DWARF甚至沒有定義一種發出非平凡的默認參數的方法。

nm的答案很棒,但為了避免編輯代碼並重新編譯,請查看GDB創建C ++字符串中給出的解決方案。

在該解決方案中,他們演示了在堆上為std::string分配空間,然后初始化std::string以傳遞給他們想要從gdb調用的function

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM