From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28474 invoked by alias); 24 Jan 2011 13:22:54 -0000 Received: (qmail 28457 invoked by uid 22791); 24 Jan 2011 13:22:52 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,TW_GC,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:22:46 +0000 Received: (qmail 19822 invoked from network); 24 Jan 2011 13:22:44 -0000 Received: from unknown (HELO scottsdale.localnet) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 24 Jan 2011 13:22:44 -0000 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [RFA v2] valprint.c / *-valprint.c: Don't lose `embedded_offset' Date: Mon, 24 Jan 2011 13:24:00 -0000 User-Agent: KMail/1.13.5 (Linux/2.6.35-24-generic; KDE/4.5.1; x86_64; ; ) Cc: Joel Brobecker MIME-Version: 1.0 Content-Type: Text/Plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Message-Id: <201101241322.42902.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/msg00458.txt.bz2 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