[MI] lvalues and variable_editable

Vladimir Prus ghost@cs.msu.su
Wed Jul 11 06:46:00 GMT 2007


On Wednesday 11 July 2007 05:26, Nick Roberts wrote:

>  > Well, ideally if I have a varobj for rvalue structure, I want the children
>  > of such varobj to be reported as non-editable. It does not seem to happen,
>  > IIUC.
> 
> Remember that an rvalue may be an lvalue also.  

I'm not sure what you mean. Technically, lvalue can be converted to
rvalue (per section 4.1 of the C++ standard). As a practical matter,
however, each expression is either assignable-to, or non-assignable


> I think you are saying a varobj 
> with children which aren't lvalues.  How would you create such a varobj?  Note:

Consider the attached program. Then consider this session:

	(gdb)
	b main
	........
	(gdb)
	r
	.........	
	(gdb)
	-var-create F * return_foo()
	^done,name="F",numchild="1",type="foo"
	(gdb)
	-var-list-children F
	^done,numchild="1",children=[child={name="F.public",exp="public",numchild="2"}]
	(gdb)
	-var-list-children F.public
	^done,numchild="2",children=[child={name="F.public.i",exp="i",numchild="0",type="int"},child={name="F.public.j",exp="j",numchild="0",type="int"}]
	(gdb)
	-var-assign F.public.i 10
	&"mi_cmd_var_assign: Could not assign expression to varible object\n"
	^error,msg="mi_cmd_var_assign: Could not assign expression to varible object"
	(gdb)

Clearly, gdb does not like assigning to F.public.i, and I'm pretty sure it's because VALUE_LVAL for
that varobj returns false. Naturally, it's reasonable to expect to have F.public.i marked as non-editable,
so that frontend won't even let the user to assign a value. I don't think your patch will do that.

It should be noted that update of F, above, is broken, but it's broken in an unrelated way.

>  > >  > > *************** varobj_value_is_changeable_p (struct var
>  > >  > > *** 1819,1837 ****
>  > >  > > --- 1822,1842 ----
>  > >  > > 
>  > >  > > type = get_value_type (var);
>  > >  > > 
>  > >  > > +
>  > >  > > switch (TYPE_CODE (type))
>  > >  > > {
>  > >  > > case TYPE_CODE_STRUCT:
>  > >  > > case TYPE_CODE_UNION:
>  > >  > > case TYPE_CODE_ARRAY:
>  > >  > > !     case TYPE_CODE_FUNC:
>  > >  > > !     case TYPE_CODE_METHOD:
>  > >  > > !       return 0;
>  > >  > 
>  > >  > In current gdb, assuming this declaration:
>  > >  > 
>  > >  >         void (*fp)();
>  > >  > 
>  > >  > I can create varobj for *fp:
>  > >  > 
>  > >  >         -var-create V * *fp
>  > >  > 
>  > >  > and V will be updated if fp changes. With your patch,
>  > >  > I get this:
>  > >  > 
>  > >  >         -var-create V * *fp
>  > >  >         ~"varobj.c:2180: internal-error: c_value_of_variable: Assertion `varobj_value_is_changeable_p (var)' failed.\n"
>  > >  >         ~"A problem internal to GDB has been detected,\n"
>  > >  >         ~"further debugging may prove unreliable.\n"
>  > >  >         ~"Quit this debugging session? (y or n) "
>  > > 
>  > > OK.  I had just thought about fp being TYPE_CODE_PTR.
>  > > 
>  > >  > So, probably TYPE_CODE_FUNC should be handled in variable_editable_p.
>  > >  > I'm not sure about TYPE_CODE_METHOD -- I don't know how to construct
>  > >  > an object of that type using any possible expression.
>  > > 
>  > > That's where they came from.  OK, I'll investigate.  It occurs to me that you
>  > > might be create problems with pointers to structs, unions and arrays too.
>  > 
>  > We should not have any problems, because we never try to get varobj->value
>  > for object of struct, union or array type.
> 
> Actually now I've looked at it, I think the problem is in c_value_of_variable.
> I think there should be an extra clause, something like:
> 
> 
>   switch (TYPE_CODE (type))
>     {
> +    case TYPE_CODE_FUNCTION:
> +      return xstrdup ("<function>");
> +      /* break; */
> 
> and a similar one for TYPE_CODE_METHOD, either here or in
> cplus_value_of_variable.  

Such a change will be regression from the current behaviour. Consider the attached program
and the following session:

	(gdb)
	b main
	.....
	(gdb)
	r
	....
	(gdb)
	n
	&"n\n"
	~"8\t    fp = bar;\n"
	^done
	(gdb)
	-var-create F * *fp
	^done,name="F",numchild="0",type="void (void)"
	(gdb)
	-var-evaluate-expression F
	^done,value="{void (void)} 0x80483c4 <foo()>"
	(gdb)
	next
	&"next\n"
	~"9\t    return 0;\n"
	^done
	(gdb)
	-var-update F
	^done,changelist=[{name="F",in_scope="true",type_changed="false"}]
	(gdb)
	-var-evaluate-expression F
	^done,value="{void (void)} 0x80483ca <bar()>"
	(gdb)

Note that the current gdb has no problem whatsoever with printing the value
of function, and it also notices when a value changes. If you change c_value_of_variable
as outlined above, you'll only see "<function>" as output.

> Functions and methods are surely not changeable. 

I think you misunderstand the meaning of varobj_value_is_changeable_p. It does not
indicate if the object itself may be changed, by the programming language or by
gdb user. It indicates if the value of varobj, as printed by -var-evaluate-expression,
may change. As shown above, in current gdb, the value of varobj having type 'function'
can change just fine, in a meaningful way.

If you make gdb print "<function>" for objects of function type, then clearly the
value cannot change, and varobj_value_is_changrable_p can return true for
functions. However, I don't see any reason why printing "<function>" for
object of function type would be better than the current situation. I further suspect
that "*f" above will be rvalue, so it will be reported as non-editable by your patch anyway.

- Volodya
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rvalue.cpp
Type: text/x-c++src
Size: 184 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/gdb-patches/attachments/20070711/f23e7528/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fp.cpp
Type: text/x-c++src
Size: 96 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/gdb-patches/attachments/20070711/f23e7528/attachment-0001.bin>


More information about the Gdb-patches mailing list