public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* frame_id question
@ 2005-11-09 16:29 Vladimir Prus
  2005-11-11 10:23 ` Jim Blandy
  0 siblings, 1 reply; 6+ messages in thread
From: Vladimir Prus @ 2005-11-09 16:29 UTC (permalink / raw)
  To: gdb


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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: frame_id question
  2005-11-09 16:29 frame_id question Vladimir Prus
@ 2005-11-11 10:23 ` Jim Blandy
  2005-11-11 10:35   ` Vladimir Prus
  0 siblings, 1 reply; 6+ messages in thread
From: Jim Blandy @ 2005-11-11 10:23 UTC (permalink / raw)
  To: Vladimir Prus; +Cc: gdb


Vladimir Prus <ghost@cs.msu.su> 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.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: frame_id question
  2005-11-11 10:23 ` Jim Blandy
@ 2005-11-11 10:35   ` Vladimir Prus
       [not found]     ` <8f2776cb0511110943p1bb2b03g1b158fb8a82f2528@mail.gmail.com>
  2005-11-13 17:32     ` Daniel Jacobowitz
  0 siblings, 2 replies; 6+ messages in thread
From: Vladimir Prus @ 2005-11-11 10:35 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb

On Friday 11 November 2005 13:23, Jim Blandy wrote:
> Vladimir Prus <ghost@cs.msu.su> 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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Fwd: frame_id question
       [not found]     ` <8f2776cb0511110943p1bb2b03g1b158fb8a82f2528@mail.gmail.com>
@ 2005-11-11 18:05       ` Jim Blandy
  0 siblings, 0 replies; 6+ messages in thread
From: Jim Blandy @ 2005-11-11 18:05 UTC (permalink / raw)
  To: gdb

---------- Forwarded message ----------
From: Jim Blandy <jimb@red-bean.com>
Date: Nov 11, 2005 9:43 AM
Subject: Re: frame_id question
To: Vladimir Prus <ghost@cs.msu.su>
Cc: Jim Blandy <jimb@redhat.com>, gdb@sources.redhat.com

On 11/11/05, Vladimir Prus <ghost@cs.msu.su> 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.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: frame_id question
  2005-11-11 10:35   ` Vladimir Prus
       [not found]     ` <8f2776cb0511110943p1bb2b03g1b158fb8a82f2528@mail.gmail.com>
@ 2005-11-13 17:32     ` Daniel Jacobowitz
  2005-11-13 23:34       ` Jim Blandy
  1 sibling, 1 reply; 6+ messages in thread
From: Daniel Jacobowitz @ 2005-11-13 17:32 UTC (permalink / raw)
  To: Vladimir Prus; +Cc: Jim Blandy, gdb

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 <ghost@cs.msu.su> 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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: frame_id question
  2005-11-13 17:32     ` Daniel Jacobowitz
@ 2005-11-13 23:34       ` Jim Blandy
  0 siblings, 0 replies; 6+ messages in thread
From: Jim Blandy @ 2005-11-13 23:34 UTC (permalink / raw)
  To: Vladimir Prus, Jim Blandy, gdb

On 11/13/05, Daniel Jacobowitz <drow@false.org> 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.)

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2005-11-13 23:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-11-09 16:29 frame_id question Vladimir Prus
2005-11-11 10:23 ` Jim Blandy
2005-11-11 10:35   ` Vladimir Prus
     [not found]     ` <8f2776cb0511110943p1bb2b03g1b158fb8a82f2528@mail.gmail.com>
2005-11-11 18:05       ` Fwd: " Jim Blandy
2005-11-13 17:32     ` Daniel Jacobowitz
2005-11-13 23:34       ` Jim Blandy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).