This is the mail archive of the gdb-patches@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: [rfc, frame] Always check for unsaved PC


On Sun, Aug 20, 2006 at 04:27:49PM +0200, Mark Kettenis wrote:
> > If there were no stack frame, this would trigger
> > the duplicate frame ID check, but there is; the function remains the
> > same but the CFA moves continually down, and the frame repeats
> > endlessly.
> > 
> > Here's a simple way to detect this.  Suppose we have two normal frames
> > in a row.  Unwind PC_REGNUM from both of them.  Two functions having
> > the same return address isn't a problem.  But two functions sharing a
> > stack slot for the return address is a big problem; that never happens
> > normally, since the first one would pop it.  So this indicates that the
> > older frame didn't actually save it.
> 
> This doesn't fly for architectures where the return address is
> computed though, like on sparc.

Right.  I don't think we need to make this generic check work
everywhere; what I'd like to do instead would be to allow the prologue
unwinder to return its own "this is why I think unwinding is done"
reason.  The check doesn't really apply to SPARC in the same form.
However, a frameless normal frame where the next frame is also a normal
frame has the same problem, and could use the same unwind stop reason.

I see that gdb doesn't use dwarf2 unwind tables on sparc.  Does GCC
generate them?  How does GCC deal with the extra +8?  It looks like
it doesn't; it uses %o7 to handle unwinding and just looks at the
location of the call site.

> > There's one wart in this patch.  frame_register_unwind doesn't tell us
> > where a register was ultimately stored; it recurses for the register
> > value, but fills in *optimizedp, *lvalp, *realnump, *addrp for where
> > _this frame_ saved it.  Which is reasonable and useful behavior.  So,
> > we need to iterate ourselves in order to find the final location.
> 
> Don't we have that code already for evaluating variables?  Can't that
> code be re-used?

We do have some similar code, but it can't readily be reused here.  I
want the frame prev_register to keep returning the non-transitive
values; that's how we generate a useful "info frame" which says which
registers were saved in this frame, instead of which registers were
saved in any frame.

> > There's an associated FIXME; I discovered that three targets don't do
> > it this way.  That doesn't break this patch, but it's inconsistent, and
> > does a bit of extra computation.  So if there's general agreement that
> > this patch is a good idea, I'll go through and fix them, and try to
> > document more clearly that you aren't supposed to do it that way.
> > Then I can remove the FIXME.
> 
> I'll have a go at alpha if you don't mind.

Sure.  It's simple: look for calls to frame_register and
frame_register_unwind in the tdep files (alpha-tdep.c and
alpha-mdebug-tdep.c), and compare them to the more common
version which uses frame_unwind_register (I hate that naming...).
The alpha version has the next frame fill in *lvalp and
always recurses.  The i386 version has the current frame fill in *lvalp
and only recurses if we need the value.

> I think the error message should be clear about which frame did not
> save the PC.

Could you give me an example of how to make it clearer?  Here's what
it looks like at the moment, IIRC (mocked up, I don't have easy access
to the test right now):

#0  0xffffe410 in __kernel_vsyscall ()
#1  0xb7e441cb in poll () from /lib/tls/i686/cmov/libc.so.6
#2  0x0810c713 in gdb_do_one_event ()
Backtrace stopped: frame did not save the PC

And:

(gdb) i frame 2
Stack frame at 0xbf8842c0:
 eip = 0x810c713 in gdb_do_one_event; saved eip 0x8109a43
 Stops backtrace: frame did not save the PC
 called by frame at 0xbf8842f0
 Arglist at 0xbf8842b8, args:

Maybe "current frame" would be clearer?

-- 
Daniel Jacobowitz
CodeSourcery


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