aboutsummaryrefslogtreecommitdiff
path: root/gdb/value.h
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2014-08-20 00:07:40 +0100
committerPedro Alves <palves@redhat.com>2014-08-20 00:07:40 +0100
commit9a0dc9e3699018b15980bb6a39eb33dea8fefa34 (patch)
tree01387811bdb9f4fcfa18caa73517c058ea91157e /gdb/value.h
parent6694c4110a37bc951d01132d6e56445d57350627 (diff)
downloadbinutils-9a0dc9e3699018b15980bb6a39eb33dea8fefa34.zip
binutils-9a0dc9e3699018b15980bb6a39eb33dea8fefa34.tar.gz
binutils-9a0dc9e3699018b15980bb6a39eb33dea8fefa34.tar.bz2
Handle partially optimized out values similarly to unavailable values
This fixes PR symtab/14604, PR symtab/14605, and Jan's test at https://sourceware.org/ml/gdb-patches/2014-07/msg00158.html, in a tree with bddbbed reverted: 2014-07-22 Pedro Alves <palves@redhat.com> * value.c (allocate_optimized_out_value): Don't mark value as non-lazy. The PRs are about variables described by the DWARF as being split over multiple registers using DWARF piece information, but some of those registers being marked as optimised out (not saved) by a later frame. GDB currently incorrectly mishandles these partially-optimized-out values. Even though we can usually tell from the debug info whether a local or global is optimized out, handling the case of a local living in a register that was not saved in a frame requires fetching the variable. GDB also needs to fetch a value to tell whether parts of it are "<unavailable>". Given this, it's not worth it to try to avoid fetching lazy optimized-out values based on debug info alone. So this patch makes GDB track which chunks of a value's contents are optimized out like it tracks <unavailable> contents. That is, it makes value->optimized_out be a bit range vector instead of a boolean, and removes the struct lval_funcs check_validity and check_any_valid hooks. Unlike Andrew's series which this is based on (at https://sourceware.org/ml/gdb-patches/2013-08/msg00300.html, note some pieces have gone in since), this doesn't merge optimized out and unavailable contents validity/availability behind a single interface, nor does it merge the bit range vectors themselves (at least yet). While it may be desirable to have a single entry point that returns existence of contents irrespective of what may make them invalid/unavailable, several places want to treat optimized out / unavailable / etc. differently, so each spot that potentially could use it will need to be careful considered on case-by-case basis, and best done as a separate change. This fixes Jan's test, because value_available_contents_eq wasn't considering optimized out value contents. It does now, and because of that it's been renamed to value_contents_eq. A new intro comment is added to value.h describing "<optimized out>", "<not saved>" and "<unavailable>" values. gdb/ PR symtab/14604 PR symtab/14605 * ada-lang.c (coerce_unspec_val_to_type): Use value_contents_copy_raw. * ada-valprint.c (val_print_packed_array_elements): Adjust. * c-valprint.c (c_val_print): Use value_bits_any_optimized_out. * cp-valprint.c (cp_print_value_fields): Let the common printing code handle optimized out values. (cp_print_value_fields_rtti): Use value_bits_any_optimized_out. * d-valprint.c (dynamic_array_type): Use value_bits_any_optimized_out. * dwarf2loc.c (entry_data_value_funcs): Remove check_validity and check_any_valid fields. (check_pieced_value_bits): Delete and inline ... (check_pieced_synthetic_pointer): ... here. (check_pieced_value_validity): Delete. (check_pieced_value_invalid): Delete. (pieced_value_funcs): Remove check_validity and check_any_valid fields. (read_pieced_value): Use mark_value_bits_optimized_out. (write_pieced_value): Switch to use mark_value_bytes_optimized_out. (dwarf2_evaluate_loc_desc_full): Copy the value contents instead of assuming the whole value is optimized out. * findvar.c (read_frame_register_value): Remove special handling of optimized out registers. (value_from_register): Use mark_value_bytes_optimized_out. * frame-unwind.c (frame_unwind_got_optimized): Use mark_value_bytes_optimized_out. * jv-valprint.c (java_value_print): Adjust. (java_print_value_fields): Let the common printing code handle optimized out values. * mips-tdep.c (mips_print_register): Remove special handling of optimized out registers. * opencl-lang.c (lval_func_check_validity): Delete. (lval_func_check_any_valid): Delete. (opencl_value_funcs): Remove check_validity and check_any_valid fields. * p-valprint.c (pascal_object_print_value_fields): Let the common printing code handle optimized out values. * stack.c (read_frame_arg): Remove special handling of optimized out values. Fetch both VAL and ENTRYVAL before comparing contents. Adjust to value_available_contents_eq rename. * valprint.c (valprint_check_validity) (val_print_scalar_formatted): Use value_bits_any_optimized_out. (val_print_array_elements): Adjust. * value.c (struct value) <optimized_out>: Now a VEC(range_s). (value_bits_any_optimized_out): New function. (value_entirely_covered_by_range_vector): New function, factored out from value_entirely_unavailable. (value_entirely_unavailable): Reimplement. (value_entirely_optimized_out): New function. (insert_into_bit_range_vector): New function, factored out from mark_value_bits_unavailable. (mark_value_bits_unavailable): Reimplement. (struct ranges_and_idx): New struct. (find_first_range_overlap_and_match): New function, factored out from value_available_contents_bits_eq. (value_available_contents_bits_eq): Rename to ... (value_contents_bits_eq): ... this. Check both unavailable contents and optimized out contents. (value_available_contents_eq): Rename to ... (value_contents_eq): ... this. (allocate_value_lazy): Remove reference to the old optimized_out boolean. (allocate_optimized_out_value): Use mark_value_bytes_optimized_out. (require_not_optimized_out): Adjust to check whether the optimized_out vec is empty. (ranges_copy_adjusted): New function, factored out from value_contents_copy_raw. (value_contents_copy_raw): Also copy the optimized out ranges. Assert the destination ranges aren't optimized out. (value_contents_copy): Update comment, remove call to require_not_optimized_out. (value_contents_equal): Adjust to check whether the optimized_out vec is empty. (set_value_optimized_out, value_optimized_out_const): Delete. (mark_value_bytes_optimized_out, mark_value_bits_optimized_out): New functions. (value_entirely_optimized_out, value_bits_valid): Delete. (value_copy): Take a VEC copy of the 'optimized_out' field. (value_primitive_field): Remove special handling of optimized out. (value_fetch_lazy): Assert that lazy values have no unavailable regions. Use value_bits_any_optimized_out. Remove some special handling for optimized out values. * value.h: Add intro comment about <optimized out> and <unavailable>. (struct lval_funcs): Remove check_validity and check_any_valid fields. (set_value_optimized_out, value_optimized_out_const): Remove. (mark_value_bytes_optimized_out, mark_value_bits_optimized_out): New declarations. (value_bits_any_optimized_out): New declaration. (value_bits_valid): Delete declaration. (value_available_contents_eq): Rename to ... (value_contents_eq): ... this, and extend comments. gdb/testsuite/ PR symtab/14604 PR symtab/14605 * gdb.dwarf2/dw2-op-out-param.exp: Remove kfail branches and use gdb_test.
Diffstat (limited to 'gdb/value.h')
-rw-r--r--gdb/value.h158
1 files changed, 111 insertions, 47 deletions
diff --git a/gdb/value.h b/gdb/value.h
index 843478b..5d4949c 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -33,6 +33,54 @@ struct language_defn;
struct value_print_options;
struct xmethod_worker;
+/* Values can be partially 'optimized out' and/or 'unavailable'.
+ These are distinct states and have different string representations
+ and related error strings.
+
+ 'unavailable' has a specific meaning in this context. It means the
+ value exists in the program (at the machine level), but GDB has no
+ means to get to it. Such a value is normally printed as
+ <unavailable>. Examples of how to end up with an unavailable value
+ would be:
+
+ - We're inspecting a traceframe, and the memory or registers the
+ debug information says the value lives on haven't been collected.
+
+ - We're inspecting a core dump, the memory or registers the debug
+ information says the value lives aren't present in the dump
+ (that is, we have a partial/trimmed core dump, or we don't fully
+ understand/handle the core dump's format).
+
+ - We're doing live debugging, but the debug API has no means to
+ get at where the value lives in the machine, like e.g., ptrace
+ not having access to some register or register set.
+
+ - Any other similar scenario.
+
+ OTOH, "optimized out" is about what the compiler decided to generate
+ (or not generate). A chunk of a value that was optimized out does
+ not actually exist in the program. There's no way to get at it
+ short of compiling the program differently.
+
+ A register that has not been saved in a frame is likewise considered
+ optimized out, except not-saved registers have a different string
+ representation and related error strings. E.g., we'll print them as
+ <not-saved> instead of <optimized out>, as in:
+
+ (gdb) p/x $rax
+ $1 = <not saved>
+ (gdb) info registers rax
+ rax <not saved>
+
+ If the debug info describes a variable as being in such a register,
+ we'll still print the variable as <optimized out>. IOW, <not saved>
+ is reserved for inspecting registers at the machine level.
+
+ When comparing value contents, optimized out chunks, unavailable
+ chunks, and valid contents data are all considered different. See
+ value_contents_eq for more info.
+*/
+
/* The structure which defines the type of a value. It should never
be possible for a program lval value to survive over a call to the
inferior (i.e. to be put into the history list or an internal
@@ -181,14 +229,6 @@ struct lval_funcs
TOVAL is not considered as an lvalue. */
void (*write) (struct value *toval, struct value *fromval);
- /* Check the validity of some bits in VALUE. This should return 1
- if all the bits starting at OFFSET and extending for LENGTH bits
- are valid, or 0 if any bit is invalid. */
- int (*check_validity) (const struct value *value, int offset, int length);
-
- /* Return 1 if any bit in VALUE is valid, 0 if they are all invalid. */
- int (*check_any_valid) (const struct value *value);
-
/* If non-NULL, this is used to implement pointer indirection for
this value. This method may return NULL, in which case value_ind
will fall back to ordinary indirection. */
@@ -327,16 +367,29 @@ extern int value_fetch_lazy (struct value *val);
exist in the program, at least partially. If the value is lazy,
this may fetch it now. */
extern int value_optimized_out (struct value *value);
-extern void set_value_optimized_out (struct value *value, int val);
-/* Like value_optimized_out, but don't fetch the value even if it is
- lazy. Mainly useful for constructing other values using VALUE as
- template. */
-extern int value_optimized_out_const (const struct value *value);
+/* Given a value, return true if any of the contents bits starting at
+ OFFSET and extending for LENGTH bits is optimized out, false
+ otherwise. */
+
+extern int value_bits_any_optimized_out (const struct value *value,
+ int bit_offset, int bit_length);
+
+/* Like value_optimized_out, but return true iff the whole value is
+ optimized out. */
+extern int value_entirely_optimized_out (struct value *value);
+
+/* Mark VALUE's content bytes starting at OFFSET and extending for
+ LENGTH bytes as optimized out. */
+
+extern void mark_value_bytes_optimized_out (struct value *value,
+ int offset, int length);
+
+/* Mark VALUE's content bits starting at OFFSET and extending for
+ LENGTH bits as optimized out. */
-/* Like value_optimized_out, but return false if any bit in the object
- is valid. */
-extern int value_entirely_optimized_out (const struct value *value);
+extern void mark_value_bits_optimized_out (struct value *value,
+ int offset, int length);
/* Set or return field indicating whether a variable is initialized or
not, based on debugging information supplied by the compiler.
@@ -416,13 +469,6 @@ extern struct value *coerce_ref (struct value *value);
extern struct value *coerce_array (struct value *value);
/* Given a value, determine whether the bits starting at OFFSET and
- extending for LENGTH bits are valid. This returns nonzero if all
- bits in the given range are valid, zero if any bit is invalid. */
-
-extern int value_bits_valid (const struct value *value,
- int offset, int length);
-
-/* Given a value, determine whether the bits starting at OFFSET and
extending for LENGTH bits are a synthetic pointer. */
extern int value_bits_synthetic_pointer (const struct value *value,
@@ -473,35 +519,53 @@ extern void mark_value_bits_unavailable (struct value *value,
its enclosing type chunk, you'd do:
int len = TYPE_LENGTH (check_typedef (value_enclosing_type (val)));
- value_available_contents (val, 0, val, 0, len);
+ value_contents_eq (val, 0, val, 0, len);
+
+ Returns true iff the set of available/valid contents match.
+
+ Optimized-out contents are equal to optimized-out contents, and are
+ not equal to non-optimized-out contents.
- Returns true iff the set of available contents match. Unavailable
- contents compare equal with unavailable contents, and different
- with any available byte. For example, if 'x's represent an
- unavailable byte, and 'V' and 'Z' represent different available
- bytes, in a value with length 16:
+ Unavailable contente are equal to unavailable contents, and are not
+ equal to non-unavailable contents.
- offset: 0 4 8 12 16
- contents: xxxxVVVVxxxxVVZZ
+ For example, if 'x's represent an unavailable byte, and 'V' and 'Z'
+ represent different available/valid bytes, in a value with length
+ 16:
+
+ offset: 0 4 8 12 16
+ contents: xxxxVVVVxxxxVVZZ
then:
- value_available_contents_eq(val, 0, val, 8, 6) => 1
- value_available_contents_eq(val, 0, val, 4, 4) => 1
- value_available_contents_eq(val, 0, val, 8, 8) => 0
- value_available_contents_eq(val, 4, val, 12, 2) => 1
- value_available_contents_eq(val, 4, val, 12, 4) => 0
- value_available_contents_eq(val, 3, val, 4, 4) => 0
-
- We only know whether a value chunk is available if we've tried to
- read it. As this routine is used by printing routines, which may
- be printing values in the value history, long after the inferior is
- gone, it works with const values. Therefore, this routine must not
- be called with lazy values. */
-
-extern int value_available_contents_eq (const struct value *val1, int offset1,
- const struct value *val2, int offset2,
- int length);
+ value_contents_eq(val, 0, val, 8, 6) => 1
+ value_contents_eq(val, 0, val, 4, 4) => 0
+ value_contents_eq(val, 0, val, 8, 8) => 0
+ value_contents_eq(val, 4, val, 12, 2) => 1
+ value_contents_eq(val, 4, val, 12, 4) => 0
+ value_contents_eq(val, 3, val, 4, 4) => 0
+
+ If 'x's represent an unavailable byte, 'o' represents an optimized
+ out byte, in a value with length 8:
+
+ offset: 0 4 8
+ contents: xxxxoooo
+
+ then:
+
+ value_contents_eq(val, 0, val, 2, 2) => 1
+ value_contents_eq(val, 4, val, 6, 2) => 1
+ value_contents_eq(val, 0, val, 4, 4) => 0
+
+ We only know whether a value chunk is unavailable or optimized out
+ if we've tried to read it. As this routine is used by printing
+ routines, which may be printing values in the value history, long
+ after the inferior is gone, it works with const values. Therefore,
+ this routine must not be called with lazy values. */
+
+extern int value_contents_eq (const struct value *val1, int offset1,
+ const struct value *val2, int offset2,
+ int length);
/* Read LENGTH bytes of memory starting at MEMADDR into BUFFER, which
is (or will be copied to) VAL's contents buffer offset by