This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[commit/Ada] Handle reference to array descriptors


This patch is to help handle aliased array variables, such as:

   type Bounded is array (Integer range <>) of Integer;
   function New_Bounded (Low, High : Integer) return Bounded;
   BT : aliased Bounded := New_Bounded (Low => 1, High => 3);

In that case, the compiler describes variable "BT" as a reference
to a thin pointer, and GDB is unable to print its value:

    (gdb) p bt
    $1 =

The problems starts when ada_value_print deconstructs the struct
value into contents and address in order to call val_print. It
turns out in this case that "bt" is not an lval. In the debug
information, this variable's location is described as:

        .uleb128 0xd    # (DIE (0xe0) DW_TAG_variable)
        .ascii "bt\0"   # DW_AT_name
        [...]
        .byte   0x6     # DW_AT_location
        .byte   0x91    # DW_OP_fbreg
        .sleb128 -56
        .byte   0x6     # DW_OP_deref
        .byte   0x23    # DW_OP_plus_uconst
        .uleb128 0x8
        .byte   0x9f    # DW_OP_stack_value

So, when ada_value_print passes the bt's (value) address, it passes
in effect a meaningless address. The problem continues shortly after
when ada_val_print_1 re-creates the value from the contents and address.
The value has become an lval_memory, with a null address.

As a result, we trigger a memory error later on, while trying to
read the array bounds in order to transform our value into a simple
array.

To avoid the problem entirely, the fix is to coerce references before
transforming array descriptors into simple arrays.

gdb/ChangeLog:

        * ada-valprint.c (ada_val_print_1): If our value is a reference
        to an array descriptor, dereference it before converting it
        to a simple array.

gdb/testsuite/ChangeLog:

        * gdb.ada/aliased_array: New testcase.

Tested on x86_64-linux.  Checked in.

---
 gdb/ChangeLog                               |    6 ++++
 gdb/ada-valprint.c                          |    4 +++
 gdb/testsuite/ChangeLog                     |    4 +++
 gdb/testsuite/gdb.ada/aliased_array.exp     |   36 +++++++++++++++++++++++++++
 gdb/testsuite/gdb.ada/aliased_array/foo.adb |   22 ++++++++++++++++
 gdb/testsuite/gdb.ada/aliased_array/pck.adb |   30 ++++++++++++++++++++++
 gdb/testsuite/gdb.ada/aliased_array/pck.ads |   21 +++++++++++++++
 7 files changed, 123 insertions(+), 0 deletions(-)
 create mode 100644 gdb/testsuite/gdb.ada/aliased_array.exp
 create mode 100644 gdb/testsuite/gdb.ada/aliased_array/foo.adb
 create mode 100644 gdb/testsuite/gdb.ada/aliased_array/pck.adb
 create mode 100644 gdb/testsuite/gdb.ada/aliased_array/pck.ads

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 064efa2..d09ed94 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
 2012-02-29  Joel Brobecker  <brobecker@adacore.com>
 
+	* ada-valprint.c (ada_val_print_1): If our value is a reference
+	to an array descriptor, dereference it before converting it
+	to a simple array.
+
+2012-02-29  Joel Brobecker  <brobecker@adacore.com>
+
 	* ada-lang.c (ada_to_fixed_value): Call unwrap_value before
 	creating fixed value.
 	(ada_value_ind, ada_coerce_ref, assign_component)
diff --git a/gdb/ada-valprint.c b/gdb/ada-valprint.c
index f43f3e3..5cb2f98 100644
--- a/gdb/ada-valprint.c
+++ b/gdb/ada-valprint.c
@@ -689,6 +689,10 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr,
       struct value *val;
 
       val = value_from_contents_and_address (type, valaddr + offset, address);
+      /* If this is a reference, coerce it now.  This helps taking care
+	 of the case where ADDRESS is meaningless because original_value
+	 was not an lval.  */
+      val = coerce_ref (val);
       if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)  /* array access type.  */
 	val = ada_coerce_to_simple_array_ptr (val);
       else
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 8a144bc..af77953 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
 2012-02-29  Joel Brobecker  <brobecker@adacore.com>
 
+	* gdb.ada/aliased_array: New testcase.
+
+2012-02-29  Joel Brobecker  <brobecker@adacore.com>
+
 	* gdb.ada/whatis_array_val: New testcase.
 
 2012-02-29  Jan Kratochvil  <jan.kratochvil@redhat.com>
diff --git a/gdb/testsuite/gdb.ada/aliased_array.exp b/gdb/testsuite/gdb.ada/aliased_array.exp
new file mode 100644
index 0000000..9fe30df
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/aliased_array.exp
@@ -0,0 +1,36 @@
+# Copyright 2012 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"
+
+if { [skip_ada_tests] } { return -1 }
+
+set testdir "aliased_array"
+set testfile "${testdir}/foo"
+set srcfile ${srcdir}/${subdir}/${testfile}.adb
+set binfile ${objdir}/${subdir}/${testfile}
+
+file mkdir ${objdir}/${subdir}/${testdir}
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} {
+    return -1
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "STOP" ${testdir}/foo.adb]
+runto "foo.adb:$bp_location"
+
+gdb_test "print bt" " = \\(1, 2, 3\\)"
+
diff --git a/gdb/testsuite/gdb.ada/aliased_array/foo.adb b/gdb/testsuite/gdb.ada/aliased_array/foo.adb
new file mode 100644
index 0000000..28acc87
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/aliased_array/foo.adb
@@ -0,0 +1,22 @@
+--  Copyright 2012 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 Pck; use Pck;
+procedure Foo is
+   BT : aliased Bounded := New_Bounded (Low => 1, High => 3);
+begin
+   Do_Nothing (BT'Address); -- STOP
+end Foo;
+
diff --git a/gdb/testsuite/gdb.ada/aliased_array/pck.adb b/gdb/testsuite/gdb.ada/aliased_array/pck.adb
new file mode 100644
index 0000000..29de743
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/aliased_array/pck.adb
@@ -0,0 +1,30 @@
+--  Copyright 2012 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 body Pck is
+   function New_Bounded (Low, High : Integer) return Bounded is
+      Result : Bounded (Low .. High);
+   begin
+      for J in Low .. High loop
+         Result (J) := J;
+      end loop;
+      return Result;
+   end New_Bounded;
+
+   procedure Do_Nothing (A : System.Address) is
+   begin
+      null;
+   end Do_Nothing;
+end Pck;
diff --git a/gdb/testsuite/gdb.ada/aliased_array/pck.ads b/gdb/testsuite/gdb.ada/aliased_array/pck.ads
new file mode 100644
index 0000000..bfff520
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/aliased_array/pck.ads
@@ -0,0 +1,21 @@
+--  Copyright 2012 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 System;
+package Pck is
+   type Bounded is array (Integer range <>) of Integer;
+   function New_Bounded (Low, High : Integer) return Bounded;
+   procedure Do_Nothing (A : System.Address);
+end Pck;
-- 
1.7.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]