public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* RFC: how to handle mutable types in varobj?
@ 2011-12-28 16:13 Joel Brobecker
  2011-12-29 11:13 ` Joel Brobecker
  2012-01-02 21:03 ` Tom Tromey
  0 siblings, 2 replies; 7+ messages in thread
From: Joel Brobecker @ 2011-12-28 16:13 UTC (permalink / raw)
  To: gdb-patches, vladimir; +Cc: Tom Tromey

Hello,

I'd like to discuss how mutable types should be handled in varobj.
Here is one example involving Ada, but perhaps some other languages
have them too. So, consider the case of a variant record, declared
as follow:

   type Variant (Disc : Boolean := True) is
   record
      A : Integer;
      case Disc is
         when True =>
            Yes : Boolean;
            No : Boolean;
         when False =>
            D : Integer;
      end case;
   end record;

This is a record where the number of components depends on the value
of the discriminant (`Disc' in this case). If the discrimant is True,
it has 4 components: `Disc', `A', as well as `Yes' and `No'. But if
the discriminant is False, it only has 3 components now: `Disc' and
`A', as before, and now `D'.

The trouble with varobj starts when the value of the discriminant
changes during the lifetime of the variable, which is legal in this
case.  If I create a varobj with a variable whose discrimant is True,
then step a few lines until the discriminant changes, and then request
an update,  what should happen? In particular, if I had also listed
the varobj's children, what should happen of them?

In this situation, we go from a varobj with 4 children, to a varobj
with 3 children, 2 of them still having the same type, two old
children having disappeared, and one new child having appeared.

At the front-end level, what should we display at the end of the
-var-update command? We have several elements to consider:

  (1) The root varobj itself
      I imagine that this varobj should be listed in the changed list.
      As far as I can tell from the documentation, probably with
      the `type_changed' attribute, and probably the new number of
      children.

  (2) The "unchanged" children `Disc' and `A', whose type have changed.

  (3) The children varobj that have now disappeared.
      Should the front-end be told somehow that they have disappeared?
      Or do they infer this from the `type_changed' attribute?

  (4) The new children varobj
      I don't think they should be listed in the changed list,
      since their value is new.

The thing is, I am wondering if we should include any of the varobj's
children at all. Whether listing (1) with `type_changed' would be
sufficient.

Purely based on the reading of the documentation and then the code,
I think that mutable types haven't been considered in the original
design - although perhaps the authors of the original design aren't
around anymore. It also seems that support for Python pretty-printing
has been crafted on to varobj, and indirectly introduced the notion
of dynamicity, which is probably similar in some ways to our mutability.
But I am also guessing that this support was implemented in a way
that kept things compatible at the GDB/MI level. As a result, I am
having a hard time building a good overal picture of how things work,
partly because there are so many flags: children_requested, from, to,
type_changed, updated, changedm children_changed, etc.

Rather than redesign the whole thing, I am wondering if we can
expand a little bit on the Python dynamic properties and create
the notion of mutability that we could use for both types that
have a pretty-printer as well as types that are genuinely mutable.

Thoughts?

Thanks!
-- 
Joel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: how to handle mutable types in varobj?
  2011-12-28 16:13 RFC: how to handle mutable types in varobj? Joel Brobecker
@ 2011-12-29 11:13 ` Joel Brobecker
  2012-01-02 15:43   ` Pedro Alves
  2012-01-02 21:03 ` Tom Tromey
  1 sibling, 1 reply; 7+ messages in thread
From: Joel Brobecker @ 2011-12-29 11:13 UTC (permalink / raw)
  To: gdb-patches, vladimir; +Cc: Tom Tromey

[-- Attachment #1: Type: text/plain, Size: 2972 bytes --]

> 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,
-- 
Joel

[-- Attachment #2: ada-type-mutation.diff --]
[-- Type: text/x-diff, Size: 5406 bytes --]

commit d75d746f839bf5a6e022cc8b7bfe1725345036e5
Author: Joel Brobecker <brobecker@adacore.com>
Date:   Thu Dec 29 11:39:06 2011 +0400

    Prototype of Ada value type-mutation.

diff --git a/gdb/varobj.c b/gdb/varobj.c
index 88f356c..b26e109 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -1759,6 +1759,87 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
 #endif
 }
 
+/* FIXME: Should be a language_specific attribute?  For now, it's just
+   used as a prototype.  It cannot be made language-independent, because
+   it needs to get the number of children and their names solely from
+   the new varobj *value*.  Perhaps the problem could be solved by
+   creating a temporary anonymous varobj for the varobj's new value?
+   But then, there is the question whether mutation is a concept that
+   remains the same for all languages.  It seems a shame to be going
+   through this for languages such as C, where there are clearly no
+   type mutations the way they occur in Ada.
+
+   This function should be able to assume that:
+     - The varobj has a value;
+     - The varobj's number of children is set (not < 0);
+     - NEW_VALUE is not NULL.
+   */
+
+static int
+ada_varobj_value_has_mutated (struct varobj *var, struct value *new_val)
+{
+  int i, from, to;
+
+  /* If the number of fields have changed, then for sure the type
+     has mutated.  */
+  if (ada_varobj_get_number_of_children (new_val) != var->num_children)
+    return 1;
+
+  /* If the number of fields have remained the same, then we need
+     to check the name of each field.  If they remain the same,
+     then chances are the type hasn't mutated.  This is technically
+     an incomplete test, as the child's type might have changed
+     despite the fact that the name remains the same.  But we'll
+     handle this situation by saying that the child has mutated,
+     not this value.
+
+     If only part (or none!) of the children have been fetched,
+     then only check the ones we fetched.  It does not matter
+     to the frontend whether a child that it has not fetched yet
+     has mutated or not. So just assume it hasn't.  */
+
+  restrict_range (var->children, &from, &to);
+  for (i = from; i < to; i++)
+    if (strcmp (ada_varobj_get_name_of_child (var->value, var->name, i),
+		VEC_index (varobj_p, var->children, i)->name) != 0)
+      return 1;
+
+  return 0;
+}
+
+/* If NEW_VALUE is the new value of the given varobj (var), return
+   non-zero if var has mutated.  In other words, if the type of
+   the new value is different from the type of the varobj's old
+   value.
+
+   NEW_VALUE may be NULL, if the varobj is now out of scope.  */
+
+static int
+varobj_value_has_mutated (struct varobj *var, struct value *new_value)
+{
+  /* If there was no previous value, it probably means that our varobj
+     was out of scope.  This is a scoping-change issue, handled
+     elsewhere, which makes the detection of mutations unnecessary.
+     Same if NEW_VALUE is NULL.  */
+  if (var->value == NULL || new_value == NULL)
+    return 0;
+
+  /* If we haven't previously computed the number of children in var,
+     it does not matter from the front-end's perspective whether
+     the type has mutated or not.  For all intents and purposes,
+     it has not mutated.
+
+     FIXME: Do we need to check var->from & var->to?  I cannot seem
+     to convince myself that this is independent of num_children.  */
+  if (var->num_children < 0)
+    return 0;
+
+  if (var->root->lang->language == vlang_ada)
+    return ada_varobj_value_has_mutated (var, new_value);
+  else
+    return 0;
+}
+
 /* Update the values for a variable and its children.  This is a
    two-pronged attack.  First, re-parse the value for the root's
    expression to see if it's changed.  Then go all the way
@@ -1853,9 +1934,24 @@ varobj_update (struct varobj **varp, int explicit)
       /* Update this variable, unless it's a root, which is already
 	 updated.  */
       if (!r.value_installed)
-	{	  
+	{
+	  int has_mutated;
+
 	  new = value_of_child (v->parent, v->index);
-	  if (install_new_value (v, new, 0 /* type not changed */))
+	  has_mutated = varobj_value_has_mutated (v, new);
+
+	  if (has_mutated)
+	    {
+	      /* The children are no longer valid; delete them now.
+	         Report the fact that its type changed as well.  */
+	      varobj_delete (v, NULL, 1 /* only_children */);
+	      v->num_children = -1;
+	      v->to = -1; /* FIXME: Is that necessary?  */
+	      v->from = -1;
+	      r.type_changed = 1;
+	    }
+
+	  if (install_new_value (v, new, r.type_changed))
 	    {
 	      r.changed = 1;
 	      v->updated = 0;
@@ -2543,7 +2639,23 @@ value_of_root (struct varobj **var_handle, int *type_changed)
       *type_changed = 0;
     }
 
-  return (*var->root->lang->value_of_root) (var_handle);
+  {
+    struct value *value;
+
+    value = (*var->root->lang->value_of_root) (var_handle);
+    if (varobj_value_has_mutated (var, value))
+      {
+	/* The type has mutated, so the children are no longer valid.
+	   Just delete them, and tell our caller that the type has
+	   changed.  */
+	varobj_delete (var, NULL, 1 /* only_children */);
+	var->num_children = -1;
+	var->to = -1; /* FIXME: Is that necessary?  */
+	var->from = -1;
+	*type_changed = 1;
+      }
+    return value;
+  }
 }
 
 /* What is the ``struct value *'' for the INDEX'th child of PARENT?  */

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: how to handle mutable types in varobj?
  2011-12-29 11:13 ` Joel Brobecker
@ 2012-01-02 15:43   ` Pedro Alves
  2012-01-02 16:22     ` Joel Brobecker
  0 siblings, 1 reply; 7+ messages in thread
From: Pedro Alves @ 2012-01-02 15:43 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches, vladimir, Tom Tromey

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..

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: how to handle mutable types in varobj?
  2012-01-02 15:43   ` Pedro Alves
@ 2012-01-02 16:22     ` Joel Brobecker
  2012-01-02 16:48       ` Pedro Alves
  0 siblings, 1 reply; 7+ messages in thread
From: Joel Brobecker @ 2012-01-02 16:22 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches, vladimir, Tom Tromey

Hi Pedro,

Thanks for the feedback. Do you mean that the changes you are talking
about are already in the tree? My interpretation of the current code
was that python pretty-printing was implemented a little ad hoc,
almost as an exception to the normal varobjs... That's why I am
a little confused by the process your went through. That being said,
It's been a few days since I looked at the code, and it took me a long
time to start understanding the code better. I might simply still be
missing many things - I need to study the code again in detail to comment
in detail.

In the meantime:

> 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?

GDB would set the dynamic property, right? That would work for me.

> 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...).

Agreed!

> That said, if you don't want to go that way, it's fine with me.  Just
> putting it out there..

I would like to do what's right once and for all :-). Of course,
if the "right thing" is costing too much effort, then I might look
for compromises.  But for now, I am still looking for guidance in
terms of the varobj interface itself, and achieve compliance.

For instance, I had imagined the case where some children of a varobj
that has mutated might still be around. But unlike you, I thought I'd
keep it as simple as possible to start, so if it was sufficient to
just reset all the children, well that is an easy thing to do :-).

-- 
Joel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: how to handle mutable types in varobj?
  2012-01-02 16:22     ` Joel Brobecker
@ 2012-01-02 16:48       ` Pedro Alves
  0 siblings, 0 replies; 7+ messages in thread
From: Pedro Alves @ 2012-01-02 16:48 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches, vladimir, Tom Tromey

On 01/02/2012 04:21 PM, Joel Brobecker wrote:
> Hi Pedro,
>
> Thanks for the feedback. Do you mean that the changes you are talking
> about are already in the tree?

No sorry.  I was talking about changes that were never posted.

> My interpretation of the current code
> was that python pretty-printing was implemented a little ad hoc,
> almost as an exception to the normal varobjs... That's why I am
> a little confused by the process your went through. That being said,
> It's been a few days since I looked at the code, and it took me a long
> time to start understanding the code better. I might simply still be
> missing many things - I need to study the code again in detail to comment
> in detail.
>
> In the meantime:
>
>> 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?
>
> GDB would set the dynamic property, right? That would work for me.

Yeah, something like that, but I think it'll need a bit more than
just one line setting a flag.

>
>> 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...).
>
> Agreed!
>
>> That said, if you don't want to go that way, it's fine with me.  Just
>> putting it out there..
>
> I would like to do what's right once and for all :-). Of course,
> if the "right thing" is costing too much effort, then I might look
> for compromises.  But for now, I am still looking for guidance in
> terms of the varobj interface itself, and achieve compliance.
>
> For instance, I had imagined the case where some children of a varobj
> that has mutated might still be around. But unlike you, I thought I'd
> keep it as simple as possible to start, so if it was sufficient to
> just reset all the children, well that is an easy thing to do :-).

It may well be the best in the end.  Let me see if we can get
them to you, so you can see and decide whether it's a path you
want to take.

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: how to handle mutable types in varobj?
  2011-12-28 16:13 RFC: how to handle mutable types in varobj? Joel Brobecker
  2011-12-29 11:13 ` Joel Brobecker
@ 2012-01-02 21:03 ` Tom Tromey
  2012-01-03 17:11   ` Joel Brobecker
  1 sibling, 1 reply; 7+ messages in thread
From: Tom Tromey @ 2012-01-02 21:03 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches, vladimir

>>>>> "Joel" == Joel Brobecker <brobecker@adacore.com> writes:

Joel> Purely based on the reading of the documentation and then the code,
Joel> I think that mutable types haven't been considered in the original
Joel> design

Yeah, I agree.  The weird access protection stuff makes me think that
perhaps C++ also wasn't considered -- IMNSHO this should be represented
via attributes on the various fields, not phony intermediate varobjs.

Joel> It also seems that support for Python pretty-printing
Joel> has been crafted on to varobj, and indirectly introduced the notion
Joel> of dynamicity, which is probably similar in some ways to our mutability.
Joel> But I am also guessing that this support was implemented in a way
Joel> that kept things compatible at the GDB/MI level. As a result, I am
Joel> having a hard time building a good overal picture of how things work,
Joel> partly because there are so many flags: children_requested, from, to,
Joel> type_changed, updated, changedm children_changed, etc.

The spaghetti is at least partly my fault.  Sorry about that.
TBH I found hacking varobj to be quite difficult.

You are right that dynamic varobjs were introduced to maintain
compatibility.  If the client does not send -enable-pretty-printing,
then no dynamic varobj will ever be created.  The idea is that dynamic
varobjs require some special client handling, so clients have to
explicitly request them.

Joel> The careful reader will also notice that I'm having trouble with
Joel> figuring out some invariants regarding the `from' and `to' fields
Joel> with respect to the `num_children' field... More stuff to be figured
Joel> out later...

'from' and 'to' are set by the MI client.  See -var-list-children and
-var-set-update-range.  I think these only really make sense for dynamic
varobjs, but maybe they work with any varobj, I don't recall.

I don't remember how 'num_children' is used any more.

Pedro> So, I factored out the "listing dynamic varobj's
Pedro> children" code behind a common interface, making use of a new
Pedro> iterator "virtual" object (struct varobj_iter), and reimplemented
Pedro> both pretty-printing varobjs and available-children-only varobjs using
Pedro> that same interface.

Sounds nice.

Pedro> Implementing Ada mutable types support through this would mean mutable
Pedro> varobjs would be exposed as dynamic=1 varobjs.  I'm not sure that'd be
Pedro> a problem?  With frontends that currently support dynamic varobjs,
Pedro> things should simply work.

I think the only caveat is that it has to be requested.
But, presumably Joel has a particular client in mind.
And, anyway, clients not supporting dynamic varobjs are really missing out.

Pedro> Non dynamic varobjs were kind of a mistake
Pedro> anyway (a !dynamic varobj that is bound to an 10000000 element array
Pedro> is wholly fetched in gdb memory at once...).

Yeah.

Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: how to handle mutable types in varobj?
  2012-01-02 21:03 ` Tom Tromey
@ 2012-01-03 17:11   ` Joel Brobecker
  0 siblings, 0 replies; 7+ messages in thread
From: Joel Brobecker @ 2012-01-03 17:11 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, vladimir

> Pedro> So, I factored out the "listing dynamic varobj's
> Pedro> children" code behind a common interface, making use of a new
> Pedro> iterator "virtual" object (struct varobj_iter), and reimplemented
> Pedro> both pretty-printing varobjs and available-children-only varobjs using
> Pedro> that same interface.
> 
> Sounds nice.

I haven't had time to look at this lately. But it does sound nice.
On the other hand, Pedro's answers gave me an idea that sounds
obvious in retrospect. I tested how floating varobjs work in C:

I have two struct types, where the first couple of fields have
the same name and type. The last two change from one location
to the next. At the first location, I did:

  | -var-create v @ v
  | ^done,name="v",numchild="4",value="{...}",type="struct variant_1",thread-id="1",has_more="0"
  | (gdb) 
  | -var-list-children 1 v
  | ^done,numchild="4",children=[child={name="v.disc",exp="disc",numchild="0",value="1",type="int",thread-id="1"},child={name="v.a",exp="a",numchild="0",value="2",type="int",thread-id="1"},child={name="v.b",exp="b",numchild="0",value="3",type="int",thread-id="1"},child={name="v.c",exp="c",numchild="0",value="5",type="int",thread-id="1"}],has_more="0"

And then resumed the execution until reaching the second location,
where a -var-update * yields:

  | -var-update 1 v
  | ^done,changelist=[{name="v",value="{...}",in_scope="true",type_changed="true",new_type="struct variant_2",new_num_children="4",has_more="0"}]

As you can see, all children of v have disappeared.

So, as long as the front-end does not make the extra assumption
that type-changes only occur with floating varobjs, a first step
at implementing mutations could be done that way.

In the light of this, do you guys think that a patch along the lines
of what I sent would be acceptable?

    http://www.sourceware.org/ml/gdb-patches/2011-12/msg00886.html

The gist of the change is a language-specific hook, and a couple of
blobs (one for root value, one for children values) that test for
mutation, and destroy children if detected.

As a second phase, we could try designing a little better how
dynamic objects behave. But I'd rather do something simple first,
familiarize myself with that, and then move on to a more difficult
project.

> I think the only caveat is that it has to be requested.

Another element that makes me think it's better to start simple
first.

> But, presumably Joel has a particular client in mind.

It's an Eclipse client. I'm not very familiar with any of them,
so I don't know how many instantiations of that project there are
out there.

I will check with the other engineer at AdaCore who looks at
this side of things, to see how he would react to non-floating
varobjs that mutate...

Cheers,
-- 
Joel

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-01-03 17:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-28 16:13 RFC: how to handle mutable types in varobj? Joel Brobecker
2011-12-29 11:13 ` Joel Brobecker
2012-01-02 15:43   ` Pedro Alves
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).