2009-10-14 87 views
1

我知道它在strcmp失敗。我在下面提供了運算符<,它調用了strcmp。幫忙解釋這個棧跟蹤

在行#1上有值@ 0xbfffeeac。 @是什麼意思?

#0 0x00212bd8 in strcmp() from /lib/libc.so.6 
#1 0x0012ed2f in Json::Value::CZString::operator< (this=0x8317300, [email protected]) 
    at src/lib_json/json_value.cpp:221 
#2 0x001361b0 in std::less<Json::Value::CZString>::operator() (this=0x83173a0, [email protected], 
    [email protected]) 
    at /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/stl_function.h:230 
#3 0x00136101 in std::_Rb_tree<Json::Value::CZString, std::pair<Json::Value::CZString const, Json::Value>, std::_Select1st<std::pair<Json::Value::CZString const, Json::Value> >, std::less<Json::Value::CZString>, std::allocator<std::pair<Json::Value::CZString const, Json::Value> > >::_M_lower_bound (this=0x83173a0, 
    __x=0x83172f0, __y=0x83173a4, [email protected]) 
    at /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/stl_tree.h:986 
#4 0x001348da in std::_Rb_tree<Json::Value::CZString, std::pair<Json::Value::CZString const, Json::Value>, std::_Select1st<std::pair<Json::Value::CZString const, Json::Value> >, std::less<Json::Value::CZString>, std::allocator<std::pair<Json::Value::CZString const, Json::Value> > >::find (this=0x83173a0, [email protected]) 
    at /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/stl_tree.h:1421 
#5 0x0013383a in std::map<Json::Value::CZString, Json::Value, std::less<Json::Value::CZString>, std::allocator<std::pair<Json::Value::CZString const, Json::Value> > >::find (this=0x83173a0, [email protected]) 
    at /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/stl_map.h:659 
#6 0x00131779 in Json::Value::operator[] (this=0x8317280, key=0xbfffef74 "col1") 
    at src/lib_json/json_value.cpp:1055 
#7 0x00131ba8 in Json::Value::isMember (this=0x8317280, key=0xbfffef74 "col1") 
    at src/lib_json/json_value.cpp:1169 
#8 0x0805cf4d in CFG::CFG_Fetch_Raw (this=0x825846c, section=0x8317280, key=0xbfffef74 "col1", defval=0x0) 
    at CFG.cpp:48 
#9 0x08050e5b in Generic::CFGSetup (this=0x825846c, k=0x8255e2c "display_qt") at Generic.cpp:89 
#10 0x0804df6a in LCDControl::ConfigSetup (this=0xbffff2a8) at LCDControl.cpp:81 
#11 0x0804d93b in LCDControl::Start (this=0xbffff2a8, argc=1, argv=0xbffff404) at LCDControl.cpp:15 
#12 0x0804f224 in main (argc=1, argv=0xbffff404) at Main.cpp:7 

bool 
Value::CZString::operator<(const CZString &other) const 
{ 
    if (cstr_) 
     return strcmp(cstr_, other.cstr_) < 0; //src/lib_json/json_value.cpp:221 
    return index_ < other.index_; 
} 

回答

2

您正在檢查this->cstr_爲空,但您並未檢查other.cstr_。也許容器會阻止任何插入了值爲空的字符串,所以這樣的檢查是不必要的。

然而,這不是問題,因爲在這種情況下其他不是空。相反,它看起來像other對象可能已被刪除。你如何管理std::map容器中物體的生命週期?有沒有可能其中一個值在未從地圖中刪除的情況下被刪除?

更新:

在進一步的檢查,這似乎是關鍵:

#5 0x0013383a in std::map<...>::find (this=0x83173a0, [email protected]) 
#6 0x00131779 in Json::Value::operator[] (this=0x8317280, key=0xbfffef74 "col1") 

你傳遞一個常量字符串指針(0xbfffef74,這顯然是有效的,因爲調試器顯示字符串),它會自動轉換爲CZString類型的臨時值。您可以看到臨時的CZString對象被忠實地傳遞到operator<

我認爲0x8...地址指示堆分配,而0xbf...地址指示堆棧分配。

不幸的是,我們需要看到的是strcmp()的參數。我們需要知道,當CZString::operator<被稱爲0xbfffeeac(臨時CZString對象)的「其他」參數時,它是否將原始字符串值0xbfffef74轉換爲strcmp,或者可能是該字符串的堆分配副本不知道CZString在內部做什麼)。

如果這是b-tree搜索中的第一個比較,那可能表示strcmp的第二個參數未正確轉換爲CZString。否則,它表示第二個參數正確傳遞,並且映射中的一個字符串是無效的,但不是空的,留下「已刪除」和「未空終止」作爲可能的嫌疑人。

+0

是的,你說得對。看起來像庫中的一個bug。謝謝。 – Scott 2009-10-14 01:22:56

+0

@Scott其實我在回答之前意外提交了。我不認爲空檢查(或缺乏)與* this *問題有關,只是它可能是* a *問題。 – 2009-10-14 01:30:37

+0

嗯,我剛剛發了一封電子郵件給jsoncpp的郵件列表,裏面提到了你剛纔陳述的內容。我會跟進你的其他評論。 – Scott 2009-10-14 01:33:30

0

也許strcmp在運行時等接收到意外的值。只是一個想法,對不起,如果我錯了。

1

@ 0xbfffeeac看起來像一個特殊值,可能未初始化的內存?我只是猜測,但@符號可以放在那裏,以指示內存地址指向一個特殊格式的值來表示未初始化的內存?

+0

這就是我在想什麼。我不確定這意味着什麼。我將不得不搜索GDB文檔。 – Scott 2009-10-14 01:26:26

+0

我相信'@'表示參數是給定地址的引用,而不是指針。 – 2009-10-14 01:31:26

+0

有趣的是,如果你是google @ 0xbfffeeac,那麼當他們的軟件崩潰時,你會收到許多觀察這個地址的人的點擊。 – 2009-10-14 01:32:38

1

@符號表示該參數是通過引用傳遞的。

爲了幫助理解程序的內存映射,例如數據段與堆棧中的地址是什麼,請在gdb下嘗試info files。另外,由於您在Linux下運行,請檢查cat /proc/<pid>/maps的輸出。