Bug 13419

Summary: Unable to pretty-print map of lists
Product: gdb Reporter: Milian Wolff <mail>
Component: miAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED OBSOLETE    
Severity: normal CC: sergiodj, tromey, valentyn.pavliuchenko
Priority: P2    
Version: HEAD   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:

Description Milian Wolff 2011-11-20 22:42:22 UTC
See also: https://bugs.kde.org/show_bug.cgi?id=257834

Compile the following code:

~~~~~~~~~~
#include <map>
#include <list>
#include <string>
using namespace std;

int main()
{
    typedef map<string, list<string> > map_t;
    map_t m;
    m["one"].push_back("a");
    m["one"].push_back("b");
    m["one"].push_back("c");
    m["two"].push_back("1");
    m["two"].push_back("2");
    m["two"].push_back("3");
    map_t::const_iterator i = m.begin();
    i++;
    return 0; // <= break point on this line
              // neither "m" nor "i" are displayed in correct way
}
~~~~~~~~~~~

Now run it and see how it's not possible to get access to the contents of the map of lists in a sane way using the gdb-mi commands:

gdb -i mi ./a.out
break 18 // assumes return 0; is on line 18
-var-create - * m
// now compare this, esp. note the 'value="{...}"'
-var-list-children --all-values var1
// with this
print m
// similarily compare the output of this:
-var-create - * i
// with the output of
print i
Comment 1 Tom Tromey 2012-08-22 17:28:39 UTC
It all seems pretty reasonable to me, but I'm not totally sure
what problem you are seeing.

(gdb) p m
$2 = std::map with 2 elements = {
  ["one"] = std::list = {
    [0] = "a",
    [1] = "b",
    [2] = "c"
  },
  ["two"] = std::list = {
    [0] = "1",
    [1] = "2",
    [2] = "3"
  }
}

That's the baseline.  Now for MI:

(gdb) 
-enable-pretty-printing
^done
(gdb) 
-var-create - * m
^done,name="var1",numchild="0",value="{...}",type="map_t",thread-id="1",displayhint="map",dynamic="1",has_more="1"
(gdb) 
-var-list-children --all-values var1
^done,numchild="4",displayhint="map",children=[child={name="var1.[0]",exp="[0]",numchild="0",value=" \"one\"",type="const std::basic_string<char, std::char_traits<char>, std::allocator<char> >",thread-id="1",displayhint="string",dynamic="1"},child={name="var1.[1]",exp="[1]",numchild="0",value="{...}",type="std::list<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >",thread-id="1",dynamic="1"},child={name="var1.[2]",exp="[2]",numchild="0",value=" \"two\"",type="const std::basic_string<char, std::char_traits<char>, std::allocator<char> >",thread-id="1",displayhint="string",dynamic="1"},child={name="var1.[3]",exp="[3]",numchild="0",value="{...}",type="std::list<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >",thread-id="1",dynamic="1"}],has_more="0"


A few things to note here.

First, dynamic varobjs must be handled differently from ordinary ones.
This is why the MI client has to request them.
It is usually wrong to request all the children, you should request just
a range of them.  Otherwise you can be overwhelmed with data, like if
the user tries to show a vector with millions of elements.

In this output, the display hint tells the MI client some useful info.
In particular it says that var1.[0] is a key, var1.[1] is an element, etc.

I'm not sure why this doesn't list the children of var1.[1] -- I don't
know if that is a dynamic/static varobj difference, or just the norm,
or even if it is intended.  But in any case it is easy to ask for
the children of var1.[1]:

-var-list-children --all-values var1.[1] 
^done,numchild="3",children=[child={name="var1.[1].[0]",exp="[0]",numchild="0",value=" \"a\"",type="std::basic_string<char, std::char_traits<char>, std::allocator<char> >",thread-id="1",displayhint="string",dynamic="1"},child={name="var1.[1].[1]",exp="[1]",numchild="0",value=" \"b\"",type="std::basic_string<char, std::char_traits<char>, std::allocator<char> >",thread-id="1",displayhint="string",dynamic="1"},child={name="var1.[1].[2]",exp="[2]",numchild="0",value=" \"c\"",type="std::basic_string<char, std::char_traits<char>, std::allocator<char> >",thread-id="1",displayhint="string",dynamic="1"}],has_more="0"


The "{...}" thing is unfortunate.  It was requested by the MI maintainer
when dynamic varobjs were written.  In most cases I think it doesn't matter
much; but perhaps we can change it someday.

Could you maybe say what in the above is causing problems?
Comment 2 Sergio Durigan Junior 2014-09-12 23:05:45 UTC
Closing as OBSOLETE due to inactivity.  Feel free to reopen if still valid.