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.
next prev 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: linkBe 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).