From patchwork Sat Jul 7 21:26:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergio Durigan Junior X-Patchwork-Id: 28279 Received: (qmail 55069 invoked by alias); 7 Jul 2018 21:26:34 -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 55059 invoked by uid 89); 7 Jul 2018 21:26:33 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=23373, abc, uint8_t, asd X-HELO: mx1.redhat.com Received: from mx3-rdu2.redhat.com (HELO mx1.redhat.com) (66.187.233.73) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 07 Jul 2018 21:26:32 +0000 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C1FEA81A4EBA for ; Sat, 7 Jul 2018 21:26:30 +0000 (UTC) Received: from psique.yyz.redhat.com (unused-10-15-17-196.yyz.redhat.com [10.15.17.196]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2D17C111E40F; Sat, 7 Jul 2018 21:26:28 +0000 (UTC) From: Sergio Durigan Junior To: GDB Patches Cc: Sergio Durigan Junior Subject: [PATCH] Fix PR c++/23373: GDB hangs when printing a struct with a static member of itself Date: Sat, 7 Jul 2018 17:26:17 -0400 Message-Id: <20180707212617.12964-1-sergiodj@redhat.com> X-IsSubscribed: yes This patch fixes a failure that happens when a structure has a static member whose type is the same as itself. From the bug report: Example code: struct A { static A Empty; int a; }; int main(void) { A a; return 0; } Output: (gdb) ptype/o A /* offset | size */ type = struct A { static struct A { static struct A { static struct A { static struct A { static struct A { static struct A { ... # infinite loop The problem here is that GDB is not taking into account the fact that static members inside a class/struct are not stored in the class/struct, and therefore they should not be accounted for during the display of the offsets/sizes. The fix is simple: we just check if the field we're dealing with (on c-typeprint.c:c_type_print_base_struct_union) is static, and if it is then we don't iterate over it. This patch also adds a new test for this case, and doesn't introduce any regressions. I believe it is important enough to be included in the 8.2 branch. OK? gdb/ChangeLog: yyyy-mm-dd Sergio Durigan Junior PR c++/23373 * c-typeprint.c (c_type_print_base_struct_union): Don't print offsets/sizes for static members of a class/struct. gdb/testsuite/ChangeLog: yyyy-mm-dd Sergio Durigan Junior PR c++/23373 * gdb.base/ptype-offsets.cc (struct static_member): New struct. (main) : New variable. * gdb.base/ptype-offsets.exp: Add test for printing a struct with a static member in it. --- gdb/c-typeprint.c | 2 +- gdb/testsuite/gdb.base/ptype-offsets.cc | 8 ++++++++ gdb/testsuite/gdb.base/ptype-offsets.exp | 11 +++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index c167e212de..eccb972f24 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -1168,7 +1168,7 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *stream, int newshow = show - 1; - if (flags->print_offsets + if (!is_static && flags->print_offsets && (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_STRUCT || TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION)) { diff --git a/gdb/testsuite/gdb.base/ptype-offsets.cc b/gdb/testsuite/gdb.base/ptype-offsets.cc index 7b01dbc5fb..e1aefe5bb3 100644 --- a/gdb/testsuite/gdb.base/ptype-offsets.cc +++ b/gdb/testsuite/gdb.base/ptype-offsets.cc @@ -177,6 +177,13 @@ struct asd void *f16; }; +/* See PR c++/23373. */ + +struct static_member +{ + static static_member Empty; + int abc; +}; int main (int argc, char *argv[]) @@ -188,6 +195,7 @@ main (int argc, char *argv[]) struct tyu e; struct asd f; uint8_t i; + static_member stmember; return 0; } diff --git a/gdb/testsuite/gdb.base/ptype-offsets.exp b/gdb/testsuite/gdb.base/ptype-offsets.exp index d8718d581b..ca0c5de7ee 100644 --- a/gdb/testsuite/gdb.base/ptype-offsets.exp +++ b/gdb/testsuite/gdb.base/ptype-offsets.exp @@ -328,3 +328,14 @@ gdb_test_multiple "$test" "$test" { pass $test } } + +# Test that printing a struct with a static member of itself doesn't +# get us into an infinite loop. +gdb_test "ptype/o static_member" \ + [multi_line \ +{/\* offset | size \*/ type = struct static_member \{} \ +{ static static_member Empty;} \ +{\/* 0 | 4 \*/ int abc;} \ +{} \ +{ /\* total size \(bytes\): 4 \*/} \ +{ \}}]