From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7396 invoked by alias); 22 Apr 2008 20:07:18 -0000 Received: (qmail 7142 invoked by uid 22791); 22 Apr 2008 20:07:17 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 22 Apr 2008 20:07:00 +0000 Received: (qmail 18087 invoked from network); 22 Apr 2008 20:06:57 -0000 Received: from unknown (HELO localhost) (vladimir@127.0.0.2) by mail.codesourcery.com with ESMTPA; 22 Apr 2008 20:06:57 -0000 From: Vladimir Prus To: gdb@sourceware.org Subject: Python/MI/STL visualization Date: Wed, 23 Apr 2008 07:46:00 -0000 User-Agent: KMail/1.9.6 (enterprise 0.20070907.709405) MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_fVkDIcc8yAXvKPu" Message-Id: <200804230006.55278.vladimir@codesourcery.com> Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2008-04/txt/msg00192.txt.bz2 --Boundary-00=_fVkDIcc8yAXvKPu Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 2750 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 >" (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 --Boundary-00=_fVkDIcc8yAXvKPu Content-Type: text/x-java; charset="utf-8"; name=".gdbinit" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=".gdbinit" Content-length: 646 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 --Boundary-00=_fVkDIcc8yAXvKPu--