Bug 13419 - Unable to pretty-print map of lists
Summary: Unable to pretty-print map of lists
Status: RESOLVED OBSOLETE
Alias: None
Product: gdb
Classification: Unclassified
Component: mi (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-11-20 22:42 UTC by Milian Wolff
Modified: 2014-09-12 23:05 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
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.