public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Luis Machado <luis.machado@linaro.org>
To: Scott Linder <scott@scottlinder.com>, gdb-patches@sourceware.org
Subject: Re: [PATCH v2] [gdb] Support frames inlined into the outer frame
Date: Fri, 3 Apr 2020 16:37:10 -0300	[thread overview]
Message-ID: <6b20b512-e9d7-79ec-7dd3-513ec3e2003d@linaro.org> (raw)
In-Reply-To: <20200331191856.31222-1-scott@scottlinder.com>

Hi Scott,

I was giving this a try on aarch64-linux to see if it fixed an existing 
problem handling inline frames, but it seems to completely break GDB for 
this architecture.

The testsuite runs into a number of internal errors of this kind:

gdb/frame.c:1841: internal-error: frame_info* 
get_next_frame_sentinel_okay(frame_info*): Assertion `this_frame != 
sentinel_frame' failed.

Even basic tests like gdb.base/break.exp run into this.

I'd recommend running this through the buildbot/tryserver to catch 
regressions. This is a very delicate area that is known to break things.

On 3/31/20 4:18 PM, Scott Linder wrote:
> Broaden the definition of `outer_frame_id` to effectively create a new
> class of "invalid" IDs to represent frames inlined into the outer frame.
> These new IDs behave like the outer frame, in that they are "invalid",
> yet return true from `frame_id_p` and compare equal to themselves.
> 
> 2020-03-18  Scott Linder  <scott@scottlinder.com>
> 
> 	* frame.c (frame_id_p): Consider functions inlined into outer frame
> 	as valid.
> 	(frame_id_eq): Consider functions inlined into outer frame with same
> 	artificial_depth as equal.
> 	(outer_frame_id_p): New.
> 	* frame.h (outer_frame_id): Update comment.
> 	(outer_frame_id_p): New.
> 	* inline-frame.c (inline_frame_this_id): Remove assert that prevents
> 	inline frame ids in outer frame.
> 
> Change-Id: I8aa129c667dccc31590ffdf426586418493a6ebe
> ---
> Changes since v1:
> * Fix ChangeLog formatting.
> * Add outer_frame_id_p to capture new definition of outer_frame_id in
>    one place and to restore checks for all members.
> * Reword some comments to make them more precise, borrowing a lot of
>    wording from Andrew Burgess.
> * Remove some comments describing what is now obvious.
> * Undo update to frame_id_p comment which exposes implementation details.
> 
>   gdb/frame.c        | 41 ++++++++++++++++++++++++++++-------------
>   gdb/frame.h        | 12 +++++++++++-
>   gdb/inline-frame.c |  4 ----
>   3 files changed, 39 insertions(+), 18 deletions(-)
> 
> diff --git a/gdb/frame.c b/gdb/frame.c
> index d74d1d5c7c..c6154c2d9c 100644
> --- a/gdb/frame.c
> +++ b/gdb/frame.c
> @@ -692,11 +692,7 @@ frame_id_p (struct frame_id l)
>   {
>     int p;
>   
> -  /* The frame is valid iff it has a valid stack address.  */
> -  p = l.stack_status != FID_STACK_INVALID;
> -  /* outer_frame_id is also valid.  */
> -  if (!p && memcmp (&l, &outer_frame_id, sizeof (l)) == 0)
> -    p = 1;
> +  p = l.stack_status != FID_STACK_INVALID || outer_frame_id_p (l);
>     if (frame_debug)
>       {
>         fprintf_unfiltered (gdb_stdlog, "{ frame_id_p (l=");
> @@ -720,14 +716,15 @@ frame_id_eq (struct frame_id l, struct frame_id r)
>   {
>     int eq;
>   
> -  if (l.stack_status == FID_STACK_INVALID && l.special_addr_p
> -      && r.stack_status == FID_STACK_INVALID && r.special_addr_p)
> -    /* The outermost frame marker is equal to itself.  This is the
> -       dodgy thing about outer_frame_id, since between execution steps
> -       we might step into another function - from which we can't
> -       unwind either.  More thought required to get rid of
> -       outer_frame_id.  */
> -    eq = 1;
> +  if (outer_frame_id_p (l) && outer_frame_id_p (r))
> +    /* The outermost frame marker, and any inline frame markers derived
> +       from it (with artificial_depth > 0), are equal to themselves.  The
> +       problem with outer_frame_id is that, if between execution steps, we
> +       step into a completely separate function (not an inlined function)
> +       that also identifies as outer_frame_id, then we can't distinguish
> +       between the previous frame and the new frame.  More thought is
> +       required to get rid of outer_frame_id.  */
> +    eq = l.artificial_depth == r.artificial_depth;
>     else if (l.stack_status == FID_STACK_INVALID
>   	   || r.stack_status == FID_STACK_INVALID)
>       /* Like a NaN, if either ID is invalid, the result is false.
> @@ -763,6 +760,24 @@ frame_id_eq (struct frame_id l, struct frame_id r)
>     return eq;
>   }
>   
> +int
> +outer_frame_id_p (struct frame_id l)
> +{
> +  int p;
> +
> +  /* The artificial_depth can vary so we ignore it when checking if this is
> +     an outer_frame_id.  */
> +  l.artificial_depth = 0;
> +  p = memcmp (&l, &outer_frame_id, sizeof (outer_frame_id));
> +  if (frame_debug)
> +    {
> +      fprintf_unfiltered (gdb_stdlog, "{ outer_frame_id_p (l=");
> +      fprint_frame_id (gdb_stdlog, l);
> +      fprintf_unfiltered (gdb_stdlog, ") -> %d }\n", p);
> +    }
> +  return p;
> +}
> +
>   /* Safety net to check whether frame ID L should be inner to
>      frame ID R, according to their stack addresses.
>   
> diff --git a/gdb/frame.h b/gdb/frame.h
> index cfc15022ed..66f19c91dc 100644
> --- a/gdb/frame.h
> +++ b/gdb/frame.h
> @@ -195,7 +195,13 @@ extern const struct frame_id sentinel_frame_id;
>   
>   /* This means "there is no frame ID, but there is a frame".  It should be
>      replaced by best-effort frame IDs for the outermost frame, somehow.
> -   The implementation is only special_addr_p set.  */
> +
> +   The implementation has stack_status set to FID_STACK_INVALID,
> +   special_addr_p set to 1, artificial_depth set to 0 or greater, and all other
> +   members set to 0. For the non-inline outer frame artificial_depth remains
> +   set to 0 and for frames inlined into it the artificial_depth is set in the
> +   typical way.  Checking if a frame marker is an outer_frame_id should be done
> +   with outer_frame_id_p.  */
>   extern const struct frame_id outer_frame_id;
>   
>   /* Flag to control debugging.  */
> @@ -250,6 +256,10 @@ extern int frame_id_artificial_p (struct frame_id l);
>      either L or R have a zero .func, then the same frame base.  */
>   extern int frame_id_eq (struct frame_id l, struct frame_id r);
>   
> +/* Returns non-zero when L is an outer frame marker or any inline frame marker
> +   derived from it.  */
> +extern int outer_frame_id_p (struct frame_id l);
> +
>   /* Write the internal representation of a frame ID on the specified
>      stream.  */
>   extern void fprint_frame_id (struct ui_file *file, struct frame_id id);
> diff --git a/gdb/inline-frame.c b/gdb/inline-frame.c
> index c650195e57..a187630840 100644
> --- a/gdb/inline-frame.c
> +++ b/gdb/inline-frame.c
> @@ -171,10 +171,6 @@ inline_frame_this_id (struct frame_info *this_frame,
>        frame").  This will take work.  */
>     gdb_assert (frame_id_p (*this_id));
>   
> -  /* For now, require we don't match outer_frame_id either (see
> -     comment above).  */
> -  gdb_assert (!frame_id_eq (*this_id, outer_frame_id));
> -
>     /* Future work NOTE: Alexandre Oliva applied a patch to GCC 4.3
>        which generates DW_AT_entry_pc for inlined functions when
>        possible.  If this attribute is available, we should use it
> 

  parent reply	other threads:[~2020-04-03 19:37 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-18 20:43 [RFC][PATCH] " scott
2020-03-18 21:17 ` scott
2020-03-18 21:27   ` Simon Marchi
2020-03-18 21:42     ` scott
2020-03-18 21:45       ` Simon Marchi
2020-03-18 22:06         ` Scott Linder
2020-03-18 22:11         ` [PATCH] [gdb] " Scott Linder
2020-03-24 10:22           ` Andrew Burgess
2020-03-30 22:22             ` scott
2020-03-31 19:18               ` [PATCH v2] " Scott Linder
2020-04-03 17:00                 ` Andrew Burgess
2020-04-17 20:41                   ` Scott Linder
2020-04-03 19:37                 ` Luis Machado [this message]
2020-04-17 20:51                   ` Scott Linder
2020-06-04 16:11                 ` Simon Marchi
2020-06-04 19:23                   ` Simon Marchi
2020-06-08 12:00                     ` Luis Machado
2020-06-08 16:01                       ` Simon Marchi
2020-06-08 16:10                         ` Luis Machado
2020-04-02 19:30               ` [PATCH] " Pedro Alves
2020-04-17 20:35                 ` Scott Linder

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=6b20b512-e9d7-79ec-7dd3-513ec3e2003d@linaro.org \
    --to=luis.machado@linaro.org \
    --cc=gdb-patches@sourceware.org \
    --cc=scott@scottlinder.com \
    /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).