Re: Questions about MI variable objects

Jim Ingham
2007-05-25T18:42:13Z

Adding a little complexity to the issue... We implemented flyover
variables using the varobj system. In that case, you can't just say
"show me variable "x" in the current scope, because if you have:

void foo ()
{
int x = 5;

printf ("Here I got %d\n", x);

{
int x = 6;
printf ("Here I got %d\n", x); /* Break here */
}
}

and the pc is at the second printf, but the user points at "x" in the
first printf, you want to show "5" and not "6". We extended this by
adding a "+" form of the varobj that accepts either an address or a
file:line specification, and looks up the varobj in the current frame,
restricted to the block surrounding that address.

We also had a problem showing global & static variables with this
frame stuff. Suppose you want to make a varobj for a global
variable. Obviously you can't use the * form - you don't want the
global to go out of scope ever... You could try to use the @ form,
but then when you went to update it, if the frame you were currently
in had a variable of the same name it would shadow the global, and the
wrong value would get printed. You could cons up some
"function:varname" or "file:varname" form, but that is a RPITA. So we
added another varobj type "NO_FRAME_NEEDED". When we make one of the
"+" style varobj's we use the NO_FRAME_NEEDED if we find the match in
the static or global block.

Turns out we didn't need to add an explicit character for the
NO_FRAME_NEEDED, however. Instead, we added commands to list the
statics & globals from a given function or file or shlib. That's the
way Xcode usually gets it's hands on this sort of thing.

BTW, even though we use the "@" form for our "expressions" window in
general, one case where it would be useful to use the "*" form instead
is if you had a deep recursive stack with gnarly big structures (that
you have to turn out pretty far to inspect the good parts) in the
recurring functions.

Then it would be useful to put the version of one of the gnarly
variables from frame 35 in the expressions window, another from frame
0, and then compare them at leisure. If you've ever tried to do this
by flipping back & forth in the stack, you will see the benefit of
this. To do this well you'd have to add some UI to the expressions
window to identify the scope each variable was tacked to. This
wouldn't be too hard, and could be handy in some cases.

Jim

On May 25, 2007, at 10:11 AM, Jim Blandy wrote:

>
> Vladimir Prus <ghost@cs.msu.su> writes:
>>> Suppose I'm stopped where the stack is like this:
>>>
>>> main -> foo (2) -> foo (1) -> foo (0)
>>>
>>> Suppose the top frame is selected, and the user adds a display for
>>> 'x'. Clearly, it should show '0'.
>>
>> You're using an ill-defined term "adds a display".
>
> Well, sure. I'm asking people to tell me about all the GUIs they work
> on, so I can't use specific language.
>
>>> 4) If the user lets control run to 'foo' again, so the stack now
>>> looks
>>> like:
>>>
>>> main -> bar (10) -> foo (9)
>>>
>>> what should happen to the display of 'x'? (I'd say it should show
>>> '9'.)
>>
>> I agree.
>>
>> I think that @-variable-object should behave as described above.
>
> Right; I wasn't aware of '@'-frame varobjs when I originally wrote,
> since they're not documented.
>
>> Note also that it's possible to imagine GUI commands that show a
>> value of some expression in particular "scope", and became
>> forever grayed out when that scope dies. It raises numerous
>> questions how to identify scopes. It should be noted that KDevelop
>> does not have such UI command, and it was never requested.
>
> Yeah, it doesn't seem too useful.
>
>>> The principle behind my guesses is that a display should refer to a
>>> particular variable in the source code --- a particular declaration
>>> --- and should show its value whenever that declaration is in
>>> scope in
>>> the selected frame. This is less specific than having the display
>>> refer to a particular frame's instance of that variable, and more
>>> specific than having it refer to any variable that happens to be in
>>> scope under that name. But it's what I'd expect from a GUI.
>>
>> This seem to contradict your claim that in 'bar', we should show '9'
>> for 'x' -- it's different 'x', after all.
>
> You misread --- I said we should show '9' in the first call to foo
> from bar.
>
>> Assume user asked to show value of "x+y". There are three
>> alternatives:
>>
>> 1. Show value of that expression in specific frame, gray it out
>> otherwise.
>> 2. Show value of that expression in current frame, provided "x" and
>> "y"
>> refer to the same language declaration.
>> 3. Show value of that expression in current frame.
>>
>> (3) is what implemented by @-varobjs. You seem to propose (2),
>> which will only differ from (2) by the fact that sometimes (3) will
>> show
>> a value and (2) will have value greyed. Is this big enough deal to
>> worry about?
>
> Yes, that is the distinction. If it's not important to GUI
> implementors, then it's certainly not a big enough deal to worry
> about.
>
>> As for (1), it's implemented by ordinary varobjs.
>
> Except for the frame collision behavior which I demonstrated, yes.