This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
cp-valprint.c, always pass valaddr == value->contents to val_print & co
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 25 Jan 2011 15:22:49 +0000
- Subject: cp-valprint.c, always pass valaddr == value->contents to val_print & co
Following up on <http://sourceware.org/ml/gdb-patches/2010-10/msg00127.html>,
This cp-valprint.c code path violates the
"always pass valaddr == value->contents to val_print & co" assertion I
mentioned adding before. Ensuring that's always true allows:
- querying the passed in value for metadata about the
contents/valaddr+embedded_offset we're handling.
- at some point in the future actually getting rid of the valaddr parameter.
Tested on x86_64-linux and applied.
--
Pedro Alves
2011-01-25 Pedro Alves <pedro@codesourcery.com>
gdb/
* cp-valprint.c (cp_print_value): Treat the 'skip' local as
boolean. Make sure to always pass a value that matches the
contents buffer to callees. Preserve `address' for following
iterations.
* value.c (value_contents_for_printing_const): New.
(value_address): Constify value argument.
* value.h (value_contents_for_printing_const): Declare.
(value_address): Constify value argument.
---
gdb/cp-valprint.c | 35 +++++++++++++++++++++++------------
gdb/value.c | 9 ++++++++-
gdb/value.h | 8 +++++++-
3 files changed, 38 insertions(+), 14 deletions(-)
Index: src/gdb/cp-valprint.c
===================================================================
--- src.orig/gdb/cp-valprint.c 2011-01-25 09:09:07.000000000 +0000
+++ src/gdb/cp-valprint.c 2011-01-25 13:05:13.107639996 +0000
@@ -488,6 +488,7 @@ cp_print_value (struct type *type, struc
struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
char *basename = TYPE_NAME (baseclass);
const gdb_byte *base_valaddr;
+ const struct value *base_val;
if (BASETYPE_VIA_VIRTUAL (type, i))
{
@@ -509,7 +510,7 @@ cp_print_value (struct type *type, struc
boffset = baseclass_offset (type, i, valaddr + offset,
address + offset);
- skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1;
+ skip = ((boffset == -1) || (boffset + offset) < 0);
if (BASETYPE_VIA_VIRTUAL (type, i))
{
@@ -525,20 +526,28 @@ cp_print_value (struct type *type, struc
large. */
gdb_byte *buf = alloca (TYPE_LENGTH (baseclass));
- base_valaddr = buf;
if (target_read_memory (address + boffset, buf,
TYPE_LENGTH (baseclass)) != 0)
skip = 1;
- address = address + boffset;
+ base_val = value_from_contents_and_address (baseclass,
+ buf,
+ address + boffset);
thisoffset = 0;
boffset = 0;
thistype = baseclass;
+ base_valaddr = value_contents_for_printing_const (base_val);
}
else
- base_valaddr = valaddr;
+ {
+ base_valaddr = valaddr;
+ base_val = val;
+ }
}
else
- base_valaddr = valaddr;
+ {
+ base_valaddr = valaddr;
+ base_val = val;
+ }
/* Now do the printing. */
if (options->pretty)
@@ -553,7 +562,7 @@ cp_print_value (struct type *type, struc
fputs_filtered ("> = ", stream);
- if (skip >= 1)
+ if (skip)
fprintf_filtered (stream, "<invalid address>");
else
{
@@ -564,15 +573,17 @@ cp_print_value (struct type *type, struc
if (!options->raw)
result = apply_val_pretty_printer (baseclass, base_valaddr,
thisoffset + boffset,
- address,
- stream, recurse,
- val, options,
- current_language);
+ value_address (base_val),
+ stream, recurse, base_val,
+ options, current_language);
+
+
if (!result)
cp_print_value_fields (baseclass, thistype, base_valaddr,
- thisoffset + boffset, address,
- stream, recurse, val, options,
+ thisoffset + boffset,
+ value_address (base_val),
+ stream, recurse, base_val, options,
((struct type **)
obstack_base (&dont_print_vb_obstack)),
0);
Index: src/gdb/value.c
===================================================================
--- src.orig/gdb/value.c 2011-01-24 21:32:37.000000000 +0000
+++ src/gdb/value.c 2011-01-25 13:08:23.447639990 +0000
@@ -435,6 +435,13 @@ value_contents_for_printing (struct valu
}
const gdb_byte *
+value_contents_for_printing_const (const struct value *value)
+{
+ gdb_assert (!value->lazy);
+ return value->contents;
+}
+
+const gdb_byte *
value_contents_all (struct value *value)
{
const gdb_byte *result = value_contents_for_printing (value);
@@ -596,7 +603,7 @@ deprecated_value_lval_hack (struct value
}
CORE_ADDR
-value_address (struct value *value)
+value_address (const struct value *value)
{
if (value->lval == lval_internalvar
|| value->lval == lval_internalvar_component)
Index: src/gdb/value.h
===================================================================
--- src.orig/gdb/value.h 2011-01-24 21:32:37.000000000 +0000
+++ src/gdb/value.h 2011-01-25 15:17:06.517639989 +0000
@@ -273,6 +273,12 @@ extern const gdb_byte *value_contents_al
plan to check the validity manually. */
extern const gdb_byte *value_contents_for_printing (struct value *value);
+/* Like value_contents_for_printing, but accepts a constant value
+ pointer. Unlike value_contents_for_printing however, the pointed
+ value must _not_ be lazy. */
+extern const gdb_byte *
+ value_contents_for_printing_const (const struct value *value);
+
extern int value_fetch_lazy (struct value *val);
extern int value_contents_equal (struct value *val1, struct value *val2);
@@ -308,7 +314,7 @@ extern enum lval_type *deprecated_value_
lval == lval_register, return the byte offset into the registers
structure. Otherwise, return 0. The returned address
includes the offset, if any. */
-extern CORE_ADDR value_address (struct value *);
+extern CORE_ADDR value_address (const struct value *);
/* Like value_address, except the result does not include value's
offset. */