* Understanding GDB frames
@ 2007-05-21 22:24 Maxim Grigoriev
2007-05-21 23:28 ` Ross Morley
` (3 more replies)
0 siblings, 4 replies; 40+ messages in thread
From: Maxim Grigoriev @ 2007-05-21 22:24 UTC (permalink / raw)
To: gdb, Marc Gauthier, Pete MacLiesh, Ross Morley
I experience some difficulties in finding a precise definition
of gdb frames.
Any help on choosing the right answer among the list provided
by me at the end of this message will be highly appreciated.
QUESTION
========
The program (frame.c) is
#include <stdio.h>
int frame_number = 1;
int f11(int b)
{
int a;
printf("f11() frame number %d\n", frame_number++);
a = b + 1;
b--;
if (b != 0)
{
printf("f11() will be called recursively\n");
f11(b);
}
return a; /* <-- BP set here. */
}
int f1(int a)
{
return f11(a);
}
int main()
{
int a = 1;
int i;
for (i = 0; i <2; i++)
a = f11(a);
a = f11(1);
a = f1(1);
return 0;
}
The gdb command file "CMD":
break frame.c:18
run
continue
continue
continue
continue
kill
quit
was used to run a gdb session like this :
gdb <executable> --command=CMD
Let's define that "frames A and B are the same" if
frame_id_eq ( A->this_id, B->this_id ) == true
The breakpoit has been set at line 18 and hit 5 times.
Execution control has been subsequently taken by
gdb in five frames numbered 1, 2, 3, 4, and 5.
According to the definition of GDB frames,
which statement is correct ?
ANSWERS
=======
1) All frames 1, 2, 3, 4, and 5 are the same;
2) All frames 1, 2, 3, 4, and 5 are different from each other;
3) Frames 1,2, and 4 are the same. Frames 3 and 5 are
different from 1, 2, 4 and from each other;
4) It's implementation-dependent. While doing architecture ports,
people decide how to implement frame_id-related functions
to compare frames;
5) Other ( explanation would be appreciated ).
-- Maxim
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-21 22:24 Understanding GDB frames Maxim Grigoriev
@ 2007-05-21 23:28 ` Ross Morley
2007-05-22 2:05 ` Nick Roberts
2007-05-22 1:40 ` Joel Brobecker
` (2 subsequent siblings)
3 siblings, 1 reply; 40+ messages in thread
From: Ross Morley @ 2007-05-21 23:28 UTC (permalink / raw)
To: Maxim Grigoriev; +Cc: gdb, Marc Gauthier, Pete MacLiesh
There is another interesting case where I think GDB might have
an issue, and that is best illustrated using Maxim's previous
test case with a modified version of f11(), say f12().
int f11(int b)
{
int a;
a = b + 1;
return a; /* <- BP set here. */
}
int f12(int b)
{
int a;
while (b < 3)
{
a = b + 1;
b = a; /* <- BP set here. */
}
return a;
}
int main()
{
int a = 1;
a = f11(a);
a = f11(a);
a = f12(1);
return a;
}
Best compile with -O0 to ensure the loop isn't optimized out.
Compare the two iterations of the loop in f12() with the two
calls to f11(). For the calls to f11(), each has a separate
instantiation of the frame and thus (strictly speaking) has a
separate frame and a separate instance of var 'a'. In the two
iterations of f12(), the frame is the same one set up at the
beginning of the single call, and 'a' is the same variable.
In both cases, the PC and SP are the same.
How can GDB tell the difference? (using the return address
instead of the PC in identifying the frame is one way, but
then one only needs to go one level deeper to defeat it).
Does GDB need to tell the difference?
GDB confronts a similar issue with watchpoints on local vars.
It uses a special scope breakpoint to detect the return of the
function and thus detect the watched variable going out of
scope. That mechanism is not used for MI variables. Is that
because the extra overhead is tolerable if a watchpoint is
set but not otherwise?
Should scoping of MI vars be treated the same as watched vars?
Ross
Maxim Grigoriev wrote:
> I experience some difficulties in finding a precise definition
> of gdb frames.
>
> Any help on choosing the right answer among the list provided
> by me at the end of this message will be highly appreciated.
>
> QUESTION
> ========
>
> The program (frame.c) is
>
> #include <stdio.h>
>
> int frame_number = 1;
>
> int f11(int b)
> {
> int a;
>
> printf("f11() frame number %d\n", frame_number++);
>
> a = b + 1;
> b--;
> if (b != 0)
> {
> printf("f11() will be called recursively\n");
> f11(b);
> }
> return a; /* <-- BP set here. */
> }
>
> int f1(int a)
> {
> return f11(a);
> }
>
> int main()
> {
> int a = 1;
> int i;
>
> for (i = 0; i <2; i++)
> a = f11(a);
>
> a = f11(1);
> a = f1(1);
>
> return 0;
> }
>
> The gdb command file "CMD":
>
> break frame.c:18
> run
> continue
> continue
> continue
> continue
> kill
> quit
>
> was used to run a gdb session like this :
> gdb <executable> --command=CMD
>
> Let's define that "frames A and B are the same" if
>
> frame_id_eq ( A->this_id, B->this_id ) == true
>
> The breakpoit has been set at line 18 and hit 5 times.
> Execution control has been subsequently taken by
> gdb in five frames numbered 1, 2, 3, 4, and 5.
>
> According to the definition of GDB frames,
> which statement is correct ?
>
> ANSWERS
> =======
>
> 1) All frames 1, 2, 3, 4, and 5 are the same;
> 2) All frames 1, 2, 3, 4, and 5 are different from each other;
> 3) Frames 1,2, and 4 are the same. Frames 3 and 5 are
> different from 1, 2, 4 and from each other;
> 4) It's implementation-dependent. While doing architecture ports,
> people decide how to implement frame_id-related functions
> to compare frames;
> 5) Other ( explanation would be appreciated ).
>
> -- Maxim
>
>
>
>
>
>
>
>
>
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-21 22:24 Understanding GDB frames Maxim Grigoriev
2007-05-21 23:28 ` Ross Morley
@ 2007-05-22 1:40 ` Joel Brobecker
2007-05-22 2:29 ` Daniel Jacobowitz
2007-05-22 18:37 ` Jim Blandy
3 siblings, 0 replies; 40+ messages in thread
From: Joel Brobecker @ 2007-05-22 1:40 UTC (permalink / raw)
To: Maxim Grigoriev; +Cc: gdb, Marc Gauthier, Pete MacLiesh, Ross Morley
If my understanding of the frame code is correct, then the only
thing that is really guaranteed is that the frame ID remains
constant throughout the lifetime of its associated frame, or
function call. The rest is implementation-dependent.
In practice, I think most targets implement the frame ID as a tuple
that contains one stack address (usually the address on the stack
of the function frame), and one code address (usually the address
of the first instruction for that function). So two consecutive
calls to the same function from the same caller would usually
result in the same frame ID being computed for these two calls.
But this is not guaranteed, for instance if the compiler elected
to adjust the stack for whatever reason between the two function
calls.
IA64 is slighly more complicated, because it also has to take
into account the fact that it has a register stack. So the frame
ID tuple also includes a non-zero "special addr".
Hope this helps. Others will correct me if I'm wrong.
--
Joel
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-21 23:28 ` Ross Morley
@ 2007-05-22 2:05 ` Nick Roberts
2007-05-22 2:31 ` Daniel Jacobowitz
0 siblings, 1 reply; 40+ messages in thread
From: Nick Roberts @ 2007-05-22 2:05 UTC (permalink / raw)
To: Ross Morley; +Cc: Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh
> Compare the two iterations of the loop in f12() with the two
> calls to f11(). For the calls to f11(), each has a separate
> instantiation of the frame and thus (strictly speaking) has a
> separate frame and a separate instance of var 'a'. In the two
> iterations of f12(), the frame is the same one set up at the
> beginning of the single call, and 'a' is the same variable.
> In both cases, the PC and SP are the same.
>
> How can GDB tell the difference? (using the return address
> instead of the PC in identifying the frame is one way, but
> then one only needs to go one level deeper to defeat it).
>
> Does GDB need to tell the difference?
>
> GDB confronts a similar issue with watchpoints on local vars.
> It uses a special scope breakpoint to detect the return of the
> function and thus detect the watched variable going out of
> scope. That mechanism is not used for MI variables. Is that
> because the extra overhead is tolerable if a watchpoint is
> set but not otherwise?
Watchpoints are different to variable objects in that they stop execution,
when their value changes, for example. Presumably when the vlaue is being
monitored, so too can the scope. Variable objects are only updated (if
requested) after execution has already stopped.
> Should scoping of MI vars be treated the same as watched vars?
As watchpoints? I don't think so. A closer analogy to variable objects
is the "display" command. There, GDB allows expressions to come back into
scope.
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-21 22:24 Understanding GDB frames Maxim Grigoriev
2007-05-21 23:28 ` Ross Morley
2007-05-22 1:40 ` Joel Brobecker
@ 2007-05-22 2:29 ` Daniel Jacobowitz
2007-05-22 18:37 ` Jim Blandy
3 siblings, 0 replies; 40+ messages in thread
From: Daniel Jacobowitz @ 2007-05-22 2:29 UTC (permalink / raw)
To: Maxim Grigoriev; +Cc: gdb, Marc Gauthier, Pete MacLiesh, Ross Morley
On Mon, May 21, 2007 at 03:24:04PM -0700, Maxim Grigoriev wrote:
> Let's define that "frames A and B are the same" if
>
> frame_id_eq ( A->this_id, B->this_id ) == true
>
> The breakpoit has been set at line 18 and hit 5 times.
> Execution control has been subsequently taken by
> gdb in five frames numbered 1, 2, 3, 4, and 5.
>
> According to the definition of GDB frames,
> which statement is correct ?
>
> ANSWERS
> =======
>
> 1) All frames 1, 2, 3, 4, and 5 are the same;
> 2) All frames 1, 2, 3, 4, and 5 are different from each other;
> 3) Frames 1,2, and 4 are the same. Frames 3 and 5 are
> different from 1, 2, 4 and from each other;
> 4) It's implementation-dependent. While doing architecture ports,
> people decide how to implement frame_id-related functions
> to compare frames;
> 5) Other ( explanation would be appreciated ).
The correct answer, in my opinion, is that all of these frames are
different. It is likely that when you compare their frame IDs, all of
those representing a call of f11 from main will have the same frame
ID - you can't always compare two arbitrary frame IDs if you don't
know where they came from, and it's impossible to get this 100%
correct without slowing down the execution of the program, so some of
them may be indistinguishable.
The frame ID is supposed to indicate which one of a set of currently
running frames you're looking at. Maybe if we have varobjs for a
specified frame ID, we should insert a scope breakpoint at the exit of
that frame to mark those varobjs as invalid.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 2:05 ` Nick Roberts
@ 2007-05-22 2:31 ` Daniel Jacobowitz
2007-05-22 2:51 ` Nick Roberts
2007-05-22 8:40 ` Ross Morley
0 siblings, 2 replies; 40+ messages in thread
From: Daniel Jacobowitz @ 2007-05-22 2:31 UTC (permalink / raw)
To: Nick Roberts
Cc: Ross Morley, Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh
On Tue, May 22, 2007 at 02:05:35PM +1200, Nick Roberts wrote:
> As watchpoints? I don't think so. A closer analogy to variable objects
> is the "display" command. There, GDB allows expressions to come back into
> scope.
I don't think that allowing varobjs to come back into scope this way
is really useful.
There's a different sort of scope that does make sense - a varobj
might come in and out of lexical scope while its frame is live, due to
optimization. But once the frame has gone we should recreate the
varobjs, or else we should associate them with the function instead of
the frame.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 2:31 ` Daniel Jacobowitz
@ 2007-05-22 2:51 ` Nick Roberts
2007-05-22 10:58 ` Daniel Jacobowitz
2007-05-22 8:40 ` Ross Morley
1 sibling, 1 reply; 40+ messages in thread
From: Nick Roberts @ 2007-05-22 2:51 UTC (permalink / raw)
To: Daniel Jacobowitz
Cc: Ross Morley, Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh
> > As watchpoints? I don't think so. A closer analogy to variable objects
> > is the "display" command. There, GDB allows expressions to come back into
> > scope.
>
> I don't think that allowing varobjs to come back into scope this way
> is really useful.
I can't say how useful it is generally because Emacs 22 is still stuck in CVS.
From personal use, however, I've sometimes found watchpoints deleting
themselves to be a nuisance. Sometimes I've got around by specifying an adress
rather than a variable name.
> ...But once the frame has gone we should recreate the
> varobjs, or else we should associate them with the function instead of
> the frame.
Would this be straightforward to implement? Isn't there anything in their
nature that makes this easier to do for watchpoints?
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 2:31 ` Daniel Jacobowitz
2007-05-22 2:51 ` Nick Roberts
@ 2007-05-22 8:40 ` Ross Morley
2007-05-22 16:10 ` Marc Gauthier
1 sibling, 1 reply; 40+ messages in thread
From: Ross Morley @ 2007-05-22 8:40 UTC (permalink / raw)
To: Daniel Jacobowitz
Cc: Nick Roberts, Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh
Daniel Jacobowitz wrote:
>On Tue, May 22, 2007 at 02:05:35PM +1200, Nick Roberts wrote:
>
>
>>As watchpoints? I don't think so. A closer analogy to variable objects
>>is the "display" command. There, GDB allows expressions to come back into
>>scope.
>>
>>
>
>I don't think that allowing varobjs to come back into scope this way
>is really useful.
>
>
I agree, since there's no way of knowing it's really the same variable.
Using a C language definition of scope (and most languages are similar)
a variable with the same name in a different scope is a different variable.
>There's a different sort of scope that does make sense - a varobj
>might come in and out of lexical scope while its frame is live, due to
>optimization. But once the frame has gone we should recreate the
>varobjs, or else we should associate them with the function instead of
>the frame.
>
>
Associating them with the function has problems with recursion. It seems to
me the ideal is to recreate vars that have gone out of scope (they really
are new vars). Use of a scope breakpoint can better detect that than the
current methods. However, are there implementation or performance issues?
Ross
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 2:51 ` Nick Roberts
@ 2007-05-22 10:58 ` Daniel Jacobowitz
0 siblings, 0 replies; 40+ messages in thread
From: Daniel Jacobowitz @ 2007-05-22 10:58 UTC (permalink / raw)
To: Nick Roberts
Cc: Ross Morley, Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh
On Tue, May 22, 2007 at 02:49:41PM +1200, Nick Roberts wrote:
> > ...But once the frame has gone we should recreate the
> > varobjs, or else we should associate them with the function instead of
> > the frame.
>
> Would this be straightforward to implement? Isn't there anything in their
> nature that makes this easier to do for watchpoints?
Nope. We could do it in basically the same way for varobjs that we do
for watchpoints, if we decide it's useful.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 40+ messages in thread
* RE: Understanding GDB frames
2007-05-22 8:40 ` Ross Morley
@ 2007-05-22 16:10 ` Marc Gauthier
2007-05-22 16:36 ` Daniel Jacobowitz
` (2 more replies)
0 siblings, 3 replies; 40+ messages in thread
From: Marc Gauthier @ 2007-05-22 16:10 UTC (permalink / raw)
To: Ross Morley, Daniel Jacobowitz
Cc: Nick Roberts, Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh
Ross Morley wrote:
> Associating them with the function has problems with recursion.
> It seems to
> me the ideal is to recreate vars that have gone out of scope (they really
> are new vars). Use of a scope breakpoint can better detect that than the
> current methods. However, are there implementation or performance issues?
As we discussed offline yesterday, this has performance implications
on the GUI, which would have to recreate the varobjs every time which
is time consuming. One often wants to just set a breakpoint on a
function, and go "next - next - next - ..." across all invocations of
that function no matter where it's called from, looking at what variables
change until one reaches the desired invocation. In this use mode one
doesn't care about specific frames, only about the specific function.
It's in this particular (common) use model that performance suffers
when distinguishing frame scopes.
It seems at the MI interface one wants a choice of whether a varobj
is associated with:
(a) a specific frame (goes away when function returns)
(b) a function
(c) a function at the same depth (which some implement)
How the distinction is made at the GUI level is a separate question.
And what to do in the event of recursion when one selected a
function-level varobj (b) is also an interesting question -- perhaps
it always refers to the topmost instance (or to theseparately selected
instance if the currently selected stack depth is to that function).
That way, (b) and (c) have less performance impact, and one of them
could be the default. And (a) being optional, could be fully supported
like watchpoints by setting a breakpoint at the return PC, even though
it has a performance hit (especially in the presence of recursion).
And perhaps MI docs could even document this ;-)
-Marc
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 16:10 ` Marc Gauthier
@ 2007-05-22 16:36 ` Daniel Jacobowitz
2007-05-22 18:14 ` Vladimir Prus
2007-05-22 18:33 ` Jim Ingham
2007-05-22 17:20 ` Ross Morley
2007-05-22 20:24 ` Nick Roberts
2 siblings, 2 replies; 40+ messages in thread
From: Daniel Jacobowitz @ 2007-05-22 16:36 UTC (permalink / raw)
To: Marc Gauthier
Cc: Ross Morley, Nick Roberts, Maxim Grigoriev, gdb, Pete MacLiesh
On Tue, May 22, 2007 at 09:10:29AM -0700, Marc Gauthier wrote:
> As we discussed offline yesterday, this has performance implications
> on the GUI, which would have to recreate the varobjs every time which
> is time consuming.
Is the performance implication the main reason? If so, I'd rather we
fix that instead. I know Nick and/or Vladimir suggested "-var-list
--locals" at one point in an earlier discussion of a related problem.
That's probably quite a lot faster, especially if we can notify the
front end when it enters a new frame.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 16:10 ` Marc Gauthier
2007-05-22 16:36 ` Daniel Jacobowitz
@ 2007-05-22 17:20 ` Ross Morley
2007-05-22 20:24 ` Nick Roberts
2 siblings, 0 replies; 40+ messages in thread
From: Ross Morley @ 2007-05-22 17:20 UTC (permalink / raw)
To: Marc Gauthier
Cc: Daniel Jacobowitz, Nick Roberts, Maxim Grigoriev, gdb, Pete MacLiesh
Marc Gauthier wrote:
>Ross Morley wrote:
>
>
>>Associating them with the function has problems with recursion.
>>It seems to
>>me the ideal is to recreate vars that have gone out of scope (they really
>>are new vars). Use of a scope breakpoint can better detect that than the
>>current methods. However, are there implementation or performance issues?
>>
>>
>
>As we discussed offline yesterday, this has performance implications
>on the GUI, which would have to recreate the varobjs every time which
>is time consuming.
>
> And (a) being optional, could be fully supported
>like watchpoints by setting a breakpoint at the return PC, even though
>it has a performance hit (especially in the presence of recursion).
>
>
>
I believe the performance implication comes mainly from the MI client
having to recreate the MI vars, not so much from the scope breakpoint.
If I recall correctly, the scope breakpoint would disappear the first
time the var went out of scope, and would not exist subsequent times
until the target stops and is resumed again (however it's been a while
since I looked at scope breakpoints).
Ross
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 16:36 ` Daniel Jacobowitz
@ 2007-05-22 18:14 ` Vladimir Prus
2007-05-22 18:33 ` Jim Ingham
1 sibling, 0 replies; 40+ messages in thread
From: Vladimir Prus @ 2007-05-22 18:14 UTC (permalink / raw)
To: gdb
Daniel Jacobowitz wrote:
> On Tue, May 22, 2007 at 09:10:29AM -0700, Marc Gauthier wrote:
>> As we discussed offline yesterday, this has performance implications
>> on the GUI, which would have to recreate the varobjs every time which
>> is time consuming.
>
> Is the performance implication the main reason? If so, I'd rather we
> fix that instead. I know Nick and/or Vladimir suggested "-var-list
> --locals" at one point in an earlier discussion of a related problem.
> That's probably quite a lot faster, especially if we can notify the
> front end when it enters a new frame.
What problem are we solving in this thread? The issue that prompted
"-var-list --locals" is that we don't reliably track local variables
as we go through lexical blocks, and we have no mechanism to create
varobj in a particular lexical scope.
It seems some other problem is being discussed, but I'm not sure which
one is that.
- Volodya
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 16:36 ` Daniel Jacobowitz
2007-05-22 18:14 ` Vladimir Prus
@ 2007-05-22 18:33 ` Jim Ingham
2007-05-22 18:36 ` Daniel Jacobowitz
1 sibling, 1 reply; 40+ messages in thread
From: Jim Ingham @ 2007-05-22 18:33 UTC (permalink / raw)
To: Daniel Jacobowitz
Cc: Marc Gauthier, Ross Morley, Nick Roberts, Maxim Grigoriev, gdb,
Pete MacLiesh
I don't see what the bad effect of not destroying the varobj if the
frame id is identical is. You might get an errant "value changed"
notification. Other than that, I can't see what you would be gaining.
If we're going to do some extra work to make sure we mark variables
out of scope when their frames are exited, we should get something
real out of it. So far it seems the benefit is only theoretical.
Jim
On May 22, 2007, at 9:36 AM, Daniel Jacobowitz wrote:
> On Tue, May 22, 2007 at 09:10:29AM -0700, Marc Gauthier wrote:
>> As we discussed offline yesterday, this has performance implications
>> on the GUI, which would have to recreate the varobjs every time which
>> is time consuming.
>
> Is the performance implication the main reason? If so, I'd rather we
> fix that instead. I know Nick and/or Vladimir suggested "-var-list
> --locals" at one point in an earlier discussion of a related problem.
> That's probably quite a lot faster, especially if we can notify the
> front end when it enters a new frame.
>
> --
> Daniel Jacobowitz
> CodeSourcery
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 18:33 ` Jim Ingham
@ 2007-05-22 18:36 ` Daniel Jacobowitz
2007-05-23 21:45 ` Jim Blandy
0 siblings, 1 reply; 40+ messages in thread
From: Daniel Jacobowitz @ 2007-05-22 18:36 UTC (permalink / raw)
To: Jim Ingham
Cc: Marc Gauthier, Ross Morley, Nick Roberts, Maxim Grigoriev, gdb,
Pete MacLiesh
On Tue, May 22, 2007 at 11:32:41AM -0700, Jim Ingham wrote:
> I don't see what the bad effect of not destroying the varobj if the frame id is
> identical is. You might get an errant "value changed" notification. Other than
> that, I can't see what you would be gaining.
>
> If we're going to do some extra work to make sure we mark variables out of
> scope when their frames are exited, we should get something real out of it. So
> far it seems the benefit is only theoretical.
Sure. I'm not seriously proposing we do that extra work, though I did
think about it. But what we do need is to clarify our semantics so
that front ends know what to expect. Should varobjs be destroyed when
we leave and re-enter a function? If the answer is "maybe", then that
is confusing enough to deserve some more explanation :-)
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-21 22:24 Understanding GDB frames Maxim Grigoriev
` (2 preceding siblings ...)
2007-05-22 2:29 ` Daniel Jacobowitz
@ 2007-05-22 18:37 ` Jim Blandy
2007-05-22 19:17 ` Maxim Grigoriev
3 siblings, 1 reply; 40+ messages in thread
From: Jim Blandy @ 2007-05-22 18:37 UTC (permalink / raw)
To: Maxim Grigoriev; +Cc: gdb, Marc Gauthier, Pete MacLiesh, Ross Morley
Maxim Grigoriev <maxim@tensilica.com> writes:
> QUESTION
> ========
>
> The program (frame.c) is
>
> #include <stdio.h>
>
> int frame_number = 1;
>
> int f11(int b)
> {
> int a;
>
> printf("f11() frame number %d\n", frame_number++);
>
> a = b + 1;
> b--;
> if (b != 0)
> {
> printf("f11() will be called recursively\n");
> f11(b);
> }
> return a; /* <-- BP set here. */
> }
>
> int f1(int a)
> {
> return f11(a);
> }
>
> int main()
> {
> int a = 1;
> int i;
>
> for (i = 0; i <2; i++)
> a = f11(a);
>
> a = f11(1);
> a = f1(1);
>
> return 0;
> }
>
> The gdb command file "CMD":
>
> break frame.c:18
> run
> continue
> continue
> continue
> continue
> kill
> quit
>
> was used to run a gdb session like this :
> gdb <executable> --command=CMD
>
> Let's define that "frames A and B are the same" if
>
> frame_id_eq ( A->this_id, B->this_id ) == true
>
> The breakpoit has been set at line 18 and hit 5 times.
> Execution control has been subsequently taken by
> gdb in five frames numbered 1, 2, 3, 4, and 5.
>
> According to the definition of GDB frames,
> which statement is correct ?
>
> ANSWERS
> =======
>
> 1) All frames 1, 2, 3, 4, and 5 are the same;
> 2) All frames 1, 2, 3, 4, and 5 are different from each other;
> 3) Frames 1,2, and 4 are the same. Frames 3 and 5 are
> different from 1, 2, 4 and from each other;
> 4) It's implementation-dependent. While doing architecture ports,
> people decide how to implement frame_id-related functions
> to compare frames;
> 5) Other ( explanation would be appreciated ).
All those frames ought to be different, but GDB will treat some of
them as the same.
Ideally, a frame is allocated each time a function is entered, and
destroyed when a function returns, or when we longjmp out of it, or
throw an exception out of it, or when the thread exits or is
cancelled. So every one of those frames is distinct. This is the
programmer's view of frames.
The first source of difficulty is optimization. The compiler may
choose to inline a function call, and thus not allocate a distinct
frame for it. Or, the compiler may choose to implement the final call
in a function as a jump, effectively freeing the caller's frame before
allocating its callee's frame. So optimization can affect which
frames actually exist in memory. GDB could 'fabricate' frames for
inlined functions, but for tail calls there's no easy solution --- the
state which would describe the caller's frame is just gone.
The second source of difficulty is that GDB doesn't get any
notification when a frame is popped. (It could arrange to get this
notification, but as Daniel says, that would slow things down.) Thus,
if a function returns, and then is called again with exactly the same
incoming stack pointer --- which is quite possible if it's the same
frame underneath making both calls --- then it's impossible for GDB to
look in on the first call, and then look in on the second call, and
know that the two frames are distinct. The PC may be the same; the SP
may be the same; the values of the arguments might be the same. If
the calls are in a loop, the PC in the caller might well be the same.
So GDB's frame ID's are a best-effort, but still faulty, approximation
to what we really want. If two ID's are *unequal*, then you can trust
that result, as far as I know. But if they're *equal*, you can't
trust that.
Joel is right when he says:
> If my understanding of the frame code is correct, then the only
> thing that is really guaranteed is that the frame ID remains
> constant throughout the lifetime of its associated frame, or
> function call. The rest is implementation-dependent.
It's worth pointing out that the 'PC' in a frame ID isn't the current
PC within the function. It's always the PC of the function's entry
point, so that stepping within a function doesn't cause the frame ID
to change. Usually it's a PC value returned by 'frame_func_unwind',
which takes care of calling get_pc_function_start for you.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 18:37 ` Jim Blandy
@ 2007-05-22 19:17 ` Maxim Grigoriev
2007-05-22 20:25 ` Nick Roberts
` (2 more replies)
0 siblings, 3 replies; 40+ messages in thread
From: Maxim Grigoriev @ 2007-05-22 19:17 UTC (permalink / raw)
To: Jim Blandy
Cc: Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh, Ross Morley
> It's worth pointing out that the 'PC' in a frame ID isn't the current
> PC within the function. It's always the PC of the function's entry
> point, so that stepping within a function doesn't cause the frame ID
> to change. Usually it's a PC value returned by 'frame_func_unwind',
> which takes care of calling get_pc_function_start for you.
We've been using a function return address instead of
the PC of the function's entry, and it works just fine.
The good part of our approach is it allowed to expose some
problems with MI variable objects :-)
> All those frames ought to be different, but GDB will treat
> some of them as the same.
I think distinguishing frames can be improved by using the third
argument of frame_id, which is a "special address". Most of the
implementations don't use it.
-- Maxim
Jim Blandy wrote:
> Maxim Grigoriev <maxim@tensilica.com> writes:
>
>> QUESTION
>> ========
>>
>> The program (frame.c) is
>>
>> #include <stdio.h>
>>
>> int frame_number = 1;
>>
>> int f11(int b)
>> {
>> int a;
>>
>> printf("f11() frame number %d\n", frame_number++);
>>
>> a = b + 1;
>> b--;
>> if (b != 0)
>> {
>> printf("f11() will be called recursively\n");
>> f11(b);
>> }
>> return a; /* <-- BP set here. */
>> }
>>
>> int f1(int a)
>> {
>> return f11(a);
>> }
>>
>> int main()
>> {
>> int a = 1;
>> int i;
>>
>> for (i = 0; i <2; i++)
>> a = f11(a);
>>
>> a = f11(1);
>> a = f1(1);
>>
>> return 0;
>> }
>>
>> The gdb command file "CMD":
>>
>> break frame.c:18
>> run
>> continue
>> continue
>> continue
>> continue
>> kill
>> quit
>>
>> was used to run a gdb session like this :
>> gdb <executable> --command=CMD
>>
>> Let's define that "frames A and B are the same" if
>>
>> frame_id_eq ( A->this_id, B->this_id ) == true
>>
>> The breakpoit has been set at line 18 and hit 5 times.
>> Execution control has been subsequently taken by
>> gdb in five frames numbered 1, 2, 3, 4, and 5.
>>
>> According to the definition of GDB frames,
>> which statement is correct ?
>>
>> ANSWERS
>> =======
>>
>> 1) All frames 1, 2, 3, 4, and 5 are the same;
>> 2) All frames 1, 2, 3, 4, and 5 are different from each other;
>> 3) Frames 1,2, and 4 are the same. Frames 3 and 5 are
>> different from 1, 2, 4 and from each other;
>> 4) It's implementation-dependent. While doing architecture ports,
>> people decide how to implement frame_id-related functions
>> to compare frames;
>> 5) Other ( explanation would be appreciated ).
>>
>
> All those frames ought to be different, but GDB will treat some of
> them as the same.
>
> Ideally, a frame is allocated each time a function is entered, and
> destroyed when a function returns, or when we longjmp out of it, or
> throw an exception out of it, or when the thread exits or is
> cancelled. So every one of those frames is distinct. This is the
> programmer's view of frames.
>
> The first source of difficulty is optimization. The compiler may
> choose to inline a function call, and thus not allocate a distinct
> frame for it. Or, the compiler may choose to implement the final call
> in a function as a jump, effectively freeing the caller's frame before
> allocating its callee's frame. So optimization can affect which
> frames actually exist in memory. GDB could 'fabricate' frames for
> inlined functions, but for tail calls there's no easy solution --- the
> state which would describe the caller's frame is just gone.
>
> The second source of difficulty is that GDB doesn't get any
> notification when a frame is popped. (It could arrange to get this
> notification, but as Daniel says, that would slow things down.) Thus,
> if a function returns, and then is called again with exactly the same
> incoming stack pointer --- which is quite possible if it's the same
> frame underneath making both calls --- then it's impossible for GDB to
> look in on the first call, and then look in on the second call, and
> know that the two frames are distinct. The PC may be the same; the SP
> may be the same; the values of the arguments might be the same. If
> the calls are in a loop, the PC in the caller might well be the same.
>
> So GDB's frame ID's are a best-effort, but still faulty, approximation
> to what we really want. If two ID's are *unequal*, then you can trust
> that result, as far as I know. But if they're *equal*, you can't
> trust that.
>
> Joel is right when he says:
>
>
>> If my understanding of the frame code is correct, then the only
>> thing that is really guaranteed is that the frame ID remains
>> constant throughout the lifetime of its associated frame, or
>> function call. The rest is implementation-dependent.
>>
>
> It's worth pointing out that the 'PC' in a frame ID isn't the current
> PC within the function. It's always the PC of the function's entry
> point, so that stepping within a function doesn't cause the frame ID
> to change. Usually it's a PC value returned by 'frame_func_unwind',
> which takes care of calling get_pc_function_start for you.
>
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* RE: Understanding GDB frames
2007-05-22 16:10 ` Marc Gauthier
2007-05-22 16:36 ` Daniel Jacobowitz
2007-05-22 17:20 ` Ross Morley
@ 2007-05-22 20:24 ` Nick Roberts
2007-05-22 21:12 ` Maxim Grigoriev
2 siblings, 1 reply; 40+ messages in thread
From: Nick Roberts @ 2007-05-22 20:24 UTC (permalink / raw)
To: Marc Gauthier
Cc: Ross Morley, Daniel Jacobowitz, Maxim Grigoriev, gdb, Pete MacLiesh
> It seems at the MI interface one wants a choice of whether a varobj
> is associated with:
> (a) a specific frame (goes away when function returns)
> (b) a function
> (c) a function at the same depth (which some implement)
GDB already does something like (b) if you use:
-var-create - @ myvar
although it's not documented. I think this can specifically be used in the
case of recursion
> How the distinction is made at the GUI level is a separate question.
> And what to do in the event of recursion when one selected a
> function-level varobj (b) is also an interesting question -- perhaps
> it always refers to the topmost instance (or to theseparately selected
> instance if the currently selected stack depth is to that function).
>
> That way, (b) and (c) have less performance impact, and one of them
> could be the default. And (a) being optional, could be fully supported
> like watchpoints by setting a breakpoint at the return PC, even though
> it has a performance hit (especially in the presence of recursion).
>
> And perhaps MI docs could even document this ;-)
If you want this functionality in GDB then I think you will have to contribute
it.
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 19:17 ` Maxim Grigoriev
@ 2007-05-22 20:25 ` Nick Roberts
2007-05-22 20:33 ` Ross Morley
2007-05-22 20:45 ` Maxim Grigoriev
2007-05-22 23:56 ` Jim Blandy
2007-05-23 0:05 ` Jim Blandy
2 siblings, 2 replies; 40+ messages in thread
From: Nick Roberts @ 2007-05-22 20:25 UTC (permalink / raw)
To: Maxim Grigoriev
Cc: Jim Blandy, gdb, Marc Gauthier, Pete MacLiesh, Ross Morley
Maxim Grigoriev writes:
> > It's worth pointing out that the 'PC' in a frame ID isn't the current
> > PC within the function. It's always the PC of the function's entry
> > point, so that stepping within a function doesn't cause the frame ID
> > to change. Usually it's a PC value returned by 'frame_func_unwind',
> > which takes care of calling get_pc_function_start for you.
>
> We've been using a function return address instead of
> the PC of the function's entry, and it works just fine.
But does this explain why xt-gdb didn't detect the variable objects coming back
into scope when an i386 gdb did?
> The good part of our approach is it allowed to expose some
> problems with MI variable objects :-)
Actually I think we've discussed this behaviour before and done nothing about
it.
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 20:25 ` Nick Roberts
@ 2007-05-22 20:33 ` Ross Morley
2007-05-22 20:45 ` Maxim Grigoriev
1 sibling, 0 replies; 40+ messages in thread
From: Ross Morley @ 2007-05-22 20:33 UTC (permalink / raw)
To: Nick Roberts
Cc: Maxim Grigoriev, Jim Blandy, gdb, Marc Gauthier, Pete MacLiesh
Nick Roberts wrote:
>Maxim Grigoriev writes:
> > > It's worth pointing out that the 'PC' in a frame ID isn't the current
> > > PC within the function. It's always the PC of the function's entry
> > > point, so that stepping within a function doesn't cause the frame ID
> > > to change. Usually it's a PC value returned by 'frame_func_unwind',
> > > which takes care of calling get_pc_function_start for you.
> >
> > We've been using a function return address instead of
> > the PC of the function's entry, and it works just fine.
>
>But does this explain why xt-gdb didn't detect the variable objects coming back
>into scope when an i386 gdb did?
>
>
In this case it's because Xtensa uses the return address rather than the
function entrypoint in the frame ID. Two calls from the same caller have
different frame IDs. That's not the case in i386.
Technically the variable didn't come back into scope, a new instance
of it was created. It's sometimes convenient to treat it as if it came
back into scope.
Ross
> > The good part of our approach is it allowed to expose some
> > problems with MI variable objects :-)
>
>Actually I think we've discussed this behaviour before and done nothing about
>it.
>
>
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 20:25 ` Nick Roberts
2007-05-22 20:33 ` Ross Morley
@ 2007-05-22 20:45 ` Maxim Grigoriev
2007-05-22 21:26 ` Nick Roberts
1 sibling, 1 reply; 40+ messages in thread
From: Maxim Grigoriev @ 2007-05-22 20:45 UTC (permalink / raw)
To: Nick Roberts
Cc: Maxim Grigoriev, Jim Blandy, gdb, Marc Gauthier, Pete MacLiesh,
Ross Morley
> But does this explain why xt-gdb didn't detect the
> variable objects coming back
> into scope when an i386 gdb did?
Yes, it does. Thanks to Ross, who already explained it in the previous email on this thread.
> Actually I think we've discussed this behavior before
> and done nothing about it.
I suggest we improve gdb documentation in the way that, when
we don't have time to describe things properly, we at
least put a reference to a corresponding GDB-mailing-list
discussion.
-- Maxim
Nick Roberts wrote:
> Maxim Grigoriev writes:
> > > It's worth pointing out that the 'PC' in a frame ID isn't the current
> > > PC within the function. It's always the PC of the function's entry
> > > point, so that stepping within a function doesn't cause the frame ID
> > > to change. Usually it's a PC value returned by 'frame_func_unwind',
> > > which takes care of calling get_pc_function_start for you.
> >
> > We've been using a function return address instead of
> > the PC of the function's entry, and it works just fine.
>
> But does this explain why xt-gdb didn't detect the variable objects coming back
> into scope when an i386 gdb did?
>
> > The good part of our approach is it allowed to expose some
> > problems with MI variable objects :-)
>
> Actually I think we've discussed this behaviour before and done nothing about
> it.
>
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 20:24 ` Nick Roberts
@ 2007-05-22 21:12 ` Maxim Grigoriev
0 siblings, 0 replies; 40+ messages in thread
From: Maxim Grigoriev @ 2007-05-22 21:12 UTC (permalink / raw)
To: Nick Roberts
Cc: Marc Gauthier, Ross Morley, Daniel Jacobowitz, Maxim Grigoriev,
gdb, Pete MacLiesh
>> -var-create - @ myvar
I tried it with my test case, and it did introduce an improvement
working as described in b).
It works in the latest GNU GDB, but it does not seem to
present/implemented in, say, GNU GDB 6.3 and 6.5.
We have to merge it from the top of the tree as soon as possible.
Thanks for pointing to this feature.
-- Maxim
Nick Roberts wrote:
> > It seems at the MI interface one wants a choice of whether a varobj
> > is associated with:
> > (a) a specific frame (goes away when function returns)
> > (b) a function
> > (c) a function at the same depth (which some implement)
>
> GDB already does something like (b) if you use:
>
> -var-create - @ myvar
>
> although it's not documented. I think this can specifically be used in the
> case of recursion
>
> > How the distinction is made at the GUI level is a separate question.
> > And what to do in the event of recursion when one selected a
> > function-level varobj (b) is also an interesting question -- perhaps
> > it always refers to the topmost instance (or to theseparately selected
> > instance if the currently selected stack depth is to that function).
> >
> > That way, (b) and (c) have less performance impact, and one of them
> > could be the default. And (a) being optional, could be fully supported
> > like watchpoints by setting a breakpoint at the return PC, even though
> > it has a performance hit (especially in the presence of recursion).
> >
> > And perhaps MI docs could even document this ;-)
>
> If you want this functionality in GDB then I think you will have to contribute
> it.
>
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 20:45 ` Maxim Grigoriev
@ 2007-05-22 21:26 ` Nick Roberts
2007-05-23 7:00 ` Eli Zaretskii
0 siblings, 1 reply; 40+ messages in thread
From: Nick Roberts @ 2007-05-22 21:26 UTC (permalink / raw)
To: Maxim Grigoriev
Cc: Jim Blandy, gdb, Marc Gauthier, Pete MacLiesh, Ross Morley
> I suggest we improve gdb documentation in the way that, when
> we don't have time to describe things properly, we at
> least put a reference to a corresponding GDB-mailing-list
> discussion.
Eli is the maintainer, but I think the documentation should be self contained.
Perhaps you should regard mailing-list as another form of documentation.
Certainly I often go from the date on a ChangeLog entry to the mailing list.
The archives also have a search facility.
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 19:17 ` Maxim Grigoriev
2007-05-22 20:25 ` Nick Roberts
@ 2007-05-22 23:56 ` Jim Blandy
2007-05-23 1:01 ` Maxim Grigoriev
2007-05-23 0:05 ` Jim Blandy
2 siblings, 1 reply; 40+ messages in thread
From: Jim Blandy @ 2007-05-22 23:56 UTC (permalink / raw)
To: Maxim Grigoriev; +Cc: gdb, Marc Gauthier, Pete MacLiesh, Ross Morley
Maxim Grigoriev <maxim@tensilica.com> writes:
>> It's worth pointing out that the 'PC' in a frame ID isn't the current
>> PC within the function. It's always the PC of the function's entry
>> point, so that stepping within a function doesn't cause the frame ID
>> to change. Usually it's a PC value returned by 'frame_func_unwind',
>> which takes care of calling get_pc_function_start for you.
>
> We've been using a function return address instead of the PC of the
> function's entry, and it works just fine.
Hmm. Consider:
void foo (void) { }
void bar (void) { }
main ()
{
int i;
for (i = 0; i < 2; i++)
{
void (*f) (void) = i ? foo : bar;
f ();
}
}
So, main will call bar first, then foo. Both calls will have
identical incoming sp's, and identical return addresses.
Using the callee's entry point is more direct; there's less
opportunity for things to go wrong. And the rest of GDB is already
working to cover up the shortcomings of that approach. :)
> I think distinguishing frames can be improved by using the third
> argument of frame_id, which is a "special address". Most of the
> implementations don't use it.
What would you put there?
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 19:17 ` Maxim Grigoriev
2007-05-22 20:25 ` Nick Roberts
2007-05-22 23:56 ` Jim Blandy
@ 2007-05-23 0:05 ` Jim Blandy
2007-05-23 0:17 ` Daniel Jacobowitz
2007-05-23 0:17 ` Ross Morley
2 siblings, 2 replies; 40+ messages in thread
From: Jim Blandy @ 2007-05-23 0:05 UTC (permalink / raw)
To: Maxim Grigoriev; +Cc: gdb, Marc Gauthier, Pete MacLiesh, Ross Morley
Maxim Grigoriev <maxim@tensilica.com> writes:
>> All those frames ought to be different, but GDB will treat
>> some of them as the same.
>
> I think distinguishing frames can be improved by using the third
> argument of frame_id, which is a "special address". Most of the
> implementations don't use it.
Yes --- that was meant for use by the IA-64, which has a separate
stack for saving registers. If you have a series of calls with frames
holding nothing but saved registers, then they may allocate no space
at all on the ordinary stack. So you need to use the register stack
pointer to distinguish frames, too.
After I'd sent my last post I realized that, of course, the "entry
point PC" approach fails in the (I'd guess) more common case that the
"return address PC" does not:
void foo (void) {}
main () { foo (); foo (); }
Perhaps the best approach is to use both the return address and the
entry point in the frame ID. If either have changed, it's certainly a
new frame.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-23 0:05 ` Jim Blandy
2007-05-23 0:17 ` Daniel Jacobowitz
@ 2007-05-23 0:17 ` Ross Morley
2007-05-23 0:32 ` Jim Blandy
1 sibling, 1 reply; 40+ messages in thread
From: Ross Morley @ 2007-05-23 0:17 UTC (permalink / raw)
To: Jim Blandy; +Cc: Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh
Jim Blandy wrote:
>Maxim Grigoriev <maxim@tensilica.com> writes:
>
>
>>>All those frames ought to be different, but GDB will treat
>>>some of them as the same.
>>>
>>>
>>I think distinguishing frames can be improved by using the third
>>argument of frame_id, which is a "special address". Most of the
>>implementations don't use it.
>>
>>
>
>Yes --- that was meant for use by the IA-64, which has a separate
>stack for saving registers. If you have a series of calls with frames
>holding nothing but saved registers, then they may allocate no space
>at all on the ordinary stack. So you need to use the register stack
>pointer to distinguish frames, too.
>
>After I'd sent my last post I realized that, of course, the "entry
>point PC" approach fails in the (I'd guess) more common case that the
>"return address PC" does not:
>
> void foo (void) {}
> main () { foo (); foo (); }
>
>Perhaps the best approach is to use both the return address and the
>entry point in the frame ID. If either have changed, it's certainly a
>new frame.
>
>
Well not quite certainly, eg.
void bar (void) {}
void foo (void) { bar (); }
main () { foo (); foo (); }
But definitely an improvement that's easy to achieve.
The problem is that the determination of the frame ID is arch specific
and so the behavior in these corner cases is not well-defined for the
MI client.
Ross
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-23 0:05 ` Jim Blandy
@ 2007-05-23 0:17 ` Daniel Jacobowitz
2007-05-23 0:17 ` Ross Morley
1 sibling, 0 replies; 40+ messages in thread
From: Daniel Jacobowitz @ 2007-05-23 0:17 UTC (permalink / raw)
To: Jim Blandy
Cc: Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh, Ross Morley
On Tue, May 22, 2007 at 05:05:27PM -0700, Jim Blandy wrote:
> Perhaps the best approach is to use both the return address and the
> entry point in the frame ID. If either have changed, it's certainly a
> new frame.
I don't think this is worth adding complexity for, honestly. Sure, it
will catch { foo(); foo(); }, but it won't catch for (i = 0; i < 10;
i++) foo ();.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-23 0:17 ` Ross Morley
@ 2007-05-23 0:32 ` Jim Blandy
2007-05-23 2:24 ` Ross Morley
0 siblings, 1 reply; 40+ messages in thread
From: Jim Blandy @ 2007-05-23 0:32 UTC (permalink / raw)
To: Ross Morley; +Cc: Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh
Ross Morley <ross@tensilica.com> writes:
> Jim Blandy wrote:
>
>>Maxim Grigoriev <maxim@tensilica.com> writes:
>>
>>
>>>>All those frames ought to be different, but GDB will treat
>>>>some of them as the same.
>>>>
>>>>
>>>I think distinguishing frames can be improved by using the third
>>>argument of frame_id, which is a "special address". Most of the
>>>implementations don't use it.
>>>
>>>
>>
>>Yes --- that was meant for use by the IA-64, which has a separate
>>stack for saving registers. If you have a series of calls with frames
>>holding nothing but saved registers, then they may allocate no space
>>at all on the ordinary stack. So you need to use the register stack
>>pointer to distinguish frames, too.
>>
>>After I'd sent my last post I realized that, of course, the "entry
>>point PC" approach fails in the (I'd guess) more common case that the
>>"return address PC" does not:
>>
>> void foo (void) {}
>> main () { foo (); foo (); }
>>
>>Perhaps the best approach is to use both the return address and the
>>entry point in the frame ID. If either have changed, it's certainly a
>>new frame.
>>
>>
> Well not quite certainly, eg.
>
> void bar (void) {}
> void foo (void) { bar (); }
> main () { foo (); foo (); }
>
> But definitely an improvement that's easy to achieve.
I don't follow. Is there something here where a frame's return
address and entry point change, but it's not a new frame? I'm not
claiming using both the return address and the entry point would
eliminate false positives in frame_eq, just that it restricts false
positives and does not introduce false negatives.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 23:56 ` Jim Blandy
@ 2007-05-23 1:01 ` Maxim Grigoriev
2007-05-23 2:24 ` Daniel Jacobowitz
0 siblings, 1 reply; 40+ messages in thread
From: Maxim Grigoriev @ 2007-05-23 1:01 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb, Marc Gauthier, Ross Morley
>> I think distinguishing frames can be improved by using the third
>> argument of frame_id, which is a "special address". Most of the
>> implementations don't use it.
> What would you put there?
Let's look at the following frame ID template:
{
stack_addr = <frame pointer of the frame>
code_addr = <PC of the entry point of the frame function>
special_addr = (Frame_Level << 24) | (<Return Address> & 0xffffff)
}
Where Frame_Level == frame_relative_level (frame) & 0xff .
I think it's going to cover
1) Recursion ;
2) void foo (void) { }
void bar (void) { }
main ()
{
int i;
for (i = 0; i < 2; i++)
{
void (*f) (void) = i ? foo : bar;
f ();
}
}
3) { foo(); foo(); }
4) All the cases when function is called from different levels;
But, this case is still a problem :
5) for (i = 0; i < 10; i++) foo ();
Anyway, doesn't it look like a reasonably inexpensive improvement ?
-- Maxim
Jim Blandy wrote:
> Maxim Grigoriev <maxim@tensilica.com> writes:
>
>>> It's worth pointing out that the 'PC' in a frame ID isn't the current
>>> PC within the function. It's always the PC of the function's entry
>>> point, so that stepping within a function doesn't cause the frame ID
>>> to change. Usually it's a PC value returned by 'frame_func_unwind',
>>> which takes care of calling get_pc_function_start for you.
>>>
>> We've been using a function return address instead of the PC of the
>> function's entry, and it works just fine.
>>
>
> Hmm. Consider:
>
> void foo (void) { }
> void bar (void) { }
>
> main ()
> {
> int i;
>
> for (i = 0; i < 2; i++)
> {
> void (*f) (void) = i ? foo : bar;
> f ();
> }
> }
>
> So, main will call bar first, then foo. Both calls will have
> identical incoming sp's, and identical return addresses.
>
> Using the callee's entry point is more direct; there's less
> opportunity for things to go wrong. And the rest of GDB is already
> working to cover up the shortcomings of that approach. :)
>
>
>> I think distinguishing frames can be improved by using the third
>> argument of frame_id, which is a "special address". Most of the
>> implementations don't use it.
>>
>
> What would you put there?
>
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-23 0:32 ` Jim Blandy
@ 2007-05-23 2:24 ` Ross Morley
2007-05-23 21:52 ` Jim Blandy
0 siblings, 1 reply; 40+ messages in thread
From: Ross Morley @ 2007-05-23 2:24 UTC (permalink / raw)
To: Jim Blandy; +Cc: Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh
Jim Blandy wrote:
>Ross Morley <ross@tensilica.com> writes:
>
>
>>Jim Blandy wrote:
>>
>>
>>>After I'd sent my last post I realized that, of course, the "entry
>>>point PC" approach fails in the (I'd guess) more common case that the
>>>"return address PC" does not:
>>>
>>> void foo (void) {}
>>> main () { foo (); foo (); }
>>>
>>>Perhaps the best approach is to use both the return address and the
>>>entry point in the frame ID. If either have changed, it's certainly a
>>>new frame.
>>>
>>>
>>>
>>>
>>Well not quite certainly, eg.
>>
>> void bar (void) {}
>> void foo (void) { bar (); }
>> main () { foo (); foo (); }
>>
>>But definitely an improvement that's easy to achieve.
>>
>>
>
>I don't follow. Is there something here where a frame's return
>address and entry point change, but it's not a new frame? I'm not
>claiming using both the return address and the entry point would
>eliminate false positives in frame_eq, just that it restricts false
>positives and does not introduce false negatives.
>
>
>
I'm sorry, I misread your post. Your "certainly" is certainly right. :-)
We need to remember, though, that one goal is to minimize the overhead
for the MI front end of having to re-create varobjs. As we get better
at detecting a frame change (reduce false positives) we actually increase
the overhead for the FE because it then (to be correct) needs to recreate
its varobjs. We should think about solving that problem before we get too
much better at detecting frame changes.
Ross
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-23 1:01 ` Maxim Grigoriev
@ 2007-05-23 2:24 ` Daniel Jacobowitz
2007-05-23 16:37 ` Maxim Grigoriev
0 siblings, 1 reply; 40+ messages in thread
From: Daniel Jacobowitz @ 2007-05-23 2:24 UTC (permalink / raw)
To: Maxim Grigoriev; +Cc: Jim Blandy, gdb, Marc Gauthier, Ross Morley
On Tue, May 22, 2007 at 06:01:01PM -0700, Maxim Grigoriev wrote:
> Anyway, doesn't it look like a reasonably inexpensive improvement ?
Why should we improve it this way?
I haven't seen any compelling reason. Jim's already said that you
can't rely on frame ID equality in all cases - this stuff is
tricky to reason about, which is exactly why we try not to export the
frame IDs to the MI client.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 21:26 ` Nick Roberts
@ 2007-05-23 7:00 ` Eli Zaretskii
2007-05-23 10:48 ` Daniel Jacobowitz
0 siblings, 1 reply; 40+ messages in thread
From: Eli Zaretskii @ 2007-05-23 7:00 UTC (permalink / raw)
To: Nick Roberts; +Cc: maxim, jimb, gdb, marc, pmac, ross
> From: Nick Roberts <nickrob@snap.net.nz>
> Date: Wed, 23 May 2007 09:26:30 +1200
> Cc: Jim Blandy <jimb@codesourcery.com>, gdb@sourceware.org, Marc Gauthier <marc@tensilica.com>, Pete MacLiesh <pmac@tensilica.com>, Ross Morley <ross@tensilica.com>
>
> > I suggest we improve gdb documentation in the way that, when
> > we don't have time to describe things properly, we at
> > least put a reference to a corresponding GDB-mailing-list
> > discussion.
>
> Eli is the maintainer, but I think the documentation should be self contained.
100% agreement.
> Perhaps you should regard mailing-list as another form of documentation.
If some discussion in the mailing list should find its way to the
manuals, I hope someone who is interested in improving the docs will
write it up and submit for inclusion; I promise to review and approve
such additions ASAP. I could also offer help in adding Texinfo markup
to an otherwise pure-ASCII text, if the author doesn't feel like
writing Texinfo.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-23 7:00 ` Eli Zaretskii
@ 2007-05-23 10:48 ` Daniel Jacobowitz
2007-05-23 12:44 ` Eli Zaretskii
0 siblings, 1 reply; 40+ messages in thread
From: Daniel Jacobowitz @ 2007-05-23 10:48 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Nick Roberts, maxim, jimb, gdb, marc, pmac, ross
On Wed, May 23, 2007 at 09:59:56AM +0300, Eli Zaretskii wrote:
> > Perhaps you should regard mailing-list as another form of documentation.
>
> If some discussion in the mailing list should find its way to the
> manuals, I hope someone who is interested in improving the docs will
> write it up and submit for inclusion; I promise to review and approve
> such additions ASAP. I could also offer help in adding Texinfo markup
> to an otherwise pure-ASCII text, if the author doesn't feel like
> writing Texinfo.
I'd also like to remind everyone that we have a Wiki now - I'm sure
there are things which would be useful to collect there.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-23 10:48 ` Daniel Jacobowitz
@ 2007-05-23 12:44 ` Eli Zaretskii
0 siblings, 0 replies; 40+ messages in thread
From: Eli Zaretskii @ 2007-05-23 12:44 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: nickrob, maxim, jimb, gdb, marc, pmac, ross
> Date: Wed, 23 May 2007 06:48:09 -0400
> From: Daniel Jacobowitz <drow@false.org>
> Cc: Nick Roberts <nickrob@snap.net.nz>, maxim@tensilica.com,
> jimb@codesourcery.com, gdb@sourceware.org, marc@tensilica.com,
> pmac@tensilica.com, ross@tensilica.com
>
> I'd also like to remind everyone that we have a Wiki now - I'm sure
> there are things which would be useful to collect there.
FWIW, I'd prefer the GDB docs to live in the manuals, not in the Wiki.
If there are entries in the Wiki that describe GDB usage or
development/hacking, but aren't appropriate for the mainstream
manuals, we could start a new manual, say gdb-faq.texi, and maintain
all those nits there.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-23 2:24 ` Daniel Jacobowitz
@ 2007-05-23 16:37 ` Maxim Grigoriev
0 siblings, 0 replies; 40+ messages in thread
From: Maxim Grigoriev @ 2007-05-23 16:37 UTC (permalink / raw)
To: Jim Blandy, gdb, Daniel Jacobowitz
> Why should we improve it this way?
I was answering abstract question how would I use "frame_id.special_addr" to improve frame ID analysis. I assumed it's been a theoretical discussion.
Daniel Jacobowitz wrote:
> On Tue, May 22, 2007 at 06:01:01PM -0700, Maxim Grigoriev wrote:
>
>> Anyway, doesn't it look like a reasonably inexpensive improvement ?
>>
>
> Why should we improve it this way?
>
> I haven't seen any compelling reason. Jim's already said that you
> can't rely on frame ID equality in all cases - this stuff is
> tricky to reason about, which is exactly why we try not to export the
> frame IDs to the MI client.
>
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-22 18:36 ` Daniel Jacobowitz
@ 2007-05-23 21:45 ` Jim Blandy
0 siblings, 0 replies; 40+ messages in thread
From: Jim Blandy @ 2007-05-23 21:45 UTC (permalink / raw)
To: Jim Ingham
Cc: Marc Gauthier, Ross Morley, Nick Roberts, Maxim Grigoriev, gdb,
Pete MacLiesh
Daniel Jacobowitz <drow@false.org> writes:
> On Tue, May 22, 2007 at 11:32:41AM -0700, Jim Ingham wrote:
>> I don't see what the bad effect of not destroying the varobj if the frame id is
>> identical is. You might get an errant "value changed" notification. Other than
>> that, I can't see what you would be gaining.
>>
>> If we're going to do some extra work to make sure we mark variables out of
>> scope when their frames are exited, we should get something real out of it. So
>> far it seems the benefit is only theoretical.
>
> Sure. I'm not seriously proposing we do that extra work, though I did
> think about it. But what we do need is to clarify our semantics so
> that front ends know what to expect. Should varobjs be destroyed when
> we leave and re-enter a function? If the answer is "maybe", then that
> is confusing enough to deserve some more explanation :-)
Varobjs were originally introduced to improve the performance of
GUI's. If I remember right, the win came from reducing round trips,
and perhaps from avoiding reparsing expressions. I think that's still
their reason for existence.
So varobjs should work in whatever way is most helpful for the GUIs
that use them. Implementing behavior that seems clean at the GDB
level, but that makes GUIs do work that negates varobjs' original
advantages, is a step backwards. Deleting varobjs when they go out of
scope, if the GUI wants to keep its display alive for the next time
that block comes back into scope, is unhelpful.
What behavior does Eclipse (say) want?
That is, if I add a variable 'x' to my display list, and the currently
selected frame is for a function 'f' with a local variable 'x', does
Eclipse want that display:
a) to be removed and forgotten when that particular frame is popped?
b) to be displayed and updated whenever a frame of 'f' is current, and
greyed out otherwise? (This is what you'd want if you were going
through various hits of a breakpoint looking at 'x' to recognize the
hit you care about.)
c) to just show whatever 'x' happens to be in scope in the current
frame?
GDB's varobjs currently implement b), which is what I'd think most
GUIs would want:
$ cat vo.c
int
foo (int x)
{
return x + 1;
}
int
bar (int x)
{
return x;
}
int
main (int argc, char **argv)
{
foo (10);
foo (20);
bar (30);
return 0;
}
If I set breakpoints in foo and bar, run to the first hit in foo, and
create a varobj for x, then the varobj is marked:
- out of scope when I return to main,
- back in scope when I re-enter foo,
- out of scope when I return to main a second time, and
- still out of scope when I enter bar.
So the frame argument to -var-create is used to identify a scope, not
to tie the varobj to that specific frame. Which I think is the
behavior that makes life easiest for GUIs.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-23 2:24 ` Ross Morley
@ 2007-05-23 21:52 ` Jim Blandy
2007-05-24 0:05 ` Ross Morley
0 siblings, 1 reply; 40+ messages in thread
From: Jim Blandy @ 2007-05-23 21:52 UTC (permalink / raw)
To: Ross Morley; +Cc: Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh
Ross Morley <ross@tensilica.com> writes:
> We need to remember, though, that one goal is to minimize the overhead
> for the MI front end of having to re-create varobjs. As we get better
> at detecting a frame change (reduce false positives) we actually increase
> the overhead for the FE because it then (to be correct) needs to recreate
> its varobjs. We should think about solving that problem before we get too
> much better at detecting frame changes.
If you don't detect a frame change, then you're displaying garbage,
aren't you? I'd expect fewer false positives should always be good...
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-23 21:52 ` Jim Blandy
@ 2007-05-24 0:05 ` Ross Morley
2007-05-24 1:24 ` Ross Morley
0 siblings, 1 reply; 40+ messages in thread
From: Ross Morley @ 2007-05-24 0:05 UTC (permalink / raw)
To: Jim Blandy; +Cc: Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh
Jim Blandy wrote:
>Ross Morley <ross@tensilica.com> writes:
>
>
>>We need to remember, though, that one goal is to minimize the overhead
>>for the MI front end of having to re-create varobjs. As we get better
>>at detecting a frame change (reduce false positives) we actually increase
>>the overhead for the FE because it then (to be correct) needs to recreate
>>its varobjs. We should think about solving that problem before we get too
>>much better at detecting frame changes.
>>
>>
>
>If you don't detect a frame change, then you're displaying garbage,
>aren't you?
>
You're displaying values from a different instance of the function.
The (new) frame is still used to find the values, but the varobj is
not deleted. Technically it's not the same variable, but from the
GUI perspective it's useful to consider it the same, as you described
in your previous post.
>I'd expect fewer false positives should always be good...
>
>
>
Apparently not if it comes at the price of having to recreate varobjs.
But it seems we're barking up the wrong tree in worrying about how to
detect a variable going out of scope...
I just had a long discussion with our eclipse GUI guy, Pete MacLiesh.
What the GUI wants is to be able to highlight which variables changed in
a function between one breakpoint and the next. It doesn't matter whether
we are still in the same instantiation of the function, in a completely
different one, or at a different frame level or recursion level.
The varobj should be associated strictly with the function, NOT the frame.
When its value is updated by -var-update, the frame is used only to find
the value (which, according to Pete, might change even as the user clicks
up and down the stack of a recursive function).
So the answer to Daniel's question:
> But what we do need is to clarify our semantics so
>> that front ends know what to expect. Should varobjs be destroyed when
>> we leave and re-enter a function? If the answer is "maybe", then that
>> is confusing enough to deserve some more explanation :-)
>
>
seems to be an unambiguous "no".
This begs the question: when should GDB destroy a varobj?
Our initial conclusion is that it is probably best to do it only when
there are no longer any instances of the function on the stack. Frame ID
should not enter into this equation, so gdbarchs are free to implement
frame ID the way that is best for them, without unexpected consequences
for GUI FEs.
Now this requires GDB to walk the entire stack when a function associated
with a varobj disappears in order to know that it has disappeared. That is
a small overhead compared to the GUI having to re-create possibly dozens of
varobjs for many functions, and try to track changes in value independently
of GDB. The reason varobjs exist is to avoid that. GDB incurs the overhead
only for varobjs, so it does not affect non-MI performance, and performance
under MI needs to be considered in light of the entire package with the GUI.
I hope this is helpful.
Ross
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-24 0:05 ` Ross Morley
@ 2007-05-24 1:24 ` Ross Morley
2007-05-24 21:56 ` Jim Blandy
0 siblings, 1 reply; 40+ messages in thread
From: Ross Morley @ 2007-05-24 1:24 UTC (permalink / raw)
To: Ross Morley
Cc: Jim Blandy, Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh
Ross Morley wrote:
>
> So the answer to Daniel's question:
>
>> But what we do need is to clarify our semantics so
>>
>>> that front ends know what to expect. Should varobjs be destroyed when
>>> we leave and re-enter a function? If the answer is "maybe", then that
>>> is confusing enough to deserve some more explanation :-)
>>
>>
>>
> seems to be an unambiguous "no".
>
> This begs the question: when should GDB destroy a varobj?
I need to revisit this. It's not clear that GDB destroys a varobj
at all unless the GUI tells it to. It seems GDB tells the GUI the
varobj went out of scope, and the GUI then doesn't update it. The
GUI's concept of scope is different than the language concept. A
var is considered in_scope if an instance of its function exists in
the stack frame (*). So perhaps GDB should not say it's not in_scope
if any instance of it still exists, even if it's a different instance
than when the varobj was created. That is, the frame ID should not
determine whether a varobj is in_scope for MI. A mere search of the
frame stack for any frame with the same entrypoint (same function)
should indicate in_scope.
(*) Before GDB 6 and the new frame ID, it seems varobj.c looked
for the frame address still being in the stack. So it may be
that MI considers a var "in scope" if its function is still
on the stack at the same level, but not if it's at a different
level. This seems less ideal for the GUI but is what GDB achieves
when frame ID uses only stack ptr and PC at function entry.
To avoid possibly breaking assumptions made by MI clients, it might
be best to simply require that a gdbarch compute frame IDs based
only on frame location in stack(s) and function entrypoint (and
explicitly NOT try to make frame ID represent a unique instantiation
of a function). This requires no change to generic GDB. If GUI people
think it would provide better behavior and can ensure their GUIs don't
rely on the present behavior, GDB could in future relax its in_scope
determination for MI vars.
Ross
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: Understanding GDB frames
2007-05-24 1:24 ` Ross Morley
@ 2007-05-24 21:56 ` Jim Blandy
0 siblings, 0 replies; 40+ messages in thread
From: Jim Blandy @ 2007-05-24 21:56 UTC (permalink / raw)
To: Ross Morley; +Cc: Maxim Grigoriev, gdb, Marc Gauthier, Pete MacLiesh
Ross Morley <ross@tensilica.com> writes:
>>> But what we do need is to clarify our semantics so
>>>
>>>> that front ends know what to expect. Should varobjs be destroyed when
>>>> we leave and re-enter a function? If the answer is "maybe", then that
>>>> is confusing enough to deserve some more explanation :-)
>>>
>>>
>>>
>> seems to be an unambiguous "no".
>>
>> This begs the question: when should GDB destroy a varobj?
>
> I need to revisit this. It's not clear that GDB destroys a varobj
> at all unless the GUI tells it to. It seems GDB tells the GUI the
> varobj went out of scope, and the GUI then doesn't update it. The
> GUI's concept of scope is different than the language concept. A
> var is considered in_scope if an instance of its function exists in
> the stack frame (*). So perhaps GDB should not say it's not in_scope
> if any instance of it still exists, even if it's a different instance
> than when the varobj was created. That is, the frame ID should not
> determine whether a varobj is in_scope for MI. A mere search of the
> frame stack for any frame with the same entrypoint (same function)
> should indicate in_scope.
>
> (*) Before GDB 6 and the new frame ID, it seems varobj.c looked
> for the frame address still being in the stack. So it may be
> that MI considers a var "in scope" if its function is still
> on the stack at the same level, but not if it's at a different
> level. This seems less ideal for the GUI but is what GDB achieves
> when frame ID uses only stack ptr and PC at function entry.
>
> To avoid possibly breaking assumptions made by MI clients, it might
> be best to simply require that a gdbarch compute frame IDs based
> only on frame location in stack(s) and function entrypoint (and
> explicitly NOT try to make frame ID represent a unique instantiation
> of a function). This requires no change to generic GDB. If GUI people
> think it would provide better behavior and can ensure their GUIs don't
> rely on the present behavior, GDB could in future relax its in_scope
> determination for MI vars.
Well, GDB uses frame IDs itself in many different ways, not just for
MI. Frame IDs are the only thing in GDB that can represent a frame
from one program pause to the next. So they're used to implement
'next', 'finish', and so on. For those purposes, frame IDs need to be
as precise as is practical. If we could, we'd give every frame ever
pushed a unique ID. We need to work out how to get the behavior GUIs
want from varobjs in terms of those ideal frame IDs.
Varobjs are really just little bits of GUI state living inside of GDB,
for speed. GDB's job is to keep the GUI up to date on how the GUI's
varobjs relate to the program's current state. I don't think GDB
should ever delete a varobj itself, except perhaps by prior
arrangement with the GUI, for the GUI's convenience.
I'd expect the most common use is for varobjs to correspond to GUI
expression/variable displays, where the user adds and removes entries.
In this use case, having GDB ever delete varobjs is just a pain: the
GUI wants them to stick around until some instance of the variable
comes back into scope. It's unclear what should happen as the program
runs and as the user selects different frames; I have some questions
about that that I'll post separately.
^ permalink raw reply [flat|nested] 40+ messages in thread
end of thread, other threads:[~2007-05-24 21:56 UTC | newest]
Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-21 22:24 Understanding GDB frames Maxim Grigoriev
2007-05-21 23:28 ` Ross Morley
2007-05-22 2:05 ` Nick Roberts
2007-05-22 2:31 ` Daniel Jacobowitz
2007-05-22 2:51 ` Nick Roberts
2007-05-22 10:58 ` Daniel Jacobowitz
2007-05-22 8:40 ` Ross Morley
2007-05-22 16:10 ` Marc Gauthier
2007-05-22 16:36 ` Daniel Jacobowitz
2007-05-22 18:14 ` Vladimir Prus
2007-05-22 18:33 ` Jim Ingham
2007-05-22 18:36 ` Daniel Jacobowitz
2007-05-23 21:45 ` Jim Blandy
2007-05-22 17:20 ` Ross Morley
2007-05-22 20:24 ` Nick Roberts
2007-05-22 21:12 ` Maxim Grigoriev
2007-05-22 1:40 ` Joel Brobecker
2007-05-22 2:29 ` Daniel Jacobowitz
2007-05-22 18:37 ` Jim Blandy
2007-05-22 19:17 ` Maxim Grigoriev
2007-05-22 20:25 ` Nick Roberts
2007-05-22 20:33 ` Ross Morley
2007-05-22 20:45 ` Maxim Grigoriev
2007-05-22 21:26 ` Nick Roberts
2007-05-23 7:00 ` Eli Zaretskii
2007-05-23 10:48 ` Daniel Jacobowitz
2007-05-23 12:44 ` Eli Zaretskii
2007-05-22 23:56 ` Jim Blandy
2007-05-23 1:01 ` Maxim Grigoriev
2007-05-23 2:24 ` Daniel Jacobowitz
2007-05-23 16:37 ` Maxim Grigoriev
2007-05-23 0:05 ` Jim Blandy
2007-05-23 0:17 ` Daniel Jacobowitz
2007-05-23 0:17 ` Ross Morley
2007-05-23 0:32 ` Jim Blandy
2007-05-23 2:24 ` Ross Morley
2007-05-23 21:52 ` Jim Blandy
2007-05-24 0:05 ` Ross Morley
2007-05-24 1:24 ` Ross Morley
2007-05-24 21:56 ` Jim Blandy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox