Mirror of the gdb mailing list
 help / color / mirror / Atom feed
From: Jim Blandy <jimb@codesourcery.com>
To: Maxim Grigoriev <maxim@tensilica.com>
Cc: gdb@sourceware.org,  Marc Gauthier <marc@tensilica.com>,
		  Pete MacLiesh <pmac@tensilica.com>,
		  Ross Morley <ross@tensilica.com>
Subject: Re: Understanding GDB frames
Date: Tue, 22 May 2007 18:37:00 -0000	[thread overview]
Message-ID: <m3y7jgbt7j.fsf@codesourcery.com> (raw)
In-Reply-To: <46521C04.7040405@hq.tensilica.com> (Maxim Grigoriev's message of "Mon, 21 May 2007 15:24:04 -0700")


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.


  parent reply	other threads:[~2007-05-22 18:37 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-21 22:24 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 [this message]
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       ` 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
2007-05-23  0:17       ` Daniel Jacobowitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m3y7jgbt7j.fsf@codesourcery.com \
    --to=jimb@codesourcery.com \
    --cc=gdb@sourceware.org \
    --cc=marc@tensilica.com \
    --cc=maxim@tensilica.com \
    --cc=pmac@tensilica.com \
    --cc=ross@tensilica.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox