diff options
author | Tom Tromey <tromey@adacore.com> | 2022-09-27 12:53:25 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2022-10-21 09:40:59 -0600 |
commit | e379f6521a9fbc65de8cd90a950e28d0ca522ae3 (patch) | |
tree | ad535756dd30530414241d77a7af18527068a7f6 /gdb/valprint.c | |
parent | 6c849804cff9e251876f3edb64d44dabeadaa711 (diff) | |
download | gdb-e379f6521a9fbc65de8cd90a950e28d0ca522ae3.zip gdb-e379f6521a9fbc65de8cd90a950e28d0ca522ae3.tar.gz gdb-e379f6521a9fbc65de8cd90a950e28d0ca522ae3.tar.bz2 |
Fix crash in value_print_array_elements
A user noticed that gdb would crash when printing a packed array after
doing "set lang c". Packed arrays don't exist in C, but it's
occasionally useful to print things in C mode when working in a non-C
language -- this lets you see under the hood a little bit.
The bug here is that generic value printing does not handle packed
arrays at all. This patch fixes the bug by introducing a new function
to extract a value from a bit offset and width.
The new function includes a hack to avoid problems with some existing
test cases when using -fgnat-encodings=all. Cleaning up this code
looked difficult, and since "all" is effectively deprecated, I thought
it made sense to simply work around the problems.
Diffstat (limited to 'gdb/valprint.c')
-rw-r--r-- | gdb/valprint.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/gdb/valprint.c b/gdb/valprint.c index 685f890..25db57e 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -1927,7 +1927,6 @@ value_print_array_elements (struct value *val, struct ui_file *stream, unsigned int things_printed = 0; unsigned len; struct type *elttype, *index_type; - unsigned eltlen; /* Position of the array element we are examining to see whether it is repeated. */ unsigned int rep1; @@ -1938,7 +1937,9 @@ value_print_array_elements (struct value *val, struct ui_file *stream, struct type *type = check_typedef (value_type (val)); elttype = type->target_type (); - eltlen = type_length_units (check_typedef (elttype)); + unsigned bit_stride = type->bit_stride (); + if (bit_stride == 0) + bit_stride = 8 * check_typedef (elttype)->length (); index_type = type->index_type (); if (index_type->code () == TYPE_CODE_RANGE) index_type = index_type->target_type (); @@ -1987,23 +1988,28 @@ value_print_array_elements (struct value *val, struct ui_file *stream, maybe_print_array_index (index_type, i + low_bound, stream, options); + struct value *element = value_from_component_bitsize (val, elttype, + bit_stride * i, + bit_stride); rep1 = i + 1; reps = 1; /* Only check for reps if repeat_count_threshold is not set to UINT_MAX (unlimited). */ if (options->repeat_count_threshold < UINT_MAX) { - while (rep1 < len - && value_contents_eq (val, i * eltlen, - val, rep1 * eltlen, - eltlen)) + while (rep1 < len) { + struct value *rep_elt + = value_from_component_bitsize (val, elttype, + rep1 * bit_stride, + bit_stride); + if (!value_contents_eq (element, rep_elt)) + break; ++reps; ++rep1; } } - struct value *element = value_from_component (val, elttype, eltlen * i); common_val_print (element, stream, recurse + 1, options, current_language); |