This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Understanding GDB frames


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.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]