views:

166

answers:

4

I know that it fails at strcmp. I've provided operator< below, which calls strcmp.

On line #1 there's the value @0xbfffeeac. What does the @ mean?

#0  0x00212bd8 in strcmp () from /lib/libc.so.6
#1  0x0012ed2f in Json::Value::CZString::operator< (this=0x8317300, other=@0xbfffeeac)
    at src/lib_json/json_value.cpp:221
#2  0x001361b0 in std::less<Json::Value::CZString>::operator() (this=0x83173a0, __x=@0x8317300, 
    __y=@0xbfffeeac)
    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, __k=@0xbfffeeac)
    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, __k=@0xbfffeeac)
    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, __x=@0xbfffeeac)
    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_;
}
A: 

Perhaps strcmp is receiving unexpected values at run-time, or something. Just an idea, sorry if I'm wrong.

Jorge Israel Peña
+2  A: 

You're checking this->cstr_ for null, but you're not checking other.cstr_. Perhaps the container prevents any strings with null cstr_ values from being inserted, so such a check is not necessary.

That's not the problem, however, since other is not null in this case. Rather it looks like the other object may have been deleted. How are you managing the lifetimes of the objects in the std::map container? Is it possible that one of the values was deleted without being removed from the map?

Update:

On further inspection, this seems to be the key:

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

You're passing in a constant string pointer (0xbfffef74, which is obviously valid since the debugger displays the string), and it's being automatically converted into a temporary value of type CZString. You can see that the temporary CZString object is faithfully passed all the way down to the operator<.

I believe that the 0x8... addresses indicate heap allocations, while 0xbf... addresses indicate stack allocations.

Unfortunately, what we need to see is the arguments to strcmp(). We need to know if, when CZString::operator< was called with an "other" argument of 0xbfffeeac (the temporary CZString object), whether it passed the original string value of 0xbfffef74 into strcmp, or perhaps a heap-allocated copy of that string (I don't know what CZString does internally).

If this is the first comparison in the b-tree search, that probably indicates that the second argument to strcmp was not correctly converted to a CZString. Otherwise, it indicates that the second argument is being passed down correctly, and one of the strings in your map is invalid but not null, leaving "deleted" and "not null-terminated" as likely suspects.

Tim Sylvester
Yeah, you're right. Looks like a bug in the library. Thanks.
Scott
@Scott Actually I accidentally submitted before I was done answering. I don't think that the null check (or lack thereof) has anything to do with *this* problem, only that it might be *a* problem.
Tim Sylvester
Well, I just sent an email out to jsoncpp's mailing list about it pointing out what you stated at first. I'll follow up with your other comments.
Scott
I tried to provide libc's debug info. I made sure glib-debuginfo and glibc-debuginfo-common were installed before launching gdb for the provided stack trace. They were already installed.
Scott
I found the problem. I freed a pointer in the wrong scope. The index of col tipped me off. It should have been col0.
Scott
+1  A: 

@0xbfffeeac looks like a special value, maybe uninitialized memory ? I am just guessing, but could the @ symbol be put there to indicate the memory address points to a specially formatted value to indicate uninitialized memory ?

Andrew Keith
That's sort of what I was thinking. I'm not sure what it means. I'll have to search the GDB docs.
Scott
I believe that the `@` indicates that the parameter is a reference to the given address, rather than a pointer.
Tim Sylvester
interesting, if you google @0xbfffeeac, you get alot of hits from people observing this address when their software crashed.
Andrew Keith
+1  A: 

The @ symbol denotes that the parameter was passed by reference.

For help understanding the memory map of your program, e.g. what addresses are in a data segment versus on the stack, try info files under gdb. Also, since you're running under Linux, check out the output of cat /proc/<pid>/maps.

David Joyner