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: frame_id question


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


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