2009-10-14 53 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的输出。