From: Pedro Alves <alves.ped@gmail.com>
To: Joel Brobecker <brobecker@adacore.com>
Cc: gdb-patches@sourceware.org, vladimir@codesourcery.com,
Tom Tromey <tromey@redhat.com>
Subject: Re: RFC: how to handle mutable types in varobj?
Date: Mon, 02 Jan 2012 15:43:00 -0000 [thread overview]
Message-ID: <4F01D098.6050206@gmail.com> (raw)
In-Reply-To: <20111229111024.GT23376@adacore.com>
On 12/29/2011 11:10 AM, Joel Brobecker wrote:
>> I'd like to discuss how mutable types should be handled in varobj.
>
> It turns out to be a little simpler than I thought, assuming my
> understanding of the GDB/MI varobj interface is right:
>
> If a varobj mutated, whether a root varobj or not, it should be
> listed in the change list as a "type_changed". However, all its
> children varobjs are simply destroyed without further ado, and
> they will not be listed in the change list. This means that we
> expect the front-end to understand that children varobjs of
> a varobj that has mutated are invalid, and thus automatically
> destroyed.
>
> With the attached prototype, this is what I get.
>
> (1) First, creating the varobj and listing its children:
>
> | -var-create v * v
> | ^done,name="v",numchild="4",value="{...}",type="pck.variant",has_more="0"
> | (gdb)
> | -var-list-children 1 v
> | ^done,numchild="4",children=[child={name="v.disc",exp="disc",numchild="0",value="true",type="boolean"},[snip]],has_more="0"
> | (gdb)
>
> (2) Second, doing an update after some changes in the value, but
> no mutation (only field "a" in our variant record changed):
>
> | -var-update v
> | ^done,changelist=[{name="v.a",in_scope="true",type_changed="false",has_more="0"}]
> | (gdb)
>
> (3) Lastly, doing an update after the value mutated. This time,
> we see that varobj simply reports that the value has mutated
> (type_changed="true"), and just provides the number number of
> children:
>
> | -var-update v
> | ^done,changelist=[{name="v",in_scope="true",type_changed="true",new_type="pck.variant",new_num_children="3",has_more="0"}]
> | (gdb)
>
> The prototype cannot be applied as is, as it needs to be applied
> on top of some other changes that are work-in-progress. But it
> should give a good idea of how I proceeded.
>
> The good thing is that this is fairly localized. I'm also wondering
> whether this might be done without a language-dependent hook (see
> the first FIXME of ada_varobj_value_has_mutated's description).
> Perhaps create_child_with_value could solve my practical problem?
> I haven't gone that far yet. I also tried testing the case where
> it's a child rather than the root that mutates, but for some reason
> the child is not properly described (in a sense similar to what
> c_describe_child does), and thus I miss the mutation. So that
> feature is untested, but it's just because of a bug I will chase
> ASAP.
>
> The unfortunate part, though, is that this is done somewhat in
> parallel of the work done to handle pretty-printers. I think it
> kind of makes sense that pretty-printers should take precedence
> over this treatment. So, I'm somewhat thinking that it's better
> that way. I haven't had time to verify that precedence is respected,
> however. I just wanted to send the patch for comment...
>
> The careful reader will also notice that I'm having trouble with
> figuring out some invariants regarding the `from' and `to' fields
> with respect to the `num_children' field... More stuff to be figured
> out later...
>
> Thanks,
This (the problem being addressed, not the solution) sounds similar to
a change I wrote for tracepoints -- augment -var-list-children to list
only children that have been partially or completely collected.
But instead of always deleting children, I taught varobjs to handle
the case of new children appearing at an index before other children,
compared to the previous update. E.g.,
with 'struct { int a; int b; } g;', if at first, only g.b was
available, but the next traceframe contains both g.a and g.b, that
is detected, and g.a is shown as a new child in a
"-var-update". While working on it, I realized
that varobj's that are filtering some of the children only, aren't
that different from pretty-printed dynamic varobj's. That is, we needed
a method to get at the "next" available child; we have no random access
to children. The "num_child" field isn't always trustable as
consequence. We want to be able to tell the frontend that the number
of children changed --- the existing "new_num_children" output field
(invented for python varobjs) (*) of -var-update fit the bill
perfectly. In terms of code, I was ending up mirroring the python
pretty-printed varobjs code in a lot of places, e.g.,
update_dynamic_varobj_children, and the more I fixed my code, the
more I realized that the new code I was adding should be exactly
like the python dynamic varobjs code.
So, I factored out the "listing dynamic varobj's
children" code behind a common interface, making use of a new
iterator "virtual" object (struct varobj_iter), and reimplemented
both pretty-printing varobjs and available-children-only varobjs using
that same interface.
I think that was the right decision. Frontends don't need to
learn anything anew, if they already support pretty-printed
dynamic varobjs (other than knowing to request a listing of only
collected fields, rather than the whole object). And a bunch of code is
shared between those varobj kinds, reducing maintenance burden.
(*) Note that the "new_num_children" attribute being output
indicates that the children list changed. The manual says:
"@item new_num_children
For a dynamic varobj, if the number of children changed, or if the
type changed, this will be the new number of children.
The @samp{numchild} field in other varobj responses is generally not
valid for a dynamic varobj -- it will show the number of children that
@value{GDBN} knows about, but because dynamic varobjs lazily
instantiate their children, this will not reflect the number of
children which may be available.
The @samp{new_num_children} attribute only reports changes to the
number of children known by @value{GDBN}. This is the only way to
^^^^^^^^^^^^^^^^^^^^^^^
detect whether an update has removed children (which necessarily can
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
only happen at the end of the update range)."
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Implementing Ada mutable types support through this would mean mutable
varobjs would be exposed as dynamic=1 varobjs. I'm not sure that'd be
a problem? With frontends that currently support dynamic varobjs,
things should simply work. Non dynamic varobjs were kind of a mistake
anyway (a !dynamic varobj that is bound to an 10000000 element array
is wholly fetched in gdb memory at once...). That said, if you don't
want to go that way, it's fine with me. Just putting it out there..
next prev parent reply other threads:[~2012-01-02 15:43 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-28 16:13 Joel Brobecker
2011-12-29 11:13 ` Joel Brobecker
2012-01-02 15:43 ` Pedro Alves [this message]
2012-01-02 16:22 ` Joel Brobecker
2012-01-02 16:48 ` Pedro Alves
2012-01-02 21:03 ` Tom Tromey
2012-01-03 17:11 ` Joel Brobecker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4F01D098.6050206@gmail.com \
--to=alves.ped@gmail.com \
--cc=brobecker@adacore.com \
--cc=gdb-patches@sourceware.org \
--cc=tromey@redhat.com \
--cc=vladimir@codesourcery.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox