public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
From: Tom Tromey <tromey@sourceware.org>
To: gdb-cvs@sourceware.org
Subject: [binutils-gdb] Avoid crash on single-field union in Rust
Date: Fri, 04 Oct 2019 02:56:00 -0000	[thread overview]
Message-ID: <20191004025632.126448.qmail@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=77c2dba3e843694fae090e237ccdf1b8f65b94e6

commit 77c2dba3e843694fae090e237ccdf1b8f65b94e6
Author: Tom Tromey <tom@tromey.com>
Date:   Thu Oct 3 17:21:52 2019 -0600

    Avoid crash on single-field union in Rust
    
    PR rust/24976 points out a crash in gdb when a single-field union is
    used in Rust.
    
    The immediate problem was a NULL pointer dereference in
    quirk_rust_enum.  However, that code is also erroneously treating a
    single-field union as if it were a univariant enum.  Looking at the
    output of an older Rust compiler, it turns out that univariant enums
    are distinguished by having a single *anonymous* field.  This patch
    changes quirk_rust_enum to limit its fixup to this case.
    
    Tested with a new-enough version of the Rust compiler to cause the
    crash; plus by using an older executable that uses the old univariant
    encoding.
    
    gdb/ChangeLog
    2019-10-03  Tom Tromey  <tom@tromey.com>
    
    	PR rust/24976:
    	* dwarf2read.c (quirk_rust_enum): Handle single-element unions.
    
    gdb/testsuite/ChangeLog
    2019-10-03  Tom Tromey  <tom@tromey.com>
    
    	PR rust/24976:
    	* gdb.rust/simple.rs (Union2): New type.
    	(main): Use Union2.
    	* gdb.rust/simple.exp: Add test.

Diff:
---
 gdb/ChangeLog                     | 5 +++++
 gdb/dwarf2read.c                  | 6 +++---
 gdb/testsuite/ChangeLog           | 7 +++++++
 gdb/testsuite/gdb.rust/simple.exp | 2 ++
 gdb/testsuite/gdb.rust/simple.rs  | 6 ++++++
 5 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 446c455..4eeed49 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2019-10-03  Tom Tromey  <tom@tromey.com>
+
+	PR rust/24976:
+	* dwarf2read.c (quirk_rust_enum): Handle single-element unions.
+
 2019-10-03  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* f-lang.c (f_language_defn): Use cp_get_symbol_name_matcher and
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index c0dd199..ee9df34 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -10076,10 +10076,10 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
       SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
       TYPE_FIELD_NAME (type, 0) = "<<variants>>";
     }
-  else if (TYPE_NFIELDS (type) == 1)
+  /* A union with a single anonymous field is probably an old-style
+     univariant enum.  */
+  else if (TYPE_NFIELDS (type) == 1 && streq (TYPE_FIELD_NAME (type, 0), ""))
     {
-      /* We assume that a union with a single field is a univariant
-	 enum.  */
       /* Smash this type to be a structure type.  We have to do this
 	 because the type has already been recorded.  */
       TYPE_CODE (type) = TYPE_CODE_STRUCT;
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index fd76144..f42a0a3c 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2019-10-03  Tom Tromey  <tom@tromey.com>
+
+	PR rust/24976:
+	* gdb.rust/simple.rs (Union2): New type.
+	(main): Use Union2.
+	* gdb.rust/simple.exp: Add test.
+
 2019-10-03  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* gdb.fortran/nested-funcs-2.exp: Run tests with and without the
diff --git a/gdb/testsuite/gdb.rust/simple.exp b/gdb/testsuite/gdb.rust/simple.exp
index 7211bd2..dcbfb90 100644
--- a/gdb/testsuite/gdb.rust/simple.exp
+++ b/gdb/testsuite/gdb.rust/simple.exp
@@ -309,6 +309,8 @@ gdb_test_sequence "ptype/o SimpleLayout" "" {
     "                         }"
 }
 
+gdb_test "print u2" " = simple::Union2 {name: \\\[1\\\]}"
+
 # PR rust/23626 - this used to crash.  Note that the results are
 # fairly lax because most existing versions of Rust (those before the
 # DW_TAG_variant patches) do not emit what gdb wants here; and there
diff --git a/gdb/testsuite/gdb.rust/simple.rs b/gdb/testsuite/gdb.rust/simple.rs
index e6e0efd..65b57f4 100644
--- a/gdb/testsuite/gdb.rust/simple.rs
+++ b/gdb/testsuite/gdb.rust/simple.rs
@@ -85,6 +85,10 @@ union Union {
     f2: u8,
 }
 
+pub union Union2 {
+    pub name: [u8; 1],
+}
+
 struct StringAtOffset {
     pub field1: &'static str,
     pub field2: i32,
@@ -180,6 +184,8 @@ fn main () {
 
     let empty_enum_value: EmptyEnum;
 
+    let u2 = Union2 { name: [1] };
+
     println!("{}, {}", x.0, x.1);        // set breakpoint here
     println!("{}", diff2(92, 45));
     empty();


                 reply	other threads:[~2019-10-04  2:56 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20191004025632.126448.qmail@sourceware.org \
    --to=tromey@sourceware.org \
    --cc=gdb-cvs@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).