GDB: Only make data actually retrieved into value history available

While it makes sense to allow accessing out-of-bounds elements in the
debuggee and see whatever there might happen to be there in memory (we
are a debugger and not a programming rules enforcement facility and we
want to make people's life easier in chasing bugs), e.g.:

  (gdb) print one_hundred[-1]
  $1 = 0
  (gdb) print one_hundred[100]
  $2 = 0
  (gdb)

we shouldn't really pretend that we have any meaningful data around
values recorded in history (what these commands really retrieve are
current debuggee memory contents outside the original data accessed,
really confusing in my opinion).  Mark values recorded in history as
such then and verify accesses to be in-range for them:

  (gdb) print one_hundred[-1]
  $1 = <unavailable>
  (gdb) print one_hundred[100]
  $2 = <unavailable>

Add a suitable test case, which also covers integer overflows in data
location calculation.

Approved-By: Tom Tromey <tom@tromey.com>
This commit is contained in:
Maciej W. Rozycki
2023-02-10 23:49:19 +00:00
parent 4f82620cc9
commit aaab5fce4f
4 changed files with 133 additions and 1 deletions

View File

@ -182,6 +182,21 @@ value_subscript (struct value *array, LONGEST index)
}
index -= *lowerbound;
/* Do not try to dereference a pointer to an unavailable value.
Instead mock up a new one and give it the original address. */
struct type *elt_type = check_typedef (tarray->target_type ());
LONGEST elt_size = type_length_units (elt_type);
if (!value_lazy (array)
&& !value_bytes_available (array, elt_size * index, elt_size))
{
struct value *val = allocate_value (elt_type);
mark_value_bytes_unavailable (val, 0, elt_size);
VALUE_LVAL (val) = lval_memory;
set_value_address (val, value_address (array) + elt_size * index);
return val;
}
array = value_coerce_array (array);
}