From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29739 invoked by alias); 24 Jan 2011 13:24:25 -0000 Received: (qmail 29722 invoked by uid 22791); 24 Jan 2011 13:24:20 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,TW_GC,TW_XA,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 24 Jan 2011 13:24:08 +0000 Received: (qmail 20165 invoked from network); 24 Jan 2011 13:24:06 -0000 Received: from unknown (HELO scottsdale.localnet) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 24 Jan 2011 13:24:06 -0000 From: Pedro Alves To: gdb-patches@sourceware.org Subject: Re: [RFA v2] valprint.c / *-valprint.c: Don't lose `embedded_offset' Date: Mon, 24 Jan 2011 16:56:00 -0000 User-Agent: KMail/1.13.5 (Linux/2.6.35-24-generic; KDE/4.5.1; x86_64; ; ) Cc: Joel Brobecker References: <201101241322.42902.pedro@codesourcery.com> In-Reply-To: <201101241322.42902.pedro@codesourcery.com> MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <201101241324.04771.pedro@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-01/txt/msg00459.txt.bz2 On Monday 24 January 2011 13:22:42, Pedro Alves wrote: > This is an updated version of the patch I posted here: > > > Compared to the previous patch, this fixes a bug in > array repeat repetition handling, and adds a testcase > to cover it. My previous patch also had SCM related changes, > but Tromey removed the SCM support from GDB meanwhile. > > Joel, there are Ada changes in the patch, are those okay? > > I have follow up patches that adjust other parts of GDB similarly, > and patches that make it so that val_print always gets a non-NULL > value to work with. > > Here's the original description of the patch more or less unchanged: > > > In a nutshell, the patch below makes sure in the value print routines > throughout, the `embedded_offset' passed around makes sense when > consulting the contents (or data about the contents) of the also passed > along "struct value *original_value". There are code paths where > that connection is lost. > > A bit of explaining on why this is necessary. In the context of > tracepoints, I'm adding support for partial/incomplete objects. That is, > say, when printing an array where only a few elements have been collected, > print what you can, and print something like "" > (like ) for what has not been collected. E.g., with: > > struct foo { > int a, b; > int array[10000]; > void *ptr; > }; > > struct foo2 { > int d, ef; > struct foo foo; > }; > > struct foo2 foo2; > > and a tracepoint that just collects "foo2.foo.array[0]", > when printing foo2 while inspecting the corresponding collected > traceframe, currently we get: > > (gdb) p foo2 > Cannot access memory at address 0x601080 > > This is GDB trying to read [&foo2, &foo2+sizeof foo2) for an lval_memory > value representing "foo2" and the read failing because required > memory is not "available" (it was not collected). > > vs afterwards, after all the necessary changes, we'll get something like: > > (gdb) p foo2 > $1 = {d = , ef = , foo = {a = , b = > , array = {12345678, > }, ptr = }} > > That is, we will still print what is available. > > This requires marking chunks of a value's contents buffer as "unavailable" > at value read time, and, at value print time, check whether the value > contents chunk being printed is "available". The "unavailable"-ness of > the contents needs to be part of the struct value itself, given that when > printing a value from the value history, you still want to know what is > or isn't available, without consulting the target (which may not > exist anymore). > > This value contents offset, is exactly `embedded_offset' in many > of the *valprint.c routines. E.g.:, > > /* Print data of type TYPE located at VALADDR (within GDB), which came from > the inferior at address ADDRESS, onto stdio stream STREAM according to > OPTIONS. The data at VALADDR is in target byte order. > > If the data are a string pointer, returns the number of string > characters printed. */ > > int > c_val_print (struct type *type, const gdb_byte *valaddr, int > embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, > const struct value *original_value, > const struct value_print_options *options) > > The comment is actually not 100% correct or clear. It's actually data of > type TYPE located at VALADDR + EMBEDDED_OFFSET, which came from the > inferior at address ADDRESS + EMBEDDED_OFFSET. ORIGINAL_VALUE, if > non-NULL, is what came from ADDRESS. (the patch doesn't fix this; there > are a bunch of copies of that comment around, and I want to fix them all > in one go in a followup, or maybe in a next revision of this patch). > > So, when printing, we want to check whether > [original_value->contents + embedded_offset, > original_value->contents + embedded_offset + TYPE_LENGTH (type)) > has been optimized out; if it has, print "$n = " or throw an > "value has been optimized out" error (preferably the former). If not > optimized out, check whether the same contents range value is actually > "available". If not, print "", otherwise, proceed printing > as usual. > > The root of the value print call tree is usually something > like this: > > val_print (value_type (val), > value_contents_for_printing (val), > value_embedded_offset (val), > value_address (val), stream, 0, > val, &opts, current_language); > > Then, in valprint.c/c-valprint.c/cp-valprint.c, subroutines where we pass > down valaddr and the `original_value', adjust embedded_offset as required > to move on to a sub-field, and pass down `valaddr' and `address' (see > c_val_print description above) unmodified. Thus, if original_value is > non-NULL, then valaddr is always equal to original_value->contents (that > is, value_contents_for_printing()). > > This works nicelly, and allows making use of the running embedded_offset > argument to query original_value whether the contents we're trying to print > are actually valid/available. > > But, not all are roses. There are code paths where the original > embedded_offset is lost, as e.g., when printing array elements. > The fix looks then simple: just add an embedded_offset parameter to > val_print_array_elements, and adjust the callers to not re-adjust > `valaddr' and `address' themselves, but to instead pass down an adjusted > embedded_offset (see the valprint.c and c-valprint.c hunks in the > patch below). > > Trouble is in languages other than C/C++ where the > advance-embedded_offset-don't-touch-valaddr-or-address contract > isn't compromised in many places. The patch below fixes all those places > as well. > > Along the way, I made places that were passing value_contents() to > val_print & co pass value_contents_for_printing(), value_embedded_offset() > instead, as is meant to be, as value_contents_for_printing is not as strict > about complaining about optimized out values (and in the > future "unavailable" values), but instead defers that to the subroutines > that actually do the printing, so we have a chance of printing as many > scalar fields of an object as possible, even if other parts of the object > have been optimized out or are "unavailable". > > I have GNAT 4.4.5 to cover gdb.ada testing, gfortran 4.4.5 for gdb.fortran, > gpc 20070904, based on gcc-4.1.3 for gdb.pascal, and gcj 4.4.5 for > gdb.java. I have no way of testing the D changes, though they are > quite small. > > I get no testsuite regressions with this patch applied on top of current > mainline. -- Pedro Alves 2011-01-24 Pedro Alves Don't lose embedded_offset in printing routines throughout. gdb/ * valprint.h (val_print_array_elements): Change prototype. * valprint.c (val_print_array_elements): Add `embedded_offset' parameter, and adjust to pass it down to val_print, while passing `valaddr' or `address' unmodified. Take embedded_offset into account when checking repetitions. * c-valprint.c (c_val_print): Pass embedded_offset to val_print_array_elements instead of adjusting `valaddr' and `address'. * m2-valprint.c (m2_print_array_contents, m2_val_print): Pass embedded_offset to val_print_array_elements instead of adjusting `valaddr'. * p-lang.h (pascal_object_print_value_fields): Adjust prototype. * p-valprint.c (pascal_val_print): Pass embedded_offset to val_print_array_elements and pascal_object_print_value_fields instead of adjusting `valaddr'. (pascal_object_print_value_fields): Add `offset' parameter, and adjust to use it. (pascal_object_print_value): Add `offset' parameter, and adjust to use it. (pascal_object_print_static_field): Use value_contents_for_printing/value_embedded_offset, rather than value_contents. * ada-valprint.c (val_print_packed_array_elements): Add `offset' parameter, and adjust to use it. Use value_contents_for_printing/value_embedded_offset, rather than value_contents. (ada_val_print): Rename `valaddr0' parameter to `valaddr'. (ada_val_print_array): Add `offset' parameter, and adjust to use it. (ada_val_print_1): Rename `valaddr0' parameter to `valaddr', and `embedded_offset' to `offset'. Don't re-adjust `valaddr'. Instead work with offsets. Use value_contents_for_printing/value_embedded_offset, rather than value_contents. Change `defer_val_int' local type to CORE_ADDR, and use value_from_pointer to extract a target pointer, rather than value_from_longest. (print_variant_part): Add `offset' parameter. Replace `outer_valaddr' parameter by a new `outer_offset' parameter. Don't re-adjust `valaddr'. Instead pass down adjusted offsets. (ada_value_print): Use value_contents_for_printing/value_embedded_offset, rather than value_contents. (print_record): Add `offset' parameter, and adjust to pass it down. (print_field_values): Add `offset' parameter. Replace `outer_valaddr' parameter by a new `outer_offset' parameter. Don't re-adjust `valaddr'. Instead pass down adjusted offsets. Use value_contents_for_printing/value_embedded_offset, rather than value_contents. * d-valprint.c (dynamic_array_type): Use value_contents_for_printing/value_embedded_offset, rather than value_contents. * jv-valprint.c (java_print_value_fields): Add `offset' parameter. Don't re-adjust `valaddr'. Instead pass down adjusted offsets. (java_print_value_fields): Take `offset' into account. Don't re-adjust `valaddr'. Instead pass down adjusted offsets. (java_val_print): Take `embedded_offset' into account. Pass it to java_print_value_fields. * f-valprint.c (f77_print_array_1): Add `embedded_offset' parameter. Don't re-adjust `valaddr' or `address'. Instead pass down adjusted offsets. (f77_print_array): Add `embedded_offset' parameter. Pass it down. (f_val_print): Take `embedded_offset' into account. gdb/testsuite/ * gdb.base/printcmds.c (some_struct): New struct and instance. * gdb.base/printcmds.exp (test_print_repeats_embedded_array): New procedure. : Call it. --- gdb/ada-valprint.c | 176 ++++++++++++++++++++--------------- gdb/c-valprint.c | 7 - gdb/d-valprint.c | 8 - gdb/f-valprint.c | 75 ++++++++------ gdb/jv-valprint.c | 42 ++++---- gdb/m2-valprint.c | 4 gdb/p-lang.h | 1 gdb/p-valprint.c | 48 ++++++--- gdb/testsuite/gdb.base/printcmds.c | 22 ++++ gdb/testsuite/gdb.base/printcmds.exp | 13 ++ gdb/valprint.c | 17 ++- gdb/valprint.h | 2 12 files changed, 262 insertions(+), 153 deletions(-) Index: src/gdb/valprint.h =================================================================== --- src.orig/gdb/valprint.h 2011-01-24 12:54:32.000000000 +0000 +++ src/gdb/valprint.h 2011-01-24 12:54:35.236177001 +0000 @@ -113,7 +113,7 @@ extern void maybe_print_array_index (str struct ui_file *stream, const struct value_print_options *); -extern void val_print_array_elements (struct type *, const gdb_byte *, +extern void val_print_array_elements (struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, const struct value *, const struct value_print_options *, Index: src/gdb/valprint.c =================================================================== --- src.orig/gdb/valprint.c 2011-01-24 12:54:32.000000000 +0000 +++ src/gdb/valprint.c 2011-01-24 13:10:43.486176996 +0000 @@ -1108,7 +1108,8 @@ maybe_print_array_index (struct type *in perhaps we should try to use that notation when appropriate. */ void -val_print_array_elements (struct type *type, const gdb_byte *valaddr, +val_print_array_elements (struct type *type, + const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, @@ -1171,8 +1172,10 @@ val_print_array_elements (struct type *t rep1 = i + 1; reps = 1; - while ((rep1 < len) && - !memcmp (valaddr + i * eltlen, valaddr + rep1 * eltlen, eltlen)) + while (rep1 < len + && memcmp (valaddr + embedded_offset + i * eltlen, + valaddr + embedded_offset + rep1 * eltlen, + eltlen) == 0) { ++reps; ++rep1; @@ -1180,8 +1183,9 @@ val_print_array_elements (struct type *t if (reps > options->repeat_count_threshold) { - val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen, - stream, recurse + 1, val, options, current_language); + val_print (elttype, valaddr, embedded_offset + i * eltlen, + address, stream, recurse + 1, val, options, + current_language); annotate_elt_rep (reps); fprintf_filtered (stream, " ", reps); annotate_elt_rep_end (); @@ -1191,7 +1195,8 @@ val_print_array_elements (struct type *t } else { - val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen, + val_print (elttype, valaddr, embedded_offset + i * eltlen, + address, stream, recurse + 1, val, options, current_language); annotate_elt (); things_printed++; Index: src/gdb/c-valprint.c =================================================================== --- src.orig/gdb/c-valprint.c 2011-01-24 12:54:32.000000000 +0000 +++ src/gdb/c-valprint.c 2011-01-24 12:54:35.246177002 +0000 @@ -233,10 +233,9 @@ c_val_print (struct type *type, const gd { i = 0; } - val_print_array_elements (type, valaddr + embedded_offset, - address + embedded_offset, - stream, recurse, - original_value, options, i); + val_print_array_elements (type, valaddr, embedded_offset, + address, stream, + recurse, original_value, options, i); fprintf_filtered (stream, "}"); } break; Index: src/gdb/m2-valprint.c =================================================================== --- src.orig/gdb/m2-valprint.c 2011-01-24 12:54:32.000000000 +0000 +++ src/gdb/m2-valprint.c 2011-01-24 12:54:35.246177002 +0000 @@ -300,7 +300,7 @@ m2_print_array_contents (struct type *ty else { fprintf_filtered (stream, "{"); - val_print_array_elements (type, valaddr + embedded_offset, + val_print_array_elements (type, valaddr, embedded_offset, address, stream, recurse, val, options, 0); fprintf_filtered (stream, "}"); @@ -370,7 +370,7 @@ m2_val_print (struct type *type, const g else { fprintf_filtered (stream, "{"); - val_print_array_elements (type, valaddr + embedded_offset, + val_print_array_elements (type, valaddr, embedded_offset, address, stream, recurse, original_value, options, 0); Index: src/gdb/p-valprint.c =================================================================== --- src.orig/gdb/p-valprint.c 2011-01-24 12:54:32.000000000 +0000 +++ src/gdb/p-valprint.c 2011-01-24 12:54:35.246177002 +0000 @@ -125,7 +125,7 @@ pascal_val_print (struct type *type, con { i = 0; } - val_print_array_elements (type, valaddr + embedded_offset, + val_print_array_elements (type, valaddr, embedded_offset, address, stream, recurse, original_value, options, i); fprintf_filtered (stream, "}"); @@ -327,7 +327,7 @@ pascal_val_print (struct type *type, con len, NULL, 0, options); } else - pascal_object_print_value_fields (type, valaddr + embedded_offset, + pascal_object_print_value_fields (type, valaddr, embedded_offset, address, stream, recurse, original_value, options, NULL, 0); @@ -629,6 +629,7 @@ static void pascal_object_print_static_f const struct value_print_options *); static void pascal_object_print_value (struct type *, const gdb_byte *, + int, CORE_ADDR, struct ui_file *, int, const struct value *, const struct value_print_options *, @@ -687,6 +688,7 @@ pascal_object_is_vtbl_member (struct typ void pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr, + int offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, @@ -706,8 +708,9 @@ pascal_object_print_value_fields (struct /* Print out baseclasses such that we don't print duplicates of virtual baseclasses. */ if (n_baseclasses > 0) - pascal_object_print_value (type, valaddr, address, stream, - recurse + 1, val, options, dont_print_vb); + pascal_object_print_value (type, valaddr, offset, address, + stream, recurse + 1, val, + options, dont_print_vb); if (!len && n_baseclasses == 1) fprintf_filtered (stream, ""); @@ -814,7 +817,8 @@ pascal_object_print_value_fields (struct struct value_print_options opts = *options; v = value_from_longest (TYPE_FIELD_TYPE (type, i), - unpack_field_as_long (type, valaddr, i)); + unpack_field_as_long (type, + valaddr + offset, i)); opts.deref_ref = 0; common_val_print (v, stream, recurse + 1, &opts, @@ -833,8 +837,9 @@ pascal_object_print_value_fields (struct v4.17 specific. */ struct value *v; - v = value_from_longest (TYPE_FIELD_TYPE (type, i), - unpack_field_as_long (type, valaddr, i)); + v = value_from_longest + (TYPE_FIELD_TYPE (type, i), + unpack_field_as_long (type, valaddr + offset, i)); if (v == NULL) fputs_filtered ("", stream); @@ -852,9 +857,8 @@ pascal_object_print_value_fields (struct address + TYPE_FIELD_BITPOS (type, i) / 8, 0, stream, format, 0, recurse + 1, pretty); */ val_print (TYPE_FIELD_TYPE (type, i), - valaddr, TYPE_FIELD_BITPOS (type, i) / 8, - address + TYPE_FIELD_BITPOS (type, i) / 8, - stream, recurse + 1, val, &opts, + valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8, + address, stream, recurse + 1, val, &opts, current_language); } } @@ -883,6 +887,7 @@ pascal_object_print_value_fields (struct static void pascal_object_print_value (struct type *type, const gdb_byte *valaddr, + int offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, @@ -909,6 +914,7 @@ pascal_object_print_value (struct type * struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); char *basename = type_name_no_tag (baseclass); const gdb_byte *base_valaddr; + int thisoffset; if (BASETYPE_VIA_VIRTUAL (type, i)) { @@ -925,7 +931,9 @@ pascal_object_print_value (struct type * obstack_ptr_grow (&dont_print_vb_obstack, baseclass); } - boffset = baseclass_offset (type, i, valaddr, address); + thisoffset = offset; + + boffset = baseclass_offset (type, i, valaddr + offset, address + offset); if (options->pretty) { @@ -952,16 +960,19 @@ pascal_object_print_value (struct type * if (target_read_memory (address + boffset, buf, TYPE_LENGTH (baseclass)) != 0) boffset = -1; + address = address + boffset; + thisoffset = 0; + boffset = 0; } else - base_valaddr = valaddr + boffset; + base_valaddr = valaddr; if (boffset == -1) fprintf_filtered (stream, ""); else pascal_object_print_value_fields (baseclass, base_valaddr, - address + boffset, stream, - recurse, val, options, + thisoffset + boffset, address, + stream, recurse, val, options, (struct type **) obstack_base (&dont_print_vb_obstack), 0); fputs_filtered (", ", stream); @@ -1025,9 +1036,12 @@ pascal_object_print_static_field (struct sizeof (CORE_ADDR)); CHECK_TYPEDEF (type); - pascal_object_print_value_fields (type, value_contents (val), addr, - stream, recurse, NULL, options, - NULL, 1); + pascal_object_print_value_fields (type, + value_contents_for_printing (val), + value_embedded_offset (val), + addr, + stream, recurse, + val, options, NULL, 1); return; } Index: src/gdb/ada-valprint.c =================================================================== --- src.orig/gdb/ada-valprint.c 2011-01-24 12:54:32.000000000 +0000 +++ src/gdb/ada-valprint.c 2011-01-24 12:54:35.246177002 +0000 @@ -36,17 +36,18 @@ #include "exceptions.h" #include "objfiles.h" -static void print_record (struct type *, const gdb_byte *, struct ui_file *, +static void print_record (struct type *, const gdb_byte *, int, + struct ui_file *, int, const struct value *, const struct value_print_options *); static int print_field_values (struct type *, const gdb_byte *, + int, struct ui_file *, int, const struct value *, const struct value_print_options *, - int, struct type *, - const gdb_byte *); + int, struct type *, int); static void adjust_type_signedness (struct type *); @@ -134,6 +135,7 @@ print_optional_low_bound (struct ui_file static void val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr, + int offset, int bitoffset, struct ui_file *stream, int recurse, const struct value *val, @@ -185,7 +187,7 @@ val_print_packed_array_elements (struct maybe_print_array_index (index_type, i + low, stream, options); i0 = i; - v0 = ada_value_primitive_packed_val (NULL, valaddr, + v0 = ada_value_primitive_packed_val (NULL, valaddr + offset, (i0 * bitsize) / HOST_CHAR_BIT, (i0 * bitsize) % HOST_CHAR_BIT, bitsize, elttype); @@ -194,7 +196,7 @@ val_print_packed_array_elements (struct i += 1; if (i >= len) break; - v1 = ada_value_primitive_packed_val (NULL, valaddr, + v1 = ada_value_primitive_packed_val (NULL, valaddr + offset, (i * bitsize) / HOST_CHAR_BIT, (i * bitsize) % HOST_CHAR_BIT, bitsize, elttype); @@ -207,7 +209,8 @@ val_print_packed_array_elements (struct struct value_print_options opts = *options; opts.deref_ref = 0; - val_print (elttype, value_contents (v0), 0, 0, stream, + val_print (elttype, value_contents_for_printing (v0), + value_embedded_offset (v0), 0, stream, recurse + 1, val, &opts, current_language); annotate_elt_rep (i - i0); fprintf_filtered (stream, _(" "), i - i0); @@ -237,7 +240,8 @@ val_print_packed_array_elements (struct maybe_print_array_index (index_type, j + low, stream, options); } - val_print (elttype, value_contents (v0), 0, 0, stream, + val_print (elttype, value_contents_for_printing (v0), + value_embedded_offset (v0), 0, stream, recurse + 1, val, &opts, current_language); annotate_elt (); } @@ -571,7 +575,7 @@ ada_printstr (struct ui_file *stream, st continuation lines; this amount is roughly twice the value of RECURSE. */ int -ada_val_print (struct type *type, const gdb_byte *valaddr0, +ada_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, @@ -580,9 +584,10 @@ ada_val_print (struct type *type, const volatile struct gdb_exception except; int result = 0; + /* XXX: this catches QUIT/ctrl-c as well. Isn't that busted? */ TRY_CATCH (except, RETURN_MASK_ALL) { - result = ada_val_print_1 (type, valaddr0, embedded_offset, address, + result = ada_val_print_1 (type, valaddr, embedded_offset, address, stream, recurse, val, options); } @@ -599,7 +604,8 @@ ada_val_print (struct type *type, const static int ada_val_print_array (struct type *type, const gdb_byte *valaddr, - CORE_ADDR address, struct ui_file *stream, int recurse, + int offset, CORE_ADDR address, + struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options) { @@ -636,12 +642,13 @@ ada_val_print_array (struct type *type, for (temp_len = 0; (temp_len < len && temp_len < options->print_max - && char_at (valaddr, temp_len, eltlen, byte_order) != 0); + && char_at (valaddr + offset, + temp_len, eltlen, byte_order) != 0); temp_len += 1); len = temp_len; } - printstr (stream, elttype, valaddr, len, 0, eltlen, options); + printstr (stream, elttype, valaddr + offset, len, 0, eltlen, options); result = len; } else @@ -649,11 +656,11 @@ ada_val_print_array (struct type *type, fprintf_filtered (stream, "("); print_optional_low_bound (stream, type, options); if (TYPE_FIELD_BITSIZE (type, 0) > 0) - val_print_packed_array_elements (type, valaddr, 0, stream, - recurse, val, options); + val_print_packed_array_elements (type, valaddr, offset, + 0, stream, recurse, val, options); else - val_print_array_elements (type, valaddr, address, stream, - recurse, val, options, 0); + val_print_array_elements (type, valaddr, offset, address, + stream, recurse, val, options, 0); fprintf_filtered (stream, ")"); } @@ -664,8 +671,8 @@ ada_val_print_array (struct type *type, does not catch evaluation errors (leaving that to ada_val_print). */ static int -ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, - int embedded_offset, CORE_ADDR address, +ada_val_print_1 (struct type *type, const gdb_byte *valaddr, + int offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *original_value, const struct value_print_options *options) @@ -674,7 +681,7 @@ ada_val_print_1 (struct type *type, cons int i; struct type *elttype; LONGEST val; - const gdb_byte *valaddr = valaddr0 + embedded_offset; + int offset_aligned; type = ada_check_typedef (type); @@ -685,7 +692,7 @@ ada_val_print_1 (struct type *type, cons struct value *mark = value_mark (); struct value *val; - val = value_from_contents_and_address (type, valaddr, address); + val = value_from_contents_and_address (type, valaddr + offset, address); if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) /* array access type. */ val = ada_coerce_to_simple_array_ptr (val); else @@ -697,32 +704,35 @@ ada_val_print_1 (struct type *type, cons retn = 0; } else - retn = ada_val_print_1 (value_type (val), value_contents (val), 0, + retn = ada_val_print_1 (value_type (val), + value_contents_for_printing (val), + value_embedded_offset (val), value_address (val), stream, recurse, NULL, options); value_free_to_mark (mark); return retn; } - valaddr = ada_aligned_value_addr (type, valaddr); - embedded_offset -= valaddr - valaddr0 - embedded_offset; - type = printable_val_type (type, valaddr); + offset_aligned = offset + ada_aligned_value_addr (type, valaddr) - valaddr; + type = printable_val_type (type, valaddr + offset_aligned); switch (TYPE_CODE (type)) { default: - return c_val_print (type, valaddr0, embedded_offset, address, stream, + return c_val_print (type, valaddr, offset, address, stream, recurse, original_value, options); case TYPE_CODE_PTR: { - int ret = c_val_print (type, valaddr0, embedded_offset, address, + int ret = c_val_print (type, valaddr, offset, address, stream, recurse, original_value, options); if (ada_is_tag_type (type)) { - struct value *val = - value_from_contents_and_address (type, valaddr, address); + struct value *val = + value_from_contents_and_address (type, + valaddr + offset_aligned, + address + offset_aligned); const char *name = ada_tag_name (val); if (name != NULL) @@ -736,7 +746,7 @@ ada_val_print_1 (struct type *type, cons case TYPE_CODE_RANGE: if (ada_is_fixed_point_type (type)) { - LONGEST v = unpack_long (type, valaddr); + LONGEST v = unpack_long (type, valaddr + offset_aligned); int len = TYPE_LENGTH (type); fprintf_filtered (stream, len < 4 ? "%.11g" : "%.17g", @@ -753,16 +763,18 @@ ada_val_print_1 (struct type *type, cons its base type. Perform a conversion, or we will get a nonsense value. Actually, we could use the same code regardless of lengths; I'm just avoiding a cast. */ - struct value *v = value_cast (target_type, - value_from_contents_and_address - (type, valaddr, 0)); - - return ada_val_print_1 (target_type, value_contents (v), 0, 0, - stream, recurse + 1, NULL, options); + struct value *v1 + = value_from_contents_and_address (type, valaddr + offset, 0); + struct value *v = value_cast (target_type, v1); + + return ada_val_print_1 (target_type, + value_contents_for_printing (v), + value_embedded_offset (v), 0, + stream, recurse + 1, NULL, options); } else return ada_val_print_1 (TYPE_TARGET_TYPE (type), - valaddr0, embedded_offset, + valaddr, offset, address, stream, recurse, original_value, options); } @@ -776,7 +788,8 @@ ada_val_print_1 (struct type *type, cons struct value_print_options opts = *options; opts.format = format; - print_scalar_formatted (valaddr, type, &opts, 0, stream); + print_scalar_formatted (valaddr + offset_aligned, + type, &opts, 0, stream); } else if (ada_is_system_address_type (type)) { @@ -788,7 +801,8 @@ ada_val_print_1 (struct type *type, cons struct gdbarch *gdbarch = get_type_arch (type); struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; - CORE_ADDR addr = extract_typed_address (valaddr, ptr_type); + CORE_ADDR addr = extract_typed_address (valaddr + offset_aligned, + ptr_type); fprintf_filtered (stream, "("); type_print (type, "", stream, -1); @@ -797,11 +811,14 @@ ada_val_print_1 (struct type *type, cons } else { - val_print_type_code_int (type, valaddr, stream); + val_print_type_code_int (type, valaddr + offset_aligned, stream); if (ada_is_character_type (type)) { + LONGEST c; + fputs_filtered (" ", stream); - ada_printchar (unpack_long (type, valaddr), type, stream); + c = unpack_long (type, valaddr + offset_aligned); + ada_printchar (c, type, stream); } } return 0; @@ -810,11 +827,12 @@ ada_val_print_1 (struct type *type, cons case TYPE_CODE_ENUM: if (options->format) { - print_scalar_formatted (valaddr, type, options, 0, stream); + print_scalar_formatted (valaddr + offset_aligned, + type, options, 0, stream); break; } len = TYPE_NFIELDS (type); - val = unpack_long (type, valaddr); + val = unpack_long (type, valaddr + offset_aligned); for (i = 0; i < len; i++) { QUIT; @@ -840,17 +858,18 @@ ada_val_print_1 (struct type *type, cons case TYPE_CODE_FLAGS: if (options->format) - print_scalar_formatted (valaddr, type, options, 0, stream); + print_scalar_formatted (valaddr + offset_aligned, + type, options, 0, stream); else - val_print_type_code_flags (type, valaddr, stream); + val_print_type_code_flags (type, valaddr + offset_aligned, stream); break; case TYPE_CODE_FLT: if (options->format) - return c_val_print (type, valaddr0, embedded_offset, address, stream, + return c_val_print (type, valaddr, offset, address, stream, recurse, original_value, options); else - ada_print_floating (valaddr0 + embedded_offset, type, stream); + ada_print_floating (valaddr + offset, type, stream); break; case TYPE_CODE_UNION: @@ -862,14 +881,15 @@ ada_val_print_1 (struct type *type, cons } else { - print_record (type, valaddr, stream, recurse, original_value, - options); + print_record (type, valaddr, offset_aligned, + stream, recurse, original_value, options); return 0; } case TYPE_CODE_ARRAY: - return ada_val_print_array (type, valaddr, address, stream, - recurse, original_value, options); + return ada_val_print_array (type, valaddr, offset_aligned, + address, stream, recurse, original_value, + options); case TYPE_CODE_REF: /* For references, the debugger is expected to print the value as @@ -881,17 +901,19 @@ ada_val_print_1 (struct type *type, cons if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { - LONGEST deref_val_int = (LONGEST) unpack_pointer (type, valaddr); + CORE_ADDR deref_val_int + = unpack_pointer (type, valaddr + offset_aligned); if (deref_val_int != 0) { struct value *deref_val = - ada_value_ind (value_from_longest + ada_value_ind (value_from_pointer (lookup_pointer_type (elttype), deref_val_int)); val_print (value_type (deref_val), - value_contents (deref_val), 0, + value_contents_for_printing (deref_val), + value_embedded_offset (deref_val), value_address (deref_val), stream, recurse + 1, original_value, options, current_language); } @@ -908,25 +930,28 @@ ada_val_print_1 (struct type *type, cons } static int -print_variant_part (struct type *type, int field_num, const gdb_byte *valaddr, +print_variant_part (struct type *type, int field_num, + const gdb_byte *valaddr, int offset, struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options, int comma_needed, - struct type *outer_type, const gdb_byte *outer_valaddr) + struct type *outer_type, int outer_offset) { struct type *var_type = TYPE_FIELD_TYPE (type, field_num); - int which = ada_which_variant_applies (var_type, outer_type, outer_valaddr); + int which = ada_which_variant_applies (var_type, outer_type, + valaddr + outer_offset); if (which < 0) return 0; else return print_field_values (TYPE_FIELD_TYPE (var_type, which), - valaddr + TYPE_FIELD_BITPOS (type, field_num) / HOST_CHAR_BIT + valaddr, + offset + TYPE_FIELD_BITPOS (type, field_num) / HOST_CHAR_BIT + TYPE_FIELD_BITPOS (var_type, which) / HOST_CHAR_BIT, stream, recurse, val, options, - comma_needed, outer_type, outer_valaddr); + comma_needed, outer_type, outer_offset); } int @@ -974,12 +999,14 @@ ada_value_print (struct value *val0, str opts = *options; opts.deref_ref = 1; - return (val_print (type, value_contents (val), 0, address, + return (val_print (type, value_contents_for_printing (val), + value_embedded_offset (val), address, stream, 0, val, &opts, current_language)); } static void print_record (struct type *type, const gdb_byte *valaddr, + int offset, struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options) @@ -988,8 +1015,9 @@ print_record (struct type *type, const g fprintf_filtered (stream, "("); - if (print_field_values (type, valaddr, stream, recurse, val, options, - 0, type, valaddr) != 0 && options->pretty) + if (print_field_values (type, valaddr, offset, + stream, recurse, val, options, + 0, type, offset) != 0 && options->pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * recurse, stream); @@ -1014,11 +1042,11 @@ print_record (struct type *type, const g static int print_field_values (struct type *type, const gdb_byte *valaddr, - struct ui_file *stream, int recurse, + int offset, struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options, int comma_needed, - struct type *outer_type, const gdb_byte *outer_valaddr) + struct type *outer_type, int outer_offset) { int i, len; @@ -1033,18 +1061,20 @@ print_field_values (struct type *type, c { comma_needed = print_field_values (TYPE_FIELD_TYPE (type, i), - valaddr - + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT, + valaddr, + (offset + + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT), stream, recurse, val, options, - comma_needed, type, valaddr); + comma_needed, type, offset); continue; } else if (ada_is_variant_part (type, i)) { comma_needed = print_variant_part (type, i, valaddr, - stream, recurse, val, options, comma_needed, - outer_type, outer_valaddr); + offset, stream, recurse, val, + options, comma_needed, + outer_type, outer_offset); continue; } @@ -1109,7 +1139,9 @@ print_field_values (struct type *type, c TYPE_FIELD_TYPE (type, i)); opts = *options; opts.deref_ref = 0; - val_print (TYPE_FIELD_TYPE (type, i), value_contents (v), 0, 0, + val_print (TYPE_FIELD_TYPE (type, i), + value_contents_for_printing (v), + value_embedded_offset (v), 0, stream, recurse + 1, v, &opts, current_language); } @@ -1120,8 +1152,10 @@ print_field_values (struct type *type, c opts.deref_ref = 0; ada_val_print (TYPE_FIELD_TYPE (type, i), - valaddr + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT, - 0, 0, stream, recurse + 1, val, &opts); + valaddr, + (offset + + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT), + 0, stream, recurse + 1, val, &opts); } annotate_field_end (); } Index: src/gdb/p-lang.h =================================================================== --- src.orig/gdb/p-lang.h 2011-01-24 12:54:32.000000000 +0000 +++ src/gdb/p-lang.h 2011-01-24 12:54:35.246177002 +0000 @@ -70,6 +70,7 @@ extern void pascal_type_print_varspec_prefix (struct type *, struct ui_file *, int, int); extern void pascal_object_print_value_fields (struct type *, const gdb_byte *, + int, CORE_ADDR, struct ui_file *, int, const struct value *, Index: src/gdb/d-valprint.c =================================================================== --- src.orig/gdb/d-valprint.c 2011-01-24 12:54:32.000000000 +0000 +++ src/gdb/d-valprint.c 2011-01-24 12:54:35.246177002 +0000 @@ -45,7 +45,6 @@ dynamic_array_type (struct type *type, c struct type *elttype; struct type *true_type; struct type *ptr_type; - const gdb_byte *ptraddr; struct value *val; int length; @@ -60,10 +59,11 @@ dynamic_array_type (struct type *type, c true_type = lookup_array_range_type (true_type, 0, length - 1); val = value_at (true_type, addr); - ptraddr = value_contents (val); - return d_val_print (true_type, ptraddr, 0, addr, stream, recurse + 1, - NULL, options); + return d_val_print (true_type, + value_contents_for_printing (val), + value_embedded_offset (val), addr, + stream, recurse + 1, val, options); } return -1; } Index: src/gdb/jv-valprint.c =================================================================== --- src.orig/gdb/jv-valprint.c 2011-01-24 12:54:32.000000000 +0000 +++ src/gdb/jv-valprint.c 2011-01-24 12:54:35.246177002 +0000 @@ -259,6 +259,7 @@ java_value_print (struct value *val, str static void java_print_value_fields (struct type *type, const gdb_byte *valaddr, + int offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, @@ -304,11 +305,11 @@ java_print_value_fields (struct type *ty base_valaddr = valaddr; - java_print_value_fields (baseclass, base_valaddr, address + boffset, + java_print_value_fields (baseclass, base_valaddr, + offset + boffset, address, stream, recurse + 1, val, options); fputs_filtered (", ", stream); } - } if (!len && n_baseclasses == 1) @@ -412,8 +413,9 @@ java_print_value_fields (struct type *ty { struct value_print_options opts; - v = value_from_longest (TYPE_FIELD_TYPE (type, i), - unpack_field_as_long (type, valaddr, i)); + v = value_from_longest + (TYPE_FIELD_TYPE (type, i), + unpack_field_as_long (type, valaddr + offset, i)); opts = *options; opts.deref_ref = 0; @@ -454,9 +456,9 @@ java_print_value_fields (struct type *ty opts.deref_ref = 0; val_print (TYPE_FIELD_TYPE (type, i), - valaddr + TYPE_FIELD_BITPOS (type, i) / 8, 0, - address + TYPE_FIELD_BITPOS (type, i) / 8, - stream, recurse + 1, val, &opts, + valaddr, + offset + TYPE_FIELD_BITPOS (type, i) / 8, + address, stream, recurse + 1, val, &opts, current_language); } } @@ -497,7 +499,8 @@ java_val_print (struct type *type, const case TYPE_CODE_PTR: if (options->format && options->format != 's') { - print_scalar_formatted (valaddr, type, options, 0, stream); + print_scalar_formatted (valaddr + embedded_offset, + type, options, 0, stream); break; } #if 0 @@ -507,14 +510,15 @@ java_val_print (struct type *type, const /* Print vtable entry - we only get here if we ARE using -fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */ /* Extract an address, assume that it is unsigned. */ - print_address_demangle (gdbarch, - extract_unsigned_integer (valaddr, - TYPE_LENGTH (type)), - stream, demangle); + print_address_demangle + (gdbarch, + extract_unsigned_integer (valaddr + embedded_offset, + TYPE_LENGTH (type)), + stream, demangle); break; } #endif - addr = unpack_pointer (type, valaddr); + addr = unpack_pointer (type, valaddr + embedded_offset); if (addr == 0) { fputs_filtered ("null", stream); @@ -548,20 +552,22 @@ java_val_print (struct type *type, const opts.format = (options->format ? options->format : options->output_format); - print_scalar_formatted (valaddr, type, &opts, 0, stream); + print_scalar_formatted (valaddr + embedded_offset, + type, &opts, 0, stream); } else if (TYPE_CODE (type) == TYPE_CODE_CHAR || (TYPE_CODE (type) == TYPE_CODE_INT && TYPE_LENGTH (type) == 2 && strcmp (TYPE_NAME (type), "char") == 0)) - LA_PRINT_CHAR ((int) unpack_long (type, valaddr), type, stream); + LA_PRINT_CHAR ((int) unpack_long (type, valaddr + embedded_offset), + type, stream); else - val_print_type_code_int (type, valaddr, stream); + val_print_type_code_int (type, valaddr + embedded_offset, stream); break; case TYPE_CODE_STRUCT: - java_print_value_fields (type, valaddr, address, stream, recurse, - val, options); + java_print_value_fields (type, valaddr, embedded_offset, + address, stream, recurse, val, options); break; default: Index: src/gdb/f-valprint.c =================================================================== --- src.orig/gdb/f-valprint.c 2011-01-24 12:54:32.000000000 +0000 +++ src/gdb/f-valprint.c 2011-01-24 12:54:35.246177002 +0000 @@ -163,7 +163,8 @@ f77_create_arrayprint_offset_tbl (struct static void f77_print_array_1 (int nss, int ndimensions, struct type *type, - const gdb_byte *valaddr, CORE_ADDR address, + const gdb_byte *valaddr, + int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options, @@ -179,8 +180,9 @@ f77_print_array_1 (int nss, int ndimensi { fprintf_filtered (stream, "( "); f77_print_array_1 (nss + 1, ndimensions, TYPE_TARGET_TYPE (type), - valaddr + i * F77_DIM_OFFSET (nss), - address + i * F77_DIM_OFFSET (nss), + valaddr, + embedded_offset + i * F77_DIM_OFFSET (nss), + address, stream, recurse, val, options, elts); fprintf_filtered (stream, ") "); } @@ -193,10 +195,10 @@ f77_print_array_1 (int nss, int ndimensi i++, (*elts)++) { val_print (TYPE_TARGET_TYPE (type), - valaddr + i * F77_DIM_OFFSET (ndimensions), - 0, - address + i * F77_DIM_OFFSET (ndimensions), - stream, recurse, val, options, current_language); + valaddr, + embedded_offset + i * F77_DIM_OFFSET (ndimensions), + address, stream, recurse, + val, options, current_language); if (i != (F77_DIM_SIZE (nss) - 1)) fprintf_filtered (stream, ", "); @@ -213,6 +215,7 @@ f77_print_array_1 (int nss, int ndimensi static void f77_print_array (struct type *type, const gdb_byte *valaddr, + int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, @@ -234,8 +237,8 @@ Type node corrupt! F77 arrays cannot hav f77_create_arrayprint_offset_tbl (type, stream); - f77_print_array_1 (1, ndimensions, type, valaddr, address, stream, - recurse, val, options, &elts); + f77_print_array_1 (1, ndimensions, type, valaddr, embedded_offset, + address, stream, recurse, val, options, &elts); } @@ -266,25 +269,27 @@ f_val_print (struct type *type, const gd case TYPE_CODE_STRING: f77_get_dynamic_length_of_aggregate (type); LA_PRINT_STRING (stream, builtin_type (gdbarch)->builtin_char, - valaddr, TYPE_LENGTH (type), NULL, 0, options); + valaddr + embedded_offset, + TYPE_LENGTH (type), NULL, 0, options); break; case TYPE_CODE_ARRAY: fprintf_filtered (stream, "("); - f77_print_array (type, valaddr, address, stream, - recurse, original_value, options); + f77_print_array (type, valaddr, embedded_offset, + address, stream, recurse, original_value, options); fprintf_filtered (stream, ")"); break; case TYPE_CODE_PTR: if (options->format && options->format != 's') { - print_scalar_formatted (valaddr, type, options, 0, stream); + print_scalar_formatted (valaddr + embedded_offset, + type, options, 0, stream); break; } else { - addr = unpack_pointer (type, valaddr); + addr = unpack_pointer (type, valaddr + embedded_offset); elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) @@ -347,7 +352,8 @@ f_val_print (struct type *type, const gd case TYPE_CODE_FUNC: if (options->format) { - print_scalar_formatted (valaddr, type, options, 0, stream); + print_scalar_formatted (valaddr + embedded_offset, + type, options, 0, stream); break; } /* FIXME, we should consider, at least for ANSI C language, eliminating @@ -366,36 +372,41 @@ f_val_print (struct type *type, const gd opts.format = (options->format ? options->format : options->output_format); - print_scalar_formatted (valaddr, type, &opts, 0, stream); + print_scalar_formatted (valaddr + embedded_offset, + type, &opts, 0, stream); } else { - val_print_type_code_int (type, valaddr, stream); + val_print_type_code_int (type, valaddr + embedded_offset, stream); /* C and C++ has no single byte int type, char is used instead. Since we don't know whether the value is really intended to be used as an integer or a character, print the character equivalent as well. */ if (TYPE_LENGTH (type) == 1) { + LONGEST c; + fputs_filtered (" ", stream); - LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr), - type, stream); + c = unpack_long (type, valaddr + embedded_offset); + LA_PRINT_CHAR ((unsigned char) c, type, stream); } } break; case TYPE_CODE_FLAGS: if (options->format) - print_scalar_formatted (valaddr, type, options, 0, stream); + print_scalar_formatted (valaddr + embedded_offset, + type, options, 0, stream); else - val_print_type_code_flags (type, valaddr, stream); + val_print_type_code_flags (type, valaddr + embedded_offset, stream); break; case TYPE_CODE_FLT: if (options->format) - print_scalar_formatted (valaddr, type, options, 0, stream); + print_scalar_formatted (valaddr + embedded_offset, + type, options, 0, stream); else - print_floating (valaddr, type, stream); + print_floating (valaddr + embedded_offset, type, stream); break; case TYPE_CODE_VOID: @@ -418,11 +429,12 @@ f_val_print (struct type *type, const gd opts.format = (options->format ? options->format : options->output_format); - print_scalar_formatted (valaddr, type, &opts, 0, stream); + print_scalar_formatted (valaddr + embedded_offset, + type, &opts, 0, stream); } else { - val = extract_unsigned_integer (valaddr, + val = extract_unsigned_integer (valaddr + embedded_offset, TYPE_LENGTH (type), byte_order); if (val == 0) fprintf_filtered (stream, ".FALSE."); @@ -433,7 +445,8 @@ f_val_print (struct type *type, const gd { /* Bash the type code temporarily. */ TYPE_CODE (type) = TYPE_CODE_INT; - val_print (type, valaddr, 0, address, stream, recurse, + val_print (type, valaddr, embedded_offset, + address, stream, recurse, original_value, options, current_language); /* Restore the type code so later uses work as intended. */ TYPE_CODE (type) = TYPE_CODE_BOOL; @@ -444,9 +457,10 @@ f_val_print (struct type *type, const gd case TYPE_CODE_COMPLEX: type = TYPE_TARGET_TYPE (type); fputs_filtered ("(", stream); - print_floating (valaddr, type, stream); + print_floating (valaddr + embedded_offset, type, stream); fputs_filtered (",", stream); - print_floating (valaddr + TYPE_LENGTH (type), type, stream); + print_floating (valaddr + embedded_offset + TYPE_LENGTH (type), + type, stream); fputs_filtered (")", stream); break; @@ -466,8 +480,9 @@ f_val_print (struct type *type, const gd { int offset = TYPE_FIELD_BITPOS (type, index) / 8; - val_print (TYPE_FIELD_TYPE (type, index), valaddr + offset, - embedded_offset, address, stream, recurse + 1, + val_print (TYPE_FIELD_TYPE (type, index), valaddr, + embedded_offset + offset, + address, stream, recurse + 1, original_value, options, current_language); if (index != TYPE_NFIELDS (type) - 1) fputs_filtered (", ", stream); Index: src/gdb/testsuite/gdb.base/printcmds.c =================================================================== --- src.orig/gdb/testsuite/gdb.base/printcmds.c 2011-01-24 13:10:14.000000000 +0000 +++ src/gdb/testsuite/gdb.base/printcmds.c 2011-01-24 13:10:43.486176996 +0000 @@ -96,6 +96,28 @@ enum some_volatile_enum { enumvolval1, e name. See PR11827. */ volatile enum some_volatile_enum some_volatile_enum = enumvolval1; +/* A structure with an embedded array at an offset > 0. The array has + all elements with the same repeating value, which must not be the + same as the value of the preceding fields in the structure for the + test to be effective. This tests whether GDB uses the correct + element content offsets (relative to the complete `some_struct' + value) when counting value repetitions. */ +struct some_struct +{ + int a; + int b; + unsigned char array[20]; +} some_struct = { + 0x12345678, + 0x87654321, + { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa + } +}; + /* -- */ int main () Index: src/gdb/testsuite/gdb.base/printcmds.exp =================================================================== --- src.orig/gdb/testsuite/gdb.base/printcmds.exp 2011-01-24 13:10:14.000000000 +0000 +++ src/gdb/testsuite/gdb.base/printcmds.exp 2011-01-24 13:10:43.486176996 +0000 @@ -474,6 +474,18 @@ proc test_print_repeats_10 {} { } } +# This tests whether GDB uses the correct element content offsets +# (relative to the complete `some_struct' value) when counting value +# repetitions. + +proc test_print_repeats_embedded_array {} { + global gdb_prompt + + gdb_test_escape_braces "p/x some_struct" \ + "= {a = 0x12345678, b = 0x87654321, array = {0xaa }}" \ + "correct element repeats in array embedded at offset > 0" +} + proc test_print_strings {} { global gdb_prompt @@ -818,6 +830,7 @@ test_float_rejected test_character_literals_accepted test_print_all_chars test_print_repeats_10 +test_print_repeats_embedded_array test_print_strings test_print_int_arrays test_print_typedef_arrays