From patchwork Fri Oct 4 02:55:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 34825 Received: (qmail 125408 invoked by alias); 4 Oct 2019 02:55:49 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 125399 invoked by uid 89); 4 Oct 2019 02:55:49 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=Union, old-style, oldstyle, single-element X-HELO: gateway36.websitewelcome.com Received: from gateway36.websitewelcome.com (HELO gateway36.websitewelcome.com) (192.185.188.18) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 04 Oct 2019 02:55:45 +0000 Received: from cm10.websitewelcome.com (cm10.websitewelcome.com [100.42.49.4]) by gateway36.websitewelcome.com (Postfix) with ESMTP id 9A1EE40137AD2 for ; Thu, 3 Oct 2019 21:02:23 -0500 (CDT) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id GDkui0Z9RHunhGDkuihwji; Thu, 03 Oct 2019 21:55:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version :Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=1LzaV3vb0cq46nAWjvB7HHOF9hoXtpmi3eWJMhWoTc8=; b=VmSqKNqW1UTHoj4xN16xfC2LAf c+GZjtyXotXk8vUT75GKZ8yykXV6tguI9CEtAslIGBpgklIG4pthCbYjVrII32fY7hrvqQSgpz5lX Gudw/IhfuTOYajPDFnD7lFYhW; Received: from 75-166-72-156.hlrn.qwest.net ([75.166.72.156]:46200 helo=bapiya.Home) by box5379.bluehost.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92) (envelope-from ) id 1iGDku-0038fn-0y; Thu, 03 Oct 2019 20:55:44 -0600 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [FYI] Avoid crash on single-field union in Rust Date: Thu, 3 Oct 2019 20:55:40 -0600 Message-Id: <20191004025540.22599-1-tom@tromey.com> 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 PR rust/24976: * dwarf2read.c (quirk_rust_enum): Handle single-element unions. gdb/testsuite/ChangeLog 2019-10-03 Tom Tromey PR rust/24976: * gdb.rust/simple.rs (Union2): New type. (main): Use Union2. * gdb.rust/simple.exp: Add test. --- 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/dwarf2read.c b/gdb/dwarf2read.c index c0dd199a797..ee9df34ed27 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) = "<>"; } - 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/gdb.rust/simple.exp b/gdb/testsuite/gdb.rust/simple.exp index 7211bd29be2..dcbfb90920f 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 e6e0efd3b16..65b57f42df6 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();