From patchwork Mon Dec 18 03:13:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Brobecker X-Patchwork-Id: 24986 Received: (qmail 106336 invoked by alias); 18 Dec 2017 03:13:40 -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 106325 invoked by uid 89); 18 Dec 2017 03:13:39 -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, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=aca, acb, aea X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 18 Dec 2017 03:13:37 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 1FB22116CDA; Sun, 17 Dec 2017 22:13:36 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id b30+d6MdAADD; Sun, 17 Dec 2017 22:13:36 -0500 (EST) Received: from tron.gnat.com (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) by rock.gnat.com (Postfix) with ESMTP id 10A9A116C73; Sun, 17 Dec 2017 22:13:36 -0500 (EST) Received: by tron.gnat.com (Postfix, from userid 4233) id 0CF6C43F; Sun, 17 Dec 2017 22:13:36 -0500 (EST) From: Joel Brobecker To: gdb-patches@sourceware.org Cc: Xavier Roirand Subject: [FYI/Ada/pushed] crash assigning to record component which is an array Date: Sun, 17 Dec 2017 22:13:34 -0500 Message-Id: <1513566814-128936-1-git-send-email-brobecker@adacore.com> Hello, Consider the following code, which declares a variabled called "input" of type "parameter", which is a record with one component called "u2", where the type of that component is a simple 3-element array of floating point values: type Float_Array_3 is array (1 .. 3) of Float; type parameters is record u2 : Float_Array_3; end record; input : parameters; Trying to assign a value to input.u2 causes GDB to crash: (gdb) p input.u2 := (0.25,0.5,0.75) [1] 20228 segmentation fault (core dumped) [...]/gdb The crash occurs because input.u2 is described in the debugging info as a typedef of an array. Indeed, input's type is: <1>: Abbrev Number: 7 (DW_TAG_structure_type) DW_AT_name : (indirect string, offset: 0x1045): target_wrapper__parameters [...] <2>: Abbrev Number: 8 (DW_TAG_member) DW_AT_name : u2 [...] DW_AT_type : <0xaca> and, looking at DIE 0xaca to get input.u2's type, we see: <1>: Abbrev Number: 4 (DW_TAG_typedef) DW_AT_name : (indirect string, offset: 0x1060): target_wrapper__float_array_3 [...] DW_AT_type : <0xad5> We can also confirm, following the DW_AT_type attribute (0xad5), that it's a typedef of our array: <1>: Abbrev Number: 5 (DW_TAG_array_type) DW_AT_name : (indirect string, offset: 0x1060): target_wrapper__float_array_3 [...] In fact, this scenario uncovered 2 areas where typedef handling is missing, thus causing a crash. The first happens inside assign_aggregate: if (ada_is_direct_array_type (lhs_type)) { lhs = ada_coerce_to_simple_array (lhs); lhs_type = value_type (lhs); low_index = TYPE_ARRAY_LOWER_BOUND_VALUE (lhs_type); high_index = TYPE_ARRAY_UPPER_BOUND_VALUE (lhs_type); } Here, lhs_type is a TYPE_CODE_TYPEDEF. ada_is_direct_array_type knows how to handle it, but TYPE_ARRAY_LOWER_BOUND_VALUE assumes that the given type is a TYPE_CODE_ARRAY. As such, it ends up accessing some fields in lhs_type which it shouldn't, and kaboom. We fixed this issue by making sure that the TYPE_CODE_TYPEDEF layer gets stripped. Once this is done, we hit a different kind of error, also leading to a SEGV, this time in assign_component. The code looks like this: if (TYPE_CODE (value_type (lhs)) == TYPE_CODE_ARRAY) [...] else [...] Because once again lhs is a TYPE_CODE_TYPEDEF, the check fail, and we end up assuming that lhs is a struct, executing the "else" block, which is: else { elt = ada_index_struct_field (index, lhs, 0, value_type (lhs)); elt = ada_to_fixed_value (elt); } Since lhs is not a struct, ada_index_struct_field returns NULL, which ada_to_fixed_value does not handle well, hence another crash. This patch fixes this other issue the same way, by stripping TYPE_CODE_TYPEDEF layers. gdb/ChangeLog: * ada-lang.c (assign_component): Strip any TYPE_CODE_TYPEDEF layer from lhs' type. (assign_aggregate): Likewise. gdb/testsuite: * gdb.ada/assign_arr: New testcase. Tested on x86_64-linux and pushed to master. Thank you, diff --git a/gdb/ChangeLog b/gdb/ChangeLog index fd2700d..5e65e5f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2017-12-18 Joel Brobecker + + * ada-lang.c (assign_component): Strip any TYPE_CODE_TYPEDEF + layer from lhs' type. + (assign_aggregate): Likewise. + 2017-12-18 Xavier Roirand * ada-lang.c (ada_convert_actual): Change the way actual value diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 8a0423e..14a0bd6 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -9960,8 +9960,9 @@ assign_component (struct value *container, struct value *lhs, LONGEST index, { struct value *mark = value_mark (); struct value *elt; + struct type *lhs_type = check_typedef (value_type (lhs)); - if (TYPE_CODE (value_type (lhs)) == TYPE_CODE_ARRAY) + if (TYPE_CODE (lhs_type) == TYPE_CODE_ARRAY) { struct type *index_type = builtin_type (exp->gdbarch)->builtin_int; struct value *index_val = value_from_longest (index_type, index); @@ -10020,11 +10021,11 @@ assign_aggregate (struct value *container, if (!deprecated_value_modifiable (lhs)) error (_("Left operand of assignment is not a modifiable lvalue.")); - lhs_type = value_type (lhs); + lhs_type = check_typedef (value_type (lhs)); if (ada_is_direct_array_type (lhs_type)) { lhs = ada_coerce_to_simple_array (lhs); - lhs_type = value_type (lhs); + lhs_type = check_typedef (value_type (lhs)); low_index = TYPE_ARRAY_LOWER_BOUND_VALUE (lhs_type); high_index = TYPE_ARRAY_UPPER_BOUND_VALUE (lhs_type); } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 3075686..c074186 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-12-18 Joel Brobecker + + * gdb.ada/assign_arr: New testcase. + 2017-12-18 Xavier Roirand * gdb.ada/funcall_ptr: New testcase. diff --git a/gdb/testsuite/gdb.ada/assign_arr.exp b/gdb/testsuite/gdb.ada/assign_arr.exp new file mode 100644 index 0000000..7129f22 --- /dev/null +++ b/gdb/testsuite/gdb.ada/assign_arr.exp @@ -0,0 +1,30 @@ +# Copyright 2016-2017 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +load_lib "ada.exp" + +standard_ada_testfile main_p324_051 + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } { + return -1 +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "STOP" ${testdir}/main_p324_051.adb] +runto "main_p324_051.adb:$bp_location" + +gdb_test "print input.u2 := (0.25,0.5,0.75)" \ + " = \\(0\\.25, 0\\.5, 0\\.75\\)" diff --git a/gdb/testsuite/gdb.ada/assign_arr/main_p324_051.adb b/gdb/testsuite/gdb.ada/assign_arr/main_p324_051.adb new file mode 100644 index 0000000..519c7b5 --- /dev/null +++ b/gdb/testsuite/gdb.ada/assign_arr/main_p324_051.adb @@ -0,0 +1,21 @@ +-- Copyright 2016-2017 Free Software Foundation, Inc. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with target_wrapper; use target_wrapper; + +procedure Main_P324_051 is +begin + input.u2 := (0.2,0.3,0.4); -- STOP +end Main_P324_051; diff --git a/gdb/testsuite/gdb.ada/assign_arr/target_wrapper.ads b/gdb/testsuite/gdb.ada/assign_arr/target_wrapper.ads new file mode 100644 index 0000000..d4a0417 --- /dev/null +++ b/gdb/testsuite/gdb.ada/assign_arr/target_wrapper.ads @@ -0,0 +1,26 @@ +-- Copyright 2016-2017 Free Software Foundation, Inc. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +package target_wrapper is + + type Float_Array_3 is array (1 .. 3) of Float; + + type parameters is record + u2 : Float_Array_3; + end record; + + input : parameters; + +end target_wrapper;