frame_id question

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

frame_id question

Vladimir Prus

Hello,
I have some confusion over "frame_id" concept, which is supposed to be
unique identifier of a function frame.

Frame id consists of a stack address and a program address. The program
address should be start address of a function and many of xxx_this_frame_id
function follow this pattern:

   static void
   xxx_frame_this_id (struct frame_info *next_frame, void **this_cache,
                      struct frame_id *this_id)
   {
      .......
      (*this_id) = frame_id_build (....,
                                   frame_func_unwind (next_frame));
   }

The question is: why frame id has to include program address at all? It it
ever possible for two frames to have the same stack address? If so, when?

The immediate problem I have is that "frame_func_unwind" requires full debug
info (address boundaries for functions), but in my case assembler modules
have only line information, so frame_func_unwind will always return 0.
Using hardcoded '0' as program address part of frame id does not cause any
problems for me, but I want to be sure.

Thanks in advance,
Volodya

Reply | Threaded
Open this post in threaded view
|

Re: frame_id question

JimB-3

Vladimir Prus <[hidden email]> writes:
> The question is: why frame id has to include program address at all? It it
> ever possible for two frames to have the same stack address? If so, when?

Some functions don't need any stack space at all.  Such a function can
even call other functions if it moves the return address to a
callee-saved register while doing so.  Unwinding through such a call,
the caller's frame will have the same CFA as the callee, but a
different function address.  Since the two frame ID's have different
function addresses, frame_id_eq will declare them distinct, and GDB
won't complain that it has gotten stuck trying to unwind the stack.
Reply | Threaded
Open this post in threaded view
|

Re: frame_id question

Vladimir Prus
On Friday 11 November 2005 13:23, Jim Blandy wrote:
> Vladimir Prus <[hidden email]> writes:
> > The question is: why frame id has to include program address at all? It
> > it ever possible for two frames to have the same stack address? If so,
> > when?
>
> Some functions don't need any stack space at all.  Such a function can
> even call other functions if it moves the return address to a
> callee-saved register while doing so.  

Do I understand correctly that this can happen only on architectures where
return address is not automatically pushed to the stack, but moved to a
special register? Like MIPS's "jal" instructions that moves return address to
$31

> Unwinding through such a call,
> the caller's frame will have the same CFA as the callee, but a
> different function address.  Since the two frame ID's have different
> function addresses, frame_id_eq will declare them distinct, and GDB
> won't complain that it has gotten stuck trying to unwind the stack.

Does it mean that for architectures with automatic pushing of return address,
using '0' as code address in frame_id will be safe? Or there are some corner
cases?

Thanks,
Volodya
Reply | Threaded
Open this post in threaded view
|

Fwd: frame_id question

jimb (Bugzilla)
---------- Forwarded message ----------
From: Jim Blandy <[hidden email]>
Date: Nov 11, 2005 9:43 AM
Subject: Re: frame_id question
To: Vladimir Prus <[hidden email]>
Cc: Jim Blandy <[hidden email]>, [hidden email]

On 11/11/05, Vladimir Prus <[hidden email]> wrote:
>  Do I understand correctly that this can happen only on architectures where
> return address is not automatically pushed to the stack, but moved to a
> special register? Like MIPS's "jal" instructions that moves return address to
> $31

 Yes, that's right.


> Does it mean that for architectures with automatic pushing of return address,
> using '0' as code address in frame_id will be safe? Or there are some corner
> cases?

 I think this is true.  It used to be that some architectures used the
top of the stack as the frame ID's stack address (even though this is
wrong: a call to alloca could change the sp, or the code itself could
push and pop things for its own reasons; either would produce a "new"
frame ID when no call, return, or longjmp has taken place).  On these
architectures, I think you could run into problems.

 But the modern thing to do is to use the base of the stack frame ---
