This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
Python/MI/STL visualization
- From: Vladimir Prus <vladimir at codesourcery dot com>
- To: gdb at sourceware dot org
- Date: Wed, 23 Apr 2008 00:06:54 +0400
- Subject: Python/MI/STL visualization
Hi,
I've just implement the logic for computing the children of MI varobj
using Python scripts. Using the attached .gdbinit, I can do the following:
-var-create V * v
^done,name="V",numchild="1",value="{...}",type="std::vector<int,std::allocator<int> >"
(gdb)
-var-set-visualizer V VectorVisualizer
^done
(gdb)
-var-list-children --all-values V
^done,numchild="2",children=[
child={name="V.0",exp="0",numchild="0",value="1",type="int"},
child={name="V.1",exp="1",numchild="0",value="2",type="int"}]
Previously, we discussed how to best report the case where the number of children of
varobj changes. The approach I've implemented is for -var-update to report the varobj
that had the number of children changed, and include the new 'children' attribute
for that varobj. So, if I had a vector of 1 element and push another other, I get
this:
-var-update V
^done,changelist=[{name="V",in_scope="true",type_changed="false",
children=[{name="V.0",exp="0",numchild="0",type="int"},
{name="V.1",exp="1",numchild="0",type="int"}]}]
I like this approach because it does not assume that children are added or removed
at back -- if the list of children change, we report the entire new list, and can
put new varobj in the middle.
On Python level, visualization is handled by a Python class instance -- one instance
per varobj. This approach, as opposed to a function, allows Python code to do
whatever caching it sees fit.
Of course, there are quite some issues and questions:
1. Vectors can get large, and getting them can get slow. Do we want to have
incremental fetch of some kind? On UI level, I'm thinking of something
like KDevelop's incremental fetch of frames, see
http://vladimir_prus.blogspot.com/2007/02/debugger-stories-stack-widget.html
But we also need MI level support.
2. Presumably, it's better to automatically assign visualizers to varobjs
of specific types. What's the best way to specify 'all vectors'. Does
using regexps seem good enough?
3. One can have vector of vectors. However, present code requires the visualizers
be explicitly set for each element of the outer vector. Should be have some way to
set visualizers on all future children of a given varobj? I'm not quite sure
how std::map will be presented, but probably we will have children of different
types. Then, should we have a way to set visualizers on all future children of
specific type.
4. We still have the problem that GCC debug information will say that variable
exists even before the constructor for that variable has run. So, creating
robust visualizer is rather hard. Anybody knows if we can workaround this?
I think even comparing declaration line with the current line is better than
nothing.
- Volodya
python
class StringVisualizer:
def to_string (self, v):
# FIXME: catch any exceptions accessing bogus memory
data = v.element ("_M_dataplus")
return str (data.element ("_M_p"))
class VectorVisualizer:
def children (self, v):
result = []
impl = v.element ('_M_impl')
start = impl.element ('_M_start')
finish = impl.element ('_M_finish')
current = start
index = 0
while not current.equals(finish):
result.append((str(index), current.dereference()))
current = current.increment(1)
index = index + 1
return result
end