Wrong value printed by info locals for dynamic object.
authorJoel Brobecker <brobecker@gnat.com>
Tue, 20 Apr 2010 22:26:57 +0000 (22:26 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Tue, 20 Apr 2010 22:26:57 +0000 (22:26 +0000)
The problem is printing the wrong value for dynamic local variables
when using the "info locals" command. Consider the following code:

   procedure Print (I1 : Positive; I2 : Positive) is
      type My_String is array (I1 .. I2) of Character;
      I : My_String := (others => 'A');
      S : String (1 .. I2 + 3) := (others => ' ');
   begin
      S (I1 .. I2) := String (I); --  BREAK
      Put_Line (S);
   end Print;

After the debugger stopped at BREAK, we try printing all local variables.
Here is what we get:

        (gdb) info locals
        i = "["00"]["00"]"
        s = "["00"]["00"]["00"]["00"]["00"]["00"]["00"]["00"]"

Curiously, printing their value using the "print" command works:

        (gdb) print i
        $1 = "AA"
        (gdb) print s
        $2 = "        "

We traced the problem to trying to get the contents of a variable
(call to value_contents) before "fix'ing" it.  For those not familiar
with the Ada language support, "fixing" a value consists of swapping
the value's dynamic type with a static version that is appropriate
for our actual value.  As a result, the dynamic type was used to
determine the value size, which is zero, and thus the value contents
was empty.

gdb/ChangeLog:

        * valprint.c (common_val_print): Fix the value before extracting
        its contents.
        * ada-lang.c (ada_to_fixed_value): Make this function extern.
        * ada-lang.h (ada_to_fixed_value): New function declaration.
        * ada-valprint.c (ada_value_print): Use ada_to_fixed_value
        to avoid code duplication and fix a bug in the handling of
        fixed types contents.

gdb/testsuite/ChangeLog:

        * gdb.ada/dyn_loc: New testcase.

gdb/ChangeLog
gdb/ada-lang.c
gdb/ada-lang.h
gdb/ada-valprint.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.ada/dyn_loc.exp [new file with mode: 0644]
gdb/testsuite/gdb.ada/dyn_loc/p.adb [new file with mode: 0644]
gdb/testsuite/gdb.ada/dyn_loc/pack.adb [new file with mode: 0644]
gdb/testsuite/gdb.ada/dyn_loc/pack.ads [new file with mode: 0644]
gdb/valprint.c

index 191e7f25abfce241e3d9b5da28fe56b98a90d9c6..dcf9cc5ba603ed609921bbb6187192bec96cbb34 100644 (file)
@@ -1,3 +1,13 @@
+2010-04-20  Joel Brobecker  <brobecker@adacore.com>
+
+       * valprint.c (common_val_print): Fix the value before extracting
+       its contents.
+       * ada-lang.c (ada_to_fixed_value): Make this function extern.
+       * ada-lang.h (ada_to_fixed_value): New function declaration.
+       * ada-valprint.c (ada_value_print): Use ada_to_fixed_value
+       to avoid code duplication and fix a bug in the handling of
+       fixed types contents.
+
 2010-04-20  Tom Tromey  <tromey@redhat.com>
 
        * dwarf2read.c (dwarf2_compute_name): Handle DW_AT_linkage_name.
index 121a3d3eda5f708b020abcecb72396377327af61..df8ff19f19534f17d03fb539d1da67ee0ac00254 100644 (file)
@@ -226,8 +226,6 @@ static int find_struct_field (char *, struct type *, int,
 static struct value *ada_to_fixed_value_create (struct type *, CORE_ADDR,
                                                 struct value *);
 
-static struct value *ada_to_fixed_value (struct value *);
-
 static int ada_resolve_function (struct ada_symbol_info *, int,
                                  struct value **, int, const char *,
                                  struct type *);
@@ -7449,7 +7447,7 @@ ada_to_fixed_value_create (struct type *type0, CORE_ADDR address,
    that correctly describes it.  Does not necessarily create a new
    value.  */
 
-static struct value *
+struct value *
 ada_to_fixed_value (struct value *val)
 {
   return ada_to_fixed_value_create (value_type (val),
index 77a63b74b5e4ad5678d873bc0200fc5bd70fbc22..017cff2548b1f5f1dd5dcce0b631e6f950e54987 100644 (file)
@@ -312,6 +312,8 @@ extern struct type *ada_to_fixed_type (struct type *, const gdb_byte *,
                                       CORE_ADDR, struct value *,
                                        int check_tag);
 
+extern struct value *ada_to_fixed_value (struct value *val);
+
 extern struct type *ada_template_to_fixed_record_type_1 (struct type *type,
                                                         const gdb_byte *valaddr,
                                                         CORE_ADDR address,
index 55901008475eacf668d99fb83fbf9c6d89dcc7b0..a1090dc318574b74a06ac2e96071e3176fe30621 100644 (file)
@@ -924,12 +924,9 @@ int
 ada_value_print (struct value *val0, struct ui_file *stream,
                 const struct value_print_options *options)
 {
-  const gdb_byte *valaddr = value_contents (val0);
-  CORE_ADDR address = value_address (val0);
-  struct type *type =
-    ada_to_fixed_type (value_type (val0), valaddr, address, NULL, 1);
-  struct value *val =
-    value_from_contents_and_address (type, valaddr, address);
+  struct value *val = ada_to_fixed_value (val0);
+  CORE_ADDR address = value_address (val);
+  struct type *type = value_type (val);
   struct value_print_options opts;
 
   /* If it is a pointer, indicate what it points to.  */
index d1aa33befb87c3c34377ed69bd92bff40f688619..8913d8962b9b8f9517f71fb919948e1164a41405 100644 (file)
@@ -1,3 +1,7 @@
+2010-04-20  Joel Brobecker  <brobecker@adacore.com>
+
+       * gdb.ada/dyn_loc: New testcase.
+
 2010-04-20  Chris Moller  <cmoller@redhat.com>
 
        PR 10867
diff --git a/gdb/testsuite/gdb.ada/dyn_loc.exp b/gdb/testsuite/gdb.ada/dyn_loc.exp
new file mode 100644 (file)
index 0000000..953bd5f
--- /dev/null
@@ -0,0 +1,53 @@
+# Copyright 2010 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/>.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+load_lib "ada.exp"
+
+set testdir "dyn_loc"
+set testfile "${testdir}/p"
+set srcfile ${srcdir}/${subdir}/${testfile}.adb
+set binfile ${objdir}/${subdir}/${testfile}
+
+file mkdir ${objdir}/${subdir}/${testdir}
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug ]] != "" } {
+  return -1
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "BREAK" ${testdir}/pack.adb]
+if ![runto "pack.adb:$bp_location" ] then {
+  return -1
+}
+
+set eol "\[\r\n\]+"
+
+set test "info locals"
+gdb_test_multiple "$test" "$test" {
+    -re "i = \"AA\"${eol}s = \"        \"" {
+        pass $test
+    }
+    -re "i = \"AA\"${eol}.*${eol}s = \"        \"" {
+        # The debugger printed the two local variable correctly, but
+        # it probably failed to NOT print some variables internally
+        # generated by the compiler.  This is a known issue.
+        xfail $test
+    }
+}
+
diff --git a/gdb/testsuite/gdb.ada/dyn_loc/p.adb b/gdb/testsuite/gdb.ada/dyn_loc/p.adb
new file mode 100644 (file)
index 0000000..f8fd801
--- /dev/null
@@ -0,0 +1,21 @@
+--  Copyright 2010 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 Pack; use Pack;
+
+procedure P is
+begin
+   Print (4, 5);
+end P;
diff --git a/gdb/testsuite/gdb.ada/dyn_loc/pack.adb b/gdb/testsuite/gdb.ada/dyn_loc/pack.adb
new file mode 100644 (file)
index 0000000..deb3d06
--- /dev/null
@@ -0,0 +1,29 @@
+--  Copyright 2010 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 Ada.Text_IO; use Ada.Text_IO;
+
+package body Pack is
+
+   procedure Print (I1 : Positive; I2 : Positive) is
+      type My_String is array (I1 .. I2) of Character;
+      I : My_String := (others => 'A');
+      S : String (1 .. I2 + 3) := (others => ' ');
+   begin
+      S (I1 .. I2) := String (I); --  BREAK
+      Put_Line (S);
+   end Print;
+
+end Pack;
diff --git a/gdb/testsuite/gdb.ada/dyn_loc/pack.ads b/gdb/testsuite/gdb.ada/dyn_loc/pack.ads
new file mode 100644 (file)
index 0000000..8925c79
--- /dev/null
@@ -0,0 +1,20 @@
+--  Copyright 2010 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 Pack is
+
+   procedure Print (I1 : Positive; I2 : Positive);
+
+end Pack;
index 3f21ae4617a3a45d930eed651be4d66ec59b8a36..d6ecc04741fdf934fe6d5d405b395861ecc3223b 100644 (file)
@@ -35,6 +35,7 @@
 #include "exceptions.h"
 #include "dfp.h"
 #include "python/python.h"
+#include "ada-lang.h"
 
 #include <errno.h>
 
@@ -361,6 +362,13 @@ common_val_print (struct value *val, struct ui_file *stream, int recurse,
   if (!value_check_printable (val, stream))
     return 0;
 
+  if (language->la_language == language_ada)
+    /* The value might have a dynamic type, which would cause trouble
+       below when trying to extract the value contents (since the value
+       size is determined from the type size which is unknown).  So
+       get a fixed representation of our value.  */
+    val = ada_to_fixed_value (val);
+
   return val_print (value_type (val), value_contents_all (val),
                    value_embedded_offset (val), value_address (val),
                    stream, recurse, options, language);