the top of the stack upon entry to the function, or some fixed offset
from that --- as the frame ID's stack address.  When you have Dwarf
CFI for the function, we use the Dwarf CFA for the frame ID stack
address, which meets those qualifications.  I'm not sure what the code
address would be needed for in those architectures.

 If you're porting to a new architecture, you'll want to go through
the test suite results very carefully to look for stack unwinding
problems.
Reply | Threaded
Open this post in threaded view
|

Re: frame_id question

Daniel Jacobowitz-2
In reply to this post by Vladimir Prus
On Fri, Nov 11, 2005 at 01:35:16PM +0300, Vladimir Prus wrote:
> On Friday 11 November 2005 13:23, Jim Blandy wrote:
> > Vladimir Prus <[hidden email]> writes:
> > > The question is: why frame id has to include program address at all? It
> > > it ever possible for two frames to have the same stack address? If so,
> > > when?
> >
> > Some functions don't need any stack space at all.  Such a function can
> > even call other functions if it moves the return address to a
> > callee-saved register while doing so.  

I was going to reply with that example, but I couldn't convince myself
it was possible.  It'll clobber the value previously in that
callee-saved register.  However, I know there is a case like this - I
just can't think of it at the moment.

This doesn't happen for ia64 because we have the register stack address
in the frame ID.  It looks like rotating SPARC register windows always
changes the stack pointer, so that's not it either.

It may be historical at this point; it was definitely added
(2002-06-10) after the ia64 port (2000-03-21), but before the special_p
address now used for the register stack (2003-10-17).

> Do I understand correctly that this can happen only on architectures where
> return address is not automatically pushed to the stack, but moved to a
> special register? Like MIPS's "jal" instructions that moves return address to
> $31

In theory, no, but it's much more likely on such an architecture.

One other problem may have to do with inconsistent unwinders.  If one
uses the top of the stack and another uses the bottom, when unwinding
different pieces of code, it's possible to get quite confused.

Here's a very hypothetical example which explains why we do need this
to cover all the corners.  Suppose we have a function foo, which is
written in assembly (I'll use i386), and knows that it will never ever
be re-entered.  We can do this:

foo:
        pop %eax
        mov %eax, 0x40004004
        call bar
        mov 0x40004004, %eax
        jmp *%eax

This function calls bar just as if it had been called from foo's
caller, except for return address.  Bar might fetch the real return
address out of the global address and then record some information
about the stack frame.

Proper DWARF-2 CFI would even enable us to backtrace through this.
A little more sophistication can make it somewhat re-entrant.

Saving the code address wouldn't help enough to handle backtracing
through this if it were re-entrant (used an on-the-side stack GDB
didn't know about), but it does let us backtrace through a single call
to it, because foo no longer has the same frame ID as its caller.

> > Unwinding through such a call,
> > the caller's frame will have the same CFA as the callee, but a
> > different function address.  Since the two frame ID's have different
> > function addresses, frame_id_eq will declare them distinct, and GDB
> > won't complain that it has gotten stuck trying to unwind the stack.
>
> Does it mean that for architectures with automatic pushing of return address,
> using '0' as code address in frame_id will be safe? Or there are some corner
> cases?

It will surely work most of the time; I can't say whether it will work
all the time or not.  In practice, probably so close to always as makes
no difference.

--
Daniel Jacobowitz
CodeSourcery, LLC
Reply | Threaded
Open this post in threaded view
|

Re: frame_id question

jimb (Bugzilla)
On 11/13/05, Daniel Jacobowitz <[hidden email]> wrote:
> > > Some functions don't need any stack space at all.  Such a function can
> > > even call other functions if it moves the return address to a
> > > callee-saved register while doing so.
>
> I was going to reply with that example, but I couldn't convince myself
> it was possible.  It'll clobber the value previously in that
> callee-saved register.  However, I know there is a case like this - I
> just can't think of it at the moment.

You're right.  Now I'm not sure it's possible either.  (Setting aside
dummy frames created by GDB.)