public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
From: "aburgess at redhat dot com" <sourceware-bugzilla@sourceware.org>
To: gdb-prs@sourceware.org
Subject: [Bug gdb/28681] Wrong pretty-printed unique_ptr value when using "finish"
Date: Tue, 14 Dec 2021 09:50:33 +0000	[thread overview]
Message-ID: <bug-28681-4717-sJxxyM6Vlf@http.sourceware.org/bugzilla/> (raw)
In-Reply-To: <bug-28681-4717@http.sourceware.org/bugzilla/>

https://sourceware.org/bugzilla/show_bug.cgi?id=28681

--- Comment #5 from Andrew Burgess <aburgess at redhat dot com> ---
Sure.  My original comment was all I knew at the time, but I've looked into it
a little more since then.

The call stack when the assert triggers is:

  amd64_return_value
    amd64_classify
      amd64_classify_aggregate
        amd64_has_unaligned_fields

In amd64_has_unaligned_fields we have this loop:

  for (int i = 0; i < type->num_fields (); i++)
    {
      struct type *subtype = check_typedef (type->field (i).type ());

      /* Ignore static fields, empty fields (for example nested
         empty structures), and bitfields (these are handled by
         the caller).  */
      if (field_is_static (&type->field (i))
          || (TYPE_FIELD_BITSIZE (type, i) == 0
              && TYPE_LENGTH (subtype) == 0)
          || TYPE_FIELD_PACKED (type, i))
        continue;

      int bitpos = type->field (i).loc_bitpos ();

      /* ... snip ... */
    }

And it is when we ask for the loc_bitpos that the assert triggers, as the
field's type is no FIELD_LOC_KIND_BITPOS, but is instead,
FIELD_LOC_KIND_DWARF_BLOCK.

In the case we're handling, the field being processed is the field that
describes the virtual base of the type being processed.

I originally starting playing with is_dynamic_type, but noticed that the type
in question doesn't return true for is_dynamic_type.  This seemed weird, as
clearly the offset needs resolving.  But then I found some code in
is_dynamic_type_internal which specifically detects the exact case I'm looking
at, and ensures that such a case is NOT enough to make a type appear dynamic. 
The comment on this code says:

            /* Do not consider C++ virtual base types to be dynamic
               due to the field's offset being dynamic; these are
               handled via other means.  */

But, frustratingly, doesn't indicate what that other means is, or where I might
find it.

However, I might be able to side step this issue for now.

The patch I'm playing with adds a check in amd64_classify_aggregate, if the
aggregate is not trivially_copyable then it should be passed in memory.  No
further checks are required.

I initially added the trivially_copyable check as the last check of the if
condition, like this:

  if (TYPE_LENGTH (type) > 16
      || amd64_has_unaligned_fields (type)
      || !language_pass_by_reference (type).trivially_copyable)
    {
      theclass[0] = theclass[1] = AMD64_MEMORY;
      return;
    }

However, while looking at the assertion case, I noticed that the type with a
virtual base was not trivially_copyable, so, if I reorder the checks like this:

  if (TYPE_LENGTH (type) > 16
      || !language_pass_by_reference (type).trivially_copyable
      || amd64_has_unaligned_fields (type))
    {
      theclass[0] = theclass[1] = AMD64_MEMORY;
      return;
    }

Then, problem solved!  Or, at least, problem kicked down the road!  I'm still
experimenting, but, so far, I've not been able to create an example that both
uses virtual base classes, and is trivially_copyable.

My plan for now is to place the checks in the "correct" order, and add a solid
comment explaining that the order is important (plus the test will fail if the
order is ever changed).

Things that would help are:

  1. Suggestions for how amd64_has_unaligned_fields can be improved in order to
handle virtual base class fields, e.g. how do we obtain the field offset for
those fields, or

  2. Confirmation that in C++ types with a virtual base class, are, by
definition, never trivially_copyable, this would imply my solution is actually
not such a hack after all, or

  3. An example of a class with a virtual base class, that is trivially
copyable.  Ideally, the class would be less than 8-bytes in size so that it can
be passed in a single register, such an example would then fail in my patched
GDB.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

  parent reply	other threads:[~2021-12-14  9:50 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-10 17:02 [Bug gdb/28681] New: " simark at simark dot ca
2021-12-12 17:05 ` [Bug gdb/28681] " ssbssa at sourceware dot org
2021-12-13 16:37 ` aburgess at redhat dot com
2021-12-13 16:50 ` aburgess at redhat dot com
2021-12-13 17:31 ` aburgess at redhat dot com
2021-12-13 18:22 ` simark at simark dot ca
2021-12-14  9:50 ` aburgess at redhat dot com [this message]
2021-12-14 13:52 ` simark at simark dot ca
2021-12-15 17:39 ` aburgess at redhat dot com
2021-12-23 12:15 ` cvs-commit at gcc dot gnu.org
2021-12-23 12:16 ` aburgess at redhat dot com
2021-12-23 13:05 ` simon.marchi at polymtl dot ca
2022-03-14 10:39 ` cvs-commit at gcc dot gnu.org
2022-11-14 21:23 ` cvs-commit at gcc dot gnu.org

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=bug-28681-4717-sJxxyM6Vlf@http.sourceware.org/bugzilla/ \
    --to=sourceware-bugzilla@sourceware.org \
    --cc=gdb-prs@sourceware.org \
    /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).