From patchwork Sat Jan 20 01:03:34 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: 25466 Received: (qmail 84223 invoked by alias); 20 Jan 2018 01:03:43 -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 84202 invoked by uid 89); 20 Jan 2018 01:03:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=2388, HX-Greylist:Sat X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 20 Jan 2018 01:03:41 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0DF4C61B9C; Sat, 20 Jan 2018 01:03:40 +0000 (UTC) Received: from psique.yyz.redhat.com (unused-10-15-17-193.yyz.redhat.com [10.15.17.193]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1BDC35C8A9; Sat, 20 Jan 2018 01:03:37 +0000 (UTC) From: Sergio Durigan Junior To: GDB Patches Cc: Eli Zaretskii , Pedro Alves , Sergio Durigan Junior Subject: [PATCH] Fix segfault when using 'set print object on' + whatis Date: Fri, 19 Jan 2018 20:03:34 -0500 Message-Id: <20180120010334.7694-1-sergiodj@redhat.com> In-Reply-To: <20180116203239.27787-1-sergiodj@redhat.com> References: <20180116203239.27787-1-sergiodj@redhat.com> X-IsSubscribed: yes This problem was hidden behind a "maybe-uninitialized" warning generated when compiling GDB with a recent GCC. The warning is: ../../gdb/typeprint.c: In function 'void whatis_exp(const char*, int)': ../../gdb/typeprint.c:515:12: warning: 'val' may be used uninitialized in this function [-Wmaybe-uninitialized] real_type = value_rtti_type (val, &full, &top, &using_enc); ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I submitted a patch fixing this by initializing "val" to NULL, but it was the wrong fix, as Pedro pointed out on : (gdb) set print object on (gdb) whatis some_structure_type Thread 1 "gdb" received signal SIGSEGV, Segmentation fault. 0x00000000005dda90 in check_typedef (type=0x6120736573756170) at src/gdb/gdbtypes.c:2388 2388 int instance_flags = TYPE_INSTANCE_FLAGS (type); ... So I set off to find the cause of the problem. It turns out that a recent-ish refactoring of the code on 'whatis_exp', introduced by: commit c973d0aa4a2c737ab527ae44a617f1c357e07364 Date: Mon Aug 21 11:34:32 2017 +0100 Fix type casts losing typedefs and reimplement "whatis" typedef stripping was the reason of the failure. After investigating what 'set print object on' was supposed to do to the output of 'whatis', if made sense initialize "val = evaluate_type (expr.get ());" all the time, not only when we're dealing with the 'ptype' command. I've regtested this on the BuildBot, without seeing any regressions. I've also extended 'gdb.base/whatis.exp' to check if the segfault is not there anymore. gdb/ChangeLog: yyyy-mm-dd Sergio Durigan Junior * typeprint.c (whatis_exp): Move initialization of "val" outside of "if". gdb/testsuite/ChangeLog: yyyy-mm-dd Sergio Durigan Junior * gdb.base/whatis.exp: Test that 'set print object on' + 'whatis ' doesn't segfault. --- gdb/testsuite/gdb.base/whatis.exp | 7 +++++++ gdb/typeprint.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/gdb/testsuite/gdb.base/whatis.exp b/gdb/testsuite/gdb.base/whatis.exp index dd6aeb02f9..8207dab59c 100644 --- a/gdb/testsuite/gdb.base/whatis.exp +++ b/gdb/testsuite/gdb.base/whatis.exp @@ -566,3 +566,10 @@ gdb_test "whatis int (*)(void, int, int)" \ gdb_test "whatis int (*)(int, void, int)" \ "'void' invalid as parameter type" \ "whatis applied to function with 'void' parameter type" + +# Test that 'set print object on' + whatis doesn't segfault. +clean_restart $binfile +gdb_test_no_output "set print object on" +gdb_test "whatis v_struct1" \ + "type = struct t_struct" \ + "whatis + set print object on doesn't segfault" diff --git a/gdb/typeprint.c b/gdb/typeprint.c index 9a125076a1..dd6e75bd4f 100644 --- a/gdb/typeprint.c +++ b/gdb/typeprint.c @@ -471,6 +471,8 @@ whatis_exp (const char *exp, int show) expression_up expr = parse_expression (exp); + val = evaluate_type (expr.get ()); + /* The behavior of "whatis" depends on whether the user expression names a type directly, or a language expression (including variable names). If the former, then "whatis" @@ -495,7 +497,6 @@ whatis_exp (const char *exp, int show) /* The user expression names a type indirectly by naming an object or expression of that type. Find that indirectly-named type. */ - val = evaluate_type (expr.get ()); type = value_type (val); } }