[英]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);
但是,我只能調用函數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.
在代碼中,執行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.