public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
From: Mark Kettenis <kettenis@chello.nl>
To: ac131313@redhat.com
Cc: mludvig@suse.cz, gdb@sources.redhat.com
Subject: Re: dwarf-frame.c question
Date: Thu, 29 May 2003 22:22:00 -0000	[thread overview]
Message-ID: <200305292222.h4TMMmGm000694@elgar.kettenis.dyndns.org> (raw)
In-Reply-To: <3ED66564.1020506@redhat.com> (message from Andrew Cagney on Thu, 29 May 2003 15:54:12 -0400)

   Date: Thu, 29 May 2003 15:54:12 -0400
   From: Andrew Cagney <ac131313@redhat.com>

   >    Date: Tue, 27 May 2003 17:18:35 +0200
   >    From: Michal Ludvig <mludvig@suse.cz>
   > 
   >    Hi Mark,
   > 
   >    why do you decrement unwound PC in dwarf_frame_cache() before using it?
   > 
   > The unwound PC is the return address, i.e. the instruction that will
   > be executed when the function returns.

   Yes, the resume address, or the next instruction that will be executed 
   when the frame resumes.

   frame_address_in_block() also tries to handle this.

Indeed.  When I noted the problems with frame_address_in_block()
before, we more or less agreed that we needed to add properties to our
frames instead of making decision based on a frames type.  One such a
property could whether to decrease the rerturn address or not.

   >  This is the instruction after
   > the call instruction.  The problem is that if the call instruction is
   > the last instruction of a function, the return address might point to
   > the next function:

   > foo:
   >    ...
   >    call abort
   > 
   > bar:
   >    push %ebp
   >    mov %esp, %ebp
   >    ...
   > 
   > That's why the GCC unwinder does the same thing.  Note that the
   > decrementing the PC is wrong for "interrupt frames", which is why the
   > if-statement is there in the code fragment you cite:
   > 
   >    dwarf-frame.c:
   >    478       /* Unwind the PC.  */
   >    479       fs->pc = frame_pc_unwind (next_frame);
   >    480       if (get_frame_type (next_frame) == NORMAL_FRAME
   >    481           && frame_relative_level (next_frame) >= 0)
   >    482         fs->pc--;

   First an FYI.  CFI has that return-address column.  I'm left wondering 
   if frame_pc_unwind() should try the frame for the unwound pc before 
   trying for registers.  However, there has so far been zero evidence 
   supporting this need so I think, until there is, let it be.  It also 
   wouldn't help with this case - it to would still point back to beyond 
   the function :-(

I'm not sure what you mean here, but dwarf-frame.c treats the
return-address column as the saved/unwound pc.

   Second, another FYI.  This isn't just a CFI problem.  There have been 
   earlier posts about how GDB, already gets confused by this - printing 
   out the wrong function address for instance.  This problem is generic.

Yes indeed it is.

   Anyway, is it safe to always decrement the resume address before looking 
   for the CFI info?  Given a more complex sequence like:

	   1: setup call
	   2: call xxx with lots of side effects
	   3: delay slot saved r0++
	   4: discard call

   then the CFI info for 4 could be very different to that for 2/3.

Well, the GCC unwinder seems to think it is safe to do this.  Note
that we only use the decremented resume address to find the FDE, and
that we use the real return address for calculating the CFI.  This
means that as long as the compiler doesn't store the CFI for 3 and 4
in different FDE's, we'll always have the correct CFI.

    >  Andrew, it seems that we should tweak the frame code
    > to make sure that frame_unwind_by_pc is always passed a PC *within* the
    > function.

   True, but how?  It would effectively be frame_unwind_address_in_block() 
   but how reliably/where could it be used?

Oops, I meant frame_unwind_find_by_pc instead of frame_unwind_by_pc.
Anyway, every invocation of get_frame_pc() is a potential candidate.

It seems to me that this deserves a bit more thought.  Should I
postpone moving the CFI unwinder over to mainline until this is
resolved?  Alternatively I can comment out the bit of code that
decrements the return-address.  That would be "acceptable" since the
bug it tries to solve is present in the current code too.

Mark

  reply	other threads:[~2003-05-29 22:22 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-05-27 15:19 Michal Ludvig
2003-05-29 15:44 ` Mark Kettenis
2003-05-29 19:54   ` Andrew Cagney
2003-05-29 22:22     ` Mark Kettenis [this message]
2003-05-29 22:43       ` Michal Ludvig
2003-05-29 23:13       ` Andrew Cagney
2003-05-30  1:34         ` Daniel Jacobowitz
2003-05-30 20:21         ` Jim Blandy
2003-05-30 20:32           ` Andrew Cagney
2003-06-03  0:04             ` Jim Blandy
2003-06-03  5:47               ` Richard Henderson
2003-06-03  6:32                 ` Jim Blandy
2003-06-03 15:58                   ` Richard Henderson
2003-06-03 17:38                     ` Richard Henderson
2003-06-03 20:12                   ` Alexandre Oliva
2003-05-30 20:44           ` Alexandre Oliva
2003-05-30 20:21         ` Jim Blandy
2003-06-01  5:59 Richard Henderson
2003-06-01 10:00 ` Mark Kettenis
2003-06-02 20:34   ` Richard Henderson

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=200305292222.h4TMMmGm000694@elgar.kettenis.dyndns.org \
    --to=kettenis@chello.nl \
    --cc=ac131313@redhat.com \
    --cc=gdb@sources.redhat.com \
    --cc=mludvig@suse.cz \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).