Re: MI: type prefixes for values

Jim Ingham
2006-04-06T16:05:46Z

On Apr 6, 2006, at 6:45 AM, Vladimir Prus wrote:

> On Thursday 06 April 2006 17:35, Daniel Jacobowitz wrote:
>> On Thu, Apr 06, 2006 at 05:03:25PM +0400, Vladimir Prus wrote:
>>> I was thinking about this more, and still not 100% sure how Xcode
>>> can do
>>> this. Do you mean that Xcode takes a stack trace when the varobj was
>>> created, and deletes varobj whenever it sees that stack became
>>> shorter?
>>>
>>> The case I'm not sure about is this:
>>>
>>> 1. main calls 'a' which calls 'b' which bits breakpoint.
>>> 2 varobj is created for local var of 'b'
>>> 3. Users says 'continue'.
>>> 4. 'b' exists and then 'a' calls 'b' again and breakpoint is
>>> hit again.
>>>
>>> However, this second time it's not guaranteed that stack frame of
>>> 'b' is
>>> at the same address as it was the last time -- maybe 'a' has pushed
>>> something on stack. How do you detect this case?
>>
>> Either b's stack frame is at the same address - in which case the
>> varobj is still valid - or else it isn't, in which case the frame id
>> has changed.
>
> I did not know that GDB exposes frame ID in any way, and Jim has
> mentioned
> that it's XCode that does the magic, not gdb. Is there some command
> to print
> frame id that I've missed?

gdb does know what stack frame a variable is bound to. But gdb
doesn't do any cleanup of variable objects on it's own. That's up to
the MI client. I am pretty sure that is what I was referring to.

>
>>>> Note, however, that the varobj's do remember their frames, so if
>>>> you
>>>> tried to evaluate one that was no longer on the stack, the varobj
>>>> would report "out of scope".
>>>
>>> Would be great to add this in FSF version.
>>
>> It's already there:
>>
>> /* The frame for this expression */
>> struct frame_id frame;
>>
>> c_value_of_root will always fail if the frame is gone.
>
> Sorry, does not seems to work this way here. For the following
> program:
>
> void foo()
> {
> int i = 10;
> ++i;
> }
>
> int main()
> {
> foo();
> }
>
> I get this session:
>
> (gdb)
> -break-insert a.cpp:5
> ^done,bkpt={......
> (gdb)
> -exec-run
> ^running
> (gdb)
> *stopped,reason="breakpoint-hit",frame=
> {addr="0x080483a1",func="foo"
> (gdb)
> -var-create TMP * i
> ^done,name="TMP",numchild="0",type="int"
> (gdb)
> -var-evaluate-expression TMP
> ^done,value="10"
> (gdb)
> -exec-finish
> ^running
> (gdb)
> *stopped,reason="function-finished",frame=
> {addr="0x080483bd",func="main",
> (gdb)
> -var-evaluate-expression TMP
> ^done,value="10"
> (gdb)
>
> There's no indication that 'TMP' varobj belongs to the stack frame
> we've
> already left. This is with vanilla 6.4.
>

-var-evaluate-expression just fetches the data for the expression as
it was last computed. As such, it doesn't know in or out of scope.
It's -var-update, which recomputes the variable's value. So if you
add on to your example:

-var-update TMP
^done,changelist=[varobj={name="TMP",in_scope="false"}]

This is for the Apple gdb, BTW, I don't have a Linux box handy so I'm
not sure what the FSF gdb would print out, but the logic would be the
same.

Jim