From: Daniel Jacobowitz <drow@false.org>
To: Mark Kettenis <mark.kettenis@xs4all.nl>
Cc: gdb-patches@sourceware.org
Subject: Re: [rfc, frame] Always check for unsaved PC
Date: Mon, 21 Aug 2006 15:58:00 -0000 [thread overview]
Message-ID: <20060820170508.GD20987@nevyn.them.org> (raw)
In-Reply-To: <200608201427.k7KERnD0001824@elgar.sibelius.xs4all.nl>
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
next prev parent reply other threads:[~2006-08-20 17:05 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-08-20 13:58 Daniel Jacobowitz
2006-08-20 16:28 ` Mark Kettenis
2006-08-21 15:58 ` Daniel Jacobowitz [this message]
2006-08-22 21:36 ` Mark Kettenis
2006-08-23 9:57 ` Daniel Jacobowitz
2006-11-10 20:16 ` Daniel Jacobowitz
2007-01-11 16:34 ` Andreas Schwab
2007-01-11 16:45 ` Daniel Jacobowitz
2007-01-11 17:15 ` Andreas Schwab
2007-01-11 17:18 ` 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=20060820170508.GD20987@nevyn.them.org \
--to=drow@false.org \
--cc=gdb-patches@sourceware.org \
--cc=mark.kettenis@xs4all.nl \
/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