(Ada) crash assigning to record component which is an array
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><ae9>: Abbrev Number: 7 (DW_TAG_structure_type) <aea> DW_AT_name : (indirect string, offset: 0x1045): target_wrapper__parameters [...] <2><af5>: Abbrev Number: 8 (DW_TAG_member) <af6> DW_AT_name : u2 [...] <afb> DW_AT_type : <0xaca> and, looking at DIE 0xaca to get input.u2's type, we see: <1><aca>: Abbrev Number: 4 (DW_TAG_typedef) <acb> DW_AT_name : (indirect string, offset: 0x1060): target_wrapper__float_array_3 [...] <ad1> DW_AT_type : <0xad5> We can also confirm, following the DW_AT_type attribute (0xad5), that it's a typedef of our array: <1><ad5>: Abbrev Number: 5 (DW_TAG_array_type) <ad6> 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.
This commit is contained in:
parent
cb923fcc23
commit
0e2da9f013
6 changed files with 91 additions and 3 deletions
|
@ -1,3 +1,9 @@
|
|||
2017-12-18 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* ada-lang.c (assign_component): Strip any TYPE_CODE_TYPEDEF
|
||||
layer from lhs' type.
|
||||
(assign_aggregate): Likewise.
|
||||
|
||||
2017-12-18 Xavier Roirand <roirand@adacore.com>
|
||||
|
||||
* ada-lang.c (ada_convert_actual): Change the way actual value
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2017-12-18 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* gdb.ada/assign_arr: New testcase.
|
||||
|
||||
2017-12-18 Xavier Roirand <roirand@adacore.com>
|
||||
|
||||
* gdb.ada/funcall_ptr: New testcase.
|
||||
|
|
30
gdb/testsuite/gdb.ada/assign_arr.exp
Normal file
30
gdb/testsuite/gdb.ada/assign_arr.exp
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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\\)"
|
21
gdb/testsuite/gdb.ada/assign_arr/main_p324_051.adb
Normal file
21
gdb/testsuite/gdb.ada/assign_arr/main_p324_051.adb
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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;
|
26
gdb/testsuite/gdb.ada/assign_arr/target_wrapper.ads
Normal file
26
gdb/testsuite/gdb.ada/assign_arr/target_wrapper.ads
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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;
|
Loading…
Add table
Add a link
Reference in a new issue