summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@gnat.com>2010-04-20 22:26:56 +0000
committerJoel Brobecker <brobecker@gnat.com>2010-04-20 22:26:56 +0000
commit36ccd968aa12f631c23256b314822943f1e4ac22 (patch)
treec1a3b93dc3195ffa6a41b452d021f29f19dc66aa
parentc0fe155d4ef80977ebeab93976d0f1f25516e783 (diff)
downloadgdb-36ccd968aa12f631c23256b314822943f1e4ac22.tar.gz
Wrong value printed by info locals for dynamic object.
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.
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/ada-lang.c4
-rw-r--r--gdb/ada-lang.h2
-rw-r--r--gdb/ada-valprint.c9
-rw-r--r--gdb/testsuite/ChangeLog4
-rw-r--r--gdb/testsuite/gdb.ada/dyn_loc.exp53
-rw-r--r--gdb/testsuite/gdb.ada/dyn_loc/p.adb21
-rw-r--r--gdb/testsuite/gdb.ada/dyn_loc/pack.adb29
-rw-r--r--gdb/testsuite/gdb.ada/dyn_loc/pack.ads20
-rw-r--r--gdb/valprint.c8
10 files changed, 151 insertions, 9 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 191e7f25abf..dcf9cc5ba60 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 121a3d3eda5..df8ff19f195 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -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),
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
index 77a63b74b5e..017cff2548b 100644
--- a/gdb/ada-lang.h
+++ b/gdb/ada-lang.h
@@ -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,
diff --git a/gdb/ada-valprint.c b/gdb/ada-valprint.c
index 55901008475..a1090dc3185 100644
--- a/gdb/ada-valprint.c
+++ b/gdb/ada-valprint.c
@@ -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. */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index d1aa33befb8..8913d8962b9 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -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
index 00000000000..953bd5f45dc
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/dyn_loc.exp
@@ -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
index 00000000000..f8fd80153cc
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/dyn_loc/p.adb
@@ -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
index 00000000000..deb3d063063
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/dyn_loc/pack.adb
@@ -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
index 00000000000..8925c795ae5
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/dyn_loc/pack.ads
@@ -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;
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 3f21ae4617a..d6ecc04741f 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -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);