mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 10:03:47 +08:00
GDB: Introduce limited array lengths while printing values
This commit introduces the idea of loading only part of an array in order to print it, what I call "limited length" arrays. The motivation behind this work is to make it possible to print slices of very large arrays, where very large means bigger than `max-value-size'. Consider this GDB session with the current GDB: (gdb) set max-value-size 100 (gdb) p large_1d_array value requires 400 bytes, which is more than max-value-size (gdb) p -elements 10 -- large_1d_array value requires 400 bytes, which is more than max-value-size notice that the request to print 10 elements still fails, even though 10 elements should be less than the max-value-size. With a patched version of GDB: (gdb) p -elements 10 -- large_1d_array $1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9...} So now the print has succeeded. It also has loaded `max-value-size' worth of data into value history, so the recorded value can be accessed consistently: (gdb) p -elements 10 -- $1 $2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9...} (gdb) p $1 $3 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, <unavailable> <repeats 75 times>} (gdb) Accesses with other languages work similarly, although for Ada only C-style [] array element/dimension accesses use history. For both Ada and Fortran () array element/dimension accesses go straight to the inferior, bypassing the value history just as with C pointers. Co-Authored-By: Maciej W. Rozycki <macro@embecosm.com>
This commit is contained in:
parent
a2fb245a4b
commit
a0c0791577
6
gdb/NEWS
6
gdb/NEWS
@ -44,6 +44,12 @@
|
||||
keyword already gave an error when used multiple times with the
|
||||
watch command, this remains unchanged.
|
||||
|
||||
* The 'set print elements' setting now helps when printing large arrays.
|
||||
If an array would otherwise exceed max-value-size, but 'print elements'
|
||||
is set such that the size of elements to print is less than or equal
|
||||
to 'max-value-size', GDB will now still print the array, however only
|
||||
'max-value-size' worth of data will be added into the value history.
|
||||
|
||||
* New commands
|
||||
|
||||
maintenance print record-instruction [ N ]
|
||||
|
@ -11759,6 +11759,14 @@ When @value{GDBN} starts, this limit is set to 200.
|
||||
Setting @var{number-of-elements} to @code{unlimited} or zero means
|
||||
that the number of elements to print is unlimited.
|
||||
|
||||
When printing very large arrays, whose size is greater than
|
||||
@code{max-value-size} (@pxref{set max-value-size,,max-value-size}),
|
||||
if the @code{print elements} is set such that the size of the elements
|
||||
being printed is less than or equal to @code{max-value-size}, then
|
||||
@value{GDBN} will print the array (up to the @code{print elements} limit),
|
||||
and only @code{max-value-size} worth of data will be added into the value
|
||||
history (@pxref{Value History, ,Value History}).
|
||||
|
||||
@item show print elements
|
||||
Display the number of elements of a large array that @value{GDBN} will print.
|
||||
|
||||
@ -14174,6 +14182,7 @@ may indicate a value that is incorrectly large, this in turn may cause
|
||||
@value{GDBN} to try and allocate an overly large amount of memory.
|
||||
|
||||
@table @code
|
||||
@anchor{set max-value-size}
|
||||
@kindex set max-value-size
|
||||
@item set max-value-size @var{bytes}
|
||||
@itemx set max-value-size unlimited
|
||||
|
@ -261,10 +261,20 @@ public:
|
||||
size_t dim_indx = m_dimension - 1;
|
||||
struct type *elt_type_prev = m_elt_type_prev;
|
||||
LONGEST elt_off_prev = m_elt_off_prev;
|
||||
bool repeated = (m_options->repeat_count_threshold < UINT_MAX
|
||||
&& elt_type_prev != nullptr
|
||||
&& value_contents_eq (m_val, elt_off_prev, m_val, elt_off,
|
||||
elt_type->length ()));
|
||||
bool repeated = false;
|
||||
|
||||
if (m_options->repeat_count_threshold < UINT_MAX
|
||||
&& elt_type_prev != nullptr)
|
||||
{
|
||||
struct value *e_val = value_from_component (m_val, elt_type, elt_off);
|
||||
struct value *e_prev = value_from_component (m_val, elt_type,
|
||||
elt_off_prev);
|
||||
repeated = ((value_entirely_available (e_prev)
|
||||
&& value_entirely_available (e_val)
|
||||
&& value_contents_eq (e_prev, e_val))
|
||||
|| (value_entirely_unavailable (e_prev)
|
||||
&& value_entirely_unavailable (e_val)));
|
||||
}
|
||||
|
||||
if (repeated)
|
||||
m_nrepeats++;
|
||||
@ -333,7 +343,7 @@ private:
|
||||
have been sliced and we do not want to compare any memory contents
|
||||
present between the slices requested. */
|
||||
bool
|
||||
dimension_contents_eq (const struct value *val, struct type *type,
|
||||
dimension_contents_eq (struct value *val, struct type *type,
|
||||
LONGEST offset1, LONGEST offset2)
|
||||
{
|
||||
if (type->code () == TYPE_CODE_ARRAY
|
||||
@ -362,8 +372,16 @@ private:
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return value_contents_eq (val, offset1, val, offset2,
|
||||
type->length ());
|
||||
{
|
||||
struct value *e_val1 = value_from_component (val, type, offset1);
|
||||
struct value *e_val2 = value_from_component (val, type, offset2);
|
||||
|
||||
return ((value_entirely_available (e_val1)
|
||||
&& value_entirely_available (e_val2)
|
||||
&& value_contents_eq (e_val1, e_val2))
|
||||
|| (value_entirely_unavailable (e_val1)
|
||||
&& value_entirely_unavailable (e_val2)));
|
||||
}
|
||||
}
|
||||
|
||||
/* The number of elements printed so far. */
|
||||
|
@ -1242,6 +1242,11 @@ print_command_parse_format (const char **expp, const char *cmdname,
|
||||
void
|
||||
print_value (value *val, const value_print_options &opts)
|
||||
{
|
||||
/* This setting allows large arrays to be printed by limiting the
|
||||
number of elements that are loaded into GDB's memory; we only
|
||||
need to load as many array elements as we plan to print. */
|
||||
scoped_array_length_limiting limit_large_arrays (opts.print_max);
|
||||
|
||||
int histindex = record_latest_value (val);
|
||||
|
||||
annotate_value_history_begin (histindex, value_type (val));
|
||||
@ -1301,6 +1306,11 @@ process_print_command_args (const char *args, value_print_options *print_opts,
|
||||
|
||||
if (exp != nullptr && *exp)
|
||||
{
|
||||
/* This setting allows large arrays to be printed by limiting the
|
||||
number of elements that are loaded into GDB's memory; we only
|
||||
need to load as many array elements as we plan to print. */
|
||||
scoped_array_length_limiting limit_large_arrays (print_opts->print_max);
|
||||
|
||||
/* VOIDPRINT is true to indicate that we do want to print a void
|
||||
value, so invert it for parse_expression. */
|
||||
expression_up expr = parse_expression (exp, nullptr, !voidprint);
|
||||
@ -1489,6 +1499,12 @@ output_command (const char *exp, int from_tty)
|
||||
|
||||
get_formatted_print_options (&opts, format);
|
||||
opts.raw = fmt.raw;
|
||||
|
||||
/* This setting allows large arrays to be printed by limiting the
|
||||
number of elements that are loaded into GDB's memory; we only
|
||||
need to load as many array elements as we plan to print. */
|
||||
scoped_array_length_limiting limit_large_arrays (opts.print_max);
|
||||
|
||||
print_formatted (val, fmt.size, &opts, gdb_stdout);
|
||||
|
||||
annotate_value_end ();
|
||||
|
264
gdb/testsuite/gdb.ada/limited-length.exp
Normal file
264
gdb/testsuite/gdb.ada/limited-length.exp
Normal file
@ -0,0 +1,264 @@
|
||||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
load_lib "ada.exp"
|
||||
|
||||
require allow_ada_tests
|
||||
|
||||
standard_ada_testfile foo
|
||||
|
||||
if {[gdb_compile_ada "${srcfile}" "${binfile}" executable \
|
||||
[list debug ]] != "" } {
|
||||
return -1
|
||||
}
|
||||
|
||||
clean_restart ${testfile}
|
||||
|
||||
set bp_location [gdb_get_line_number "STOP" ${testdir}/foo.adb]
|
||||
if {![runto "foo.adb:$bp_location"]} {
|
||||
perror "Couldn't run ${testfile}"
|
||||
return
|
||||
}
|
||||
|
||||
with_test_prefix "with standard max-value size" {
|
||||
gdb_test "print Large_1d_Array" \
|
||||
" = \\(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\
|
||||
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\
|
||||
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,\
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,\
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,\
|
||||
61, 62, 63, 64\\)"
|
||||
gdb_test -nonl "output Large_1d_Array" \
|
||||
"\\(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\
|
||||
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\
|
||||
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,\
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,\
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,\
|
||||
61, 62, 63, 64\\)"
|
||||
gdb_test "print Large_3d_Array" \
|
||||
" = \\(\\(\\(1, 2, 3, 4\\), \\(5, 6, 7, 8\\),\
|
||||
\\(9, 10, 11, 12\\), \\(13, 14, 15, 16\\)\\),\
|
||||
\\(\\(17, 18, 19, 20\\), \\(21, 22, 23, 24\\),\
|
||||
\\(25, 26, 27, 28\\), \\(29, 30, 31, 32\\)\\),\
|
||||
\\(\\(33, 34, 35, 36\\), \\(37, 38, 39, 40\\),\
|
||||
\\(41, 42, 43, 44\\), \\(45, 46, 47, 48\\)\\),\
|
||||
\\(\\(49, 50, 51, 52\\), \\(53, 54, 55, 56\\),\
|
||||
\\(57, 58, 59, 60\\), \\(61, 62, 63, 64\\)\\)\\)"
|
||||
gdb_test -nonl "output Large_3d_Array" \
|
||||
"\\(\\(\\(1, 2, 3, 4\\), \\(5, 6, 7, 8\\),\
|
||||
\\(9, 10, 11, 12\\), \\(13, 14, 15, 16\\)\\),\
|
||||
\\(\\(17, 18, 19, 20\\), \\(21, 22, 23, 24\\),\
|
||||
\\(25, 26, 27, 28\\), \\(29, 30, 31, 32\\)\\),\
|
||||
\\(\\(33, 34, 35, 36\\), \\(37, 38, 39, 40\\),\
|
||||
\\(41, 42, 43, 44\\), \\(45, 46, 47, 48\\)\\),\
|
||||
\\(\\(49, 50, 51, 52\\), \\(53, 54, 55, 56\\),\
|
||||
\\(57, 58, 59, 60\\), \\(61, 62, 63, 64\\)\\)\\)"
|
||||
}
|
||||
|
||||
# Set the max-value-size so we can only print 33 elements.
|
||||
set elements 33
|
||||
set elem_size [get_valueof "/d" "(Large_1d_Array(1)'Size + 7) / 8" "*unknown*"]
|
||||
gdb_test_no_output "set max-value-size [expr $elem_size * $elements]"
|
||||
|
||||
with_test_prefix "with reduced max-value size" {
|
||||
gdb_test "print Large_1d_Array" \
|
||||
"value of type `.*' requires $decimal bytes,\
|
||||
which is more than max-value-size"
|
||||
gdb_test "output Large_1d_Array" \
|
||||
"value of type `.*' requires $decimal bytes,\
|
||||
which is more than max-value-size"
|
||||
gdb_test "print Large_3d_Array" \
|
||||
"value of type `.*' requires $decimal bytes,\
|
||||
which is more than max-value-size"
|
||||
gdb_test "output Large_3d_Array" \
|
||||
"value of type `.*' requires $decimal bytes,\
|
||||
which is more than max-value-size"
|
||||
}
|
||||
|
||||
with_test_prefix "with reduced print -elements flag" {
|
||||
gdb_test "print -elements 2 -- Large_1d_Array" \
|
||||
" = \\(1, 2\\.\\.\\.\\)"
|
||||
gdb_test "print -elements 2 -- Large_3d_Array" \
|
||||
" = \\(\\(\\(1, 2\\.\\.\\.\\), \\(5, 6\\.\\.\\.\\)\\.\\.\\.\\),\
|
||||
\\(\\(17, 18\\.\\.\\.\\),\
|
||||
\\(21, 22\\.\\.\\.\\)\\.\\.\\.\\)\\.\\.\\.\\)"
|
||||
}
|
||||
|
||||
gdb_test_no_output "set print elements 2"
|
||||
|
||||
with_test_prefix "with reduced print elements" {
|
||||
gdb_test "print Large_1d_Array" \
|
||||
" = \\(1, 2\\.\\.\\.\\)"
|
||||
gdb_test -nonl "output Large_1d_Array" \
|
||||
"\\(1, 2\\.\\.\\.\\)"
|
||||
|
||||
gdb_test "print \$" \
|
||||
" = \\(1, 2\\.\\.\\.\\)" \
|
||||
"print Large_1d_Array from history"
|
||||
gdb_test -nonl "output \$\$" \
|
||||
"\\(1, 2\\.\\.\\.\\)" \
|
||||
"output Large_1d_Array from history"
|
||||
|
||||
gdb_test "print Large_3d_Array" \
|
||||
" = \\(\\(\\(1, 2\\.\\.\\.\\), \\(5, 6\\.\\.\\.\\)\\.\\.\\.\\),\
|
||||
\\(\\(17, 18\\.\\.\\.\\),\
|
||||
\\(21, 22\\.\\.\\.\\)\\.\\.\\.\\)\\.\\.\\.\\)"
|
||||
gdb_test -nonl "output Large_3d_Array" \
|
||||
"\\(\\(\\(1, 2\\.\\.\\.\\), \\(5, 6\\.\\.\\.\\)\\.\\.\\.\\),\
|
||||
\\(\\(17, 18\\.\\.\\.\\),\
|
||||
\\(21, 22\\.\\.\\.\\)\\.\\.\\.\\)\\.\\.\\.\\)"
|
||||
|
||||
gdb_test "print \$" \
|
||||
" = \\(\\(\\(1, 2\\.\\.\\.\\), \\(5, 6\\.\\.\\.\\)\\.\\.\\.\\),\
|
||||
\\(\\(17, 18\\.\\.\\.\\),\
|
||||
\\(21, 22\\.\\.\\.\\)\\.\\.\\.\\)\\.\\.\\.\\)" \
|
||||
"print Large_3d_Array from history"
|
||||
gdb_test -nonl "output \$\$" \
|
||||
"\\(\\(\\(1, 2\\.\\.\\.\\), \\(5, 6\\.\\.\\.\\)\\.\\.\\.\\),\
|
||||
\\(\\(17, 18\\.\\.\\.\\),\
|
||||
\\(21, 22\\.\\.\\.\\)\\.\\.\\.\\)\\.\\.\\.\\)" \
|
||||
"output Large_3d_Array from history"
|
||||
}
|
||||
|
||||
gdb_test_no_output "set print elements $elements"
|
||||
|
||||
with_test_prefix "with print elements matching max-value size" {
|
||||
gdb_test "print \$\$2" \
|
||||
" = \\(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\
|
||||
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\
|
||||
25, 26, 27, 28, 29, 30, 31, 32, 33\\.\\.\\.\\)" \
|
||||
"print Large_1d_Array from history"
|
||||
gdb_test -nonl "output \$\$3" \
|
||||
"\\(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\
|
||||
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\
|
||||
25, 26, 27, 28, 29, 30, 31, 32, 33\\.\\.\\.\\)" \
|
||||
"output Large_1d_Array from history"
|
||||
|
||||
gdb_test "print \$\$2" \
|
||||
" = \\(\\(\\(1, 2, 3, 4\\), \\(5, 6, 7, 8\\),\
|
||||
\\(9, 10, 11, 12\\), \\(13, 14, 15, 16\\)\\),\
|
||||
\\(\\(17, 18, 19, 20\\), \\(21, 22, 23, 24\\),\
|
||||
\\(25, 26, 27, 28\\), \\(29, 30, 31, 32\\)\\),\
|
||||
\\(\\(33(?:, <unavailable>)\{3\}\\)(?:,\
|
||||
\\(<unavailable>(?:, <unavailable>)\{3\}\\))\{3\}\\),\
|
||||
\\(\\(<unavailable>(?:, <unavailable>)\{3\}\\)(?:,\
|
||||
\\(<unavailable>(?:, <unavailable>)\{3\}\\))\{3\}\\)\\)" \
|
||||
"print Large_3d_Array from history"
|
||||
gdb_test -nonl "output \$\$3" \
|
||||
"\\(\\(\\(1, 2, 3, 4\\), \\(5, 6, 7, 8\\),\
|
||||
\\(9, 10, 11, 12\\), \\(13, 14, 15, 16\\)\\),\
|
||||
\\(\\(17, 18, 19, 20\\), \\(21, 22, 23, 24\\),\
|
||||
\\(25, 26, 27, 28\\), \\(29, 30, 31, 32\\)\\),\
|
||||
\\(\\(33(?:, <unavailable>)\{3\}\\)(?:,\
|
||||
\\(<unavailable>(?:, <unavailable>)\{3\}\\))\{3\}\\),\
|
||||
\\(\\(<unavailable>(?:, <unavailable>)\{3\}\\)(?:,\
|
||||
\\(<unavailable>(?:, <unavailable>)\{3\}\\))\{3\}\\)\\)" \
|
||||
"output Large_3d_Array from history"
|
||||
}
|
||||
|
||||
gdb_test_no_output "set max-value-size unlimited"
|
||||
gdb_test_no_output "set print elements unlimited"
|
||||
gdb_test_no_output "set print repeats 2"
|
||||
|
||||
with_test_prefix "with unlimited print elements" {
|
||||
gdb_test "print \$\$" \
|
||||
" = \\(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\
|
||||
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\
|
||||
25, 26, 27, 28, 29, 30, 31, 32, 33,\
|
||||
<unavailable> <repeats 31 times>\\)" \
|
||||
"print Large_1d_Array from history"
|
||||
gdb_test -nonl "output \$\$2" \
|
||||
"\\(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\
|
||||
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\
|
||||
25, 26, 27, 28, 29, 30, 31, 32, 33,\
|
||||
<unavailable> <repeats 31 times>\\)" \
|
||||
"output Large_1d_Array from history"
|
||||
|
||||
gdb_test "print \$\$" \
|
||||
" = \\(\\(\\(1, 2, 3, 4\\), \\(5, 6, 7, 8\\),\
|
||||
\\(9, 10, 11, 12\\), \\(13, 14, 15, 16\\)\\),\
|
||||
\\(\\(17, 18, 19, 20\\), \\(21, 22, 23, 24\\),\
|
||||
\\(25, 26, 27, 28\\), \\(29, 30, 31, 32\\)\\),\
|
||||
\\(\\(33, <unavailable> <repeats 3 times>\\),\
|
||||
\\(<unavailable> <repeats 4 times>\\) <repeats 3 times>\\),\
|
||||
\\(\\(<unavailable> <repeats 4 times>\\)\
|
||||
<repeats 4 times>\\)\\)" \
|
||||
"print Large_3d_Array from history"
|
||||
gdb_test -nonl "output \$\$2" \
|
||||
"\\(\\(\\(1, 2, 3, 4\\), \\(5, 6, 7, 8\\),\
|
||||
\\(9, 10, 11, 12\\), \\(13, 14, 15, 16\\)\\),\
|
||||
\\(\\(17, 18, 19, 20\\), \\(21, 22, 23, 24\\),\
|
||||
\\(25, 26, 27, 28\\), \\(29, 30, 31, 32\\)\\),\
|
||||
\\(\\(33, <unavailable> <repeats 3 times>\\),\
|
||||
\\(<unavailable> <repeats 4 times>\\) <repeats 3 times>\\),\
|
||||
\\(\\(<unavailable> <repeats 4 times>\\) <repeats 4 times>\\)\\)" \
|
||||
"output Large_3d_Array from history"
|
||||
|
||||
gdb_test "print \$\[2\]" \
|
||||
" = \\(\\(17, 18, 19, 20\\), \\(21, 22, 23, 24\\),\
|
||||
\\(25, 26, 27, 28\\), \\(29, 30, 31, 32\\)\\)" \
|
||||
"print available Large_3d_Array row from history"
|
||||
gdb_test -nonl "output \$\$\[2\]" \
|
||||
"\\(\\(17, 18, 19, 20\\), \\(21, 22, 23, 24\\),\
|
||||
\\(25, 26, 27, 28\\), \\(29, 30, 31, 32\\)\\)" \
|
||||
"output available Large_3d_Array row from history"
|
||||
|
||||
gdb_test "print \$\$\[3\]" \
|
||||
" = \\(\\(33, <unavailable> <repeats 3 times>\\),\
|
||||
\\(<unavailable> <repeats 4 times>\\) <repeats 3 times>\\)" \
|
||||
"print partially available Large_3d_Array row from history"
|
||||
gdb_test -nonl "output \$\$2\[3\]" \
|
||||
"\\(\\(33, <unavailable> <repeats 3 times>\\),\
|
||||
\\(<unavailable> <repeats 4 times>\\) <repeats 3 times>\\)" \
|
||||
"output partially available Large_3d_Array row from history"
|
||||
|
||||
# These go straigth to the inferior.
|
||||
gdb_test "print \$\$2(3)" \
|
||||
" = \\(\\(33, 34, 35, 36\\), \\(37, 38, 39, 40\\),\
|
||||
\\(41, 42, 43, 44\\), \\(45, 46, 47, 48\\)\\)" \
|
||||
"print partially available Large_3d_Array row bypassing history"
|
||||
gdb_test -nonl "output \$\$3(3)" \
|
||||
"\\(\\(33, 34, 35, 36\\), \\(37, 38, 39, 40\\),\
|
||||
\\(41, 42, 43, 44\\), \\(45, 46, 47, 48\\)\\)" \
|
||||
"output partially available Large_3d_Array row bypassing history"
|
||||
|
||||
gdb_test "print \$\$3\[4\]" \
|
||||
" = <unavailable>" \
|
||||
"print unavailable Large_3d_Array row from history"
|
||||
gdb_test -nonl "output \$\$4\[4\]" \
|
||||
"<unavailable>" \
|
||||
"output unavailable Large_3d_Array row from history"
|
||||
|
||||
gdb_test "print \$\$4\[3\]\[1\]\[1\]" \
|
||||
" = 33" \
|
||||
"print available Large_3d_Array element from history"
|
||||
gdb_test -nonl "output \$\$5\[3\]\[1\]\[1\]" \
|
||||
"33" \
|
||||
"output available Large_3d_Array element from history"
|
||||
|
||||
gdb_test "print \$\$5\[3\]\[1\]\[2\]" \
|
||||
" = <unavailable>" \
|
||||
"print unavailable Large_3d_Array element from history"
|
||||
gdb_test -nonl "output \$\$6\[3\]\[1\]\[2\]" \
|
||||
"<unavailable>" \
|
||||
"output unavailable Large_3d_Array element from history"
|
||||
|
||||
gdb_test "print \$\$6\[3\]\[1\]\[1\] + \$\$6\[3\]\[1\]\[2\]" \
|
||||
"value is not available" \
|
||||
"print expression referring unavailable element from history"
|
||||
gdb_test "output \$\$6\[3\]\[1\]\[1\] + \$\$6\[3\]\[1\]\[2\]" \
|
||||
"value is not available" \
|
||||
"output expression referring unavailable element from history"
|
||||
}
|
37
gdb/testsuite/gdb.ada/limited-length/foo.adb
Normal file
37
gdb/testsuite/gdb.ada/limited-length/foo.adb
Normal file
@ -0,0 +1,37 @@
|
||||
-- This testcase is part of GDB, the GNU debugger.
|
||||
--
|
||||
-- Copyright 2023 Free Software Foundation, Inc.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
with Pck; use Pck;
|
||||
|
||||
procedure Foo is
|
||||
Large_1d_Array : array (1..64) of Integer;
|
||||
Large_3d_Array : array (1..4,1..4,1..4) of Integer;
|
||||
Count : Integer := 1;
|
||||
begin
|
||||
for i in 1 .. 4 loop
|
||||
for j in 1 .. 4 loop
|
||||
for k in 1 .. 4 loop
|
||||
Large_1d_Array (Count) := Count;
|
||||
Large_3d_Array (i,j,k) := Count;
|
||||
Count := Count + 1;
|
||||
end loop;
|
||||
end loop;
|
||||
end loop;
|
||||
Do_Nothing (Large_1d_Array'Address);
|
||||
Do_Nothing (Large_3d_Array'Address); -- STOP
|
||||
end Foo;
|
||||
|
25
gdb/testsuite/gdb.ada/limited-length/pck.adb
Normal file
25
gdb/testsuite/gdb.ada/limited-length/pck.adb
Normal file
@ -0,0 +1,25 @@
|
||||
-- This testcase is part of GDB, the GNU debugger.
|
||||
--
|
||||
-- Copyright 2023 Free Software Foundation, Inc.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package body Pck is
|
||||
|
||||
procedure Do_Nothing (A : System.Address) is
|
||||
begin
|
||||
null;
|
||||
end Do_Nothing;
|
||||
|
||||
end Pck;
|
21
gdb/testsuite/gdb.ada/limited-length/pck.ads
Normal file
21
gdb/testsuite/gdb.ada/limited-length/pck.ads
Normal file
@ -0,0 +1,21 @@
|
||||
-- This testcase is part of GDB, the GNU debugger.
|
||||
--
|
||||
-- Copyright 2023 Free Software Foundation, Inc.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
with System;
|
||||
package Pck is
|
||||
procedure Do_Nothing (A : System.Address);
|
||||
end Pck;
|
48
gdb/testsuite/gdb.base/limited-length.c
Normal file
48
gdb/testsuite/gdb.base/limited-length.c
Normal file
@ -0,0 +1,48 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
int large_1d_array[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
|
||||
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
|
||||
70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
|
||||
90, 91, 92, 93, 94, 95, 96, 97, 98, 99
|
||||
};
|
||||
|
||||
int large_2d_array[][10] = {
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
{10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
|
||||
{20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
|
||||
{30, 31, 32, 33, 34, 35, 36, 37, 38, 39},
|
||||
{40, 41, 42, 43, 44, 45, 46, 47, 48, 49},
|
||||
{50, 51, 52, 53, 54, 55, 56, 57, 58, 59},
|
||||
{60, 61, 62, 63, 64, 65, 66, 67, 68, 69},
|
||||
{70, 71, 72, 73, 74, 75, 76, 77, 78, 79},
|
||||
{80, 81, 82, 83, 84, 85, 86, 87, 88, 89},
|
||||
{90, 91, 92, 93, 94, 95, 96, 97, 98, 99}
|
||||
};
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return 0;
|
||||
}
|
242
gdb/testsuite/gdb.base/limited-length.exp
Normal file
242
gdb/testsuite/gdb.base/limited-length.exp
Normal file
@ -0,0 +1,242 @@
|
||||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Test GDB's limited array printing.
|
||||
|
||||
standard_testfile
|
||||
|
||||
if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} {
|
||||
return -1
|
||||
}
|
||||
|
||||
if {![runto_main]} {
|
||||
perror "couldn't run to breakpoint"
|
||||
continue
|
||||
}
|
||||
|
||||
with_test_prefix "with standard max-value size" {
|
||||
gdb_test "print large_1d_array" \
|
||||
" = \\\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,\
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,\
|
||||
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,\
|
||||
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,\
|
||||
72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,\
|
||||
84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,\
|
||||
96, 97, 98, 99\\\}"
|
||||
gdb_test -nonl "output large_1d_array" \
|
||||
"\\\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,\
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,\
|
||||
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,\
|
||||
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,\
|
||||
72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,\
|
||||
84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,\
|
||||
96, 97, 98, 99\\\}"
|
||||
gdb_test "print large_2d_array" \
|
||||
" = \\\{\\\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9\\\},\
|
||||
\\\{10, 11, 12, 13, 14, 15, 16, 17, 18, 19\\\},\
|
||||
\\\{20, 21, 22, 23, 24, 25, 26, 27, 28, 29\\\},\
|
||||
\\\{30, 31, 32, 33, 34, 35, 36, 37, 38, 39\\\},\
|
||||
\\\{40, 41, 42, 43, 44, 45, 46, 47, 48, 49\\\},\
|
||||
\\\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59\\\},\
|
||||
\\\{60, 61, 62, 63, 64, 65, 66, 67, 68, 69\\\},\
|
||||
\\\{70, 71, 72, 73, 74, 75, 76, 77, 78, 79\\\},\
|
||||
\\\{80, 81, 82, 83, 84, 85, 86, 87, 88, 89\\\},\
|
||||
\\\{90, 91, 92, 93, 94, 95, 96, 97, 98, 99\\\}\\\}"
|
||||
gdb_test -nonl "output large_2d_array" \
|
||||
"\\\{\\\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9\\\},\
|
||||
\\\{10, 11, 12, 13, 14, 15, 16, 17, 18, 19\\\},\
|
||||
\\\{20, 21, 22, 23, 24, 25, 26, 27, 28, 29\\\},\
|
||||
\\\{30, 31, 32, 33, 34, 35, 36, 37, 38, 39\\\},\
|
||||
\\\{40, 41, 42, 43, 44, 45, 46, 47, 48, 49\\\},\
|
||||
\\\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59\\\},\
|
||||
\\\{60, 61, 62, 63, 64, 65, 66, 67, 68, 69\\\},\
|
||||
\\\{70, 71, 72, 73, 74, 75, 76, 77, 78, 79\\\},\
|
||||
\\\{80, 81, 82, 83, 84, 85, 86, 87, 88, 89\\\},\
|
||||
\\\{90, 91, 92, 93, 94, 95, 96, 97, 98, 99\\\}\\\}"
|
||||
}
|
||||
|
||||
# Set the max-value-size so we can only print 51 elements.
|
||||
set elements 51
|
||||
set int_size [get_valueof "/d" "sizeof(large_1d_array\[0\])" "*unknown*"]
|
||||
gdb_test_no_output "set max-value-size [expr $int_size * $elements]"
|
||||
|
||||
with_test_prefix "with reduced max-value size" {
|
||||
gdb_test "print large_1d_array" \
|
||||
"\r\nvalue requires $decimal bytes, which is more than max-value-size"
|
||||
gdb_test "output large_1d_array" \
|
||||
"\r\nvalue requires $decimal bytes, which is more than max-value-size"
|
||||
gdb_test "print large_2d_array" \
|
||||
"\r\nvalue requires $decimal bytes, which is more than max-value-size"
|
||||
gdb_test "output large_2d_array" \
|
||||
"\r\nvalue requires $decimal bytes, which is more than max-value-size"
|
||||
}
|
||||
|
||||
gdb_test_no_output "set print elements 3"
|
||||
|
||||
with_test_prefix "with reduced print elements" {
|
||||
gdb_test "print large_1d_array" \
|
||||
" = \\\{0, 1, 2\\.\\.\\.\\\}"
|
||||
gdb_test -nonl "output large_1d_array" \
|
||||
"\\\{0, 1, 2\\.\\.\\.\\\}"
|
||||
|
||||
gdb_test "print \$" \
|
||||
" = \\\{0, 1, 2\\.\\.\\.\\\}" \
|
||||
"print large_1d_array from history"
|
||||
gdb_test -nonl "output \$\$" \
|
||||
"\\\{0, 1, 2\\.\\.\\.\\\}" \
|
||||
"output large_1d_array from history"
|
||||
|
||||
gdb_test "print large_2d_array" \
|
||||
" = \\\{\\\{0, 1, 2\\.\\.\\.\\\}, \\\{10, 11, 12\\.\\.\\.\\\},\
|
||||
\\\{20, 21, 22\\.\\.\\.\\\}\\.\\.\\.\\\}"
|
||||
gdb_test -nonl "output large_2d_array" \
|
||||
"\\\{\\\{0, 1, 2\\.\\.\\.\\\}, \\\{10, 11, 12\\.\\.\\.\\\},\
|
||||
\\\{20, 21, 22\\.\\.\\.\\\}\\.\\.\\.\\\}"
|
||||
|
||||
gdb_test "print \$" \
|
||||
" = \\\{\\\{0, 1, 2\\.\\.\\.\\\}, \\\{10, 11, 12\\.\\.\\.\\\},\
|
||||
\\\{20, 21, 22\\.\\.\\.\\\}\\.\\.\\.\\\}" \
|
||||
"print large_2d_array from history"
|
||||
gdb_test -nonl "output \$\$" \
|
||||
"\\\{\\\{0, 1, 2\\.\\.\\.\\\}, \\\{10, 11, 12\\.\\.\\.\\\},\
|
||||
\\\{20, 21, 22\\.\\.\\.\\\}\\.\\.\\.\\\}" \
|
||||
"output large_2d_array from history"
|
||||
}
|
||||
|
||||
gdb_test_no_output "set print elements $elements"
|
||||
|
||||
with_test_prefix "with print elements matching max-value size" {
|
||||
gdb_test "print \$\$2" \
|
||||
" = \\\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,\
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,\
|
||||
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\
|
||||
48, 49, 50\\.\\.\\.\\\}" \
|
||||
"print large_1d_array from history"
|
||||
gdb_test -nonl "output \$\$3" \
|
||||
"\\\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,\
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,\
|
||||
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\
|
||||
48, 49, 50\\.\\.\\.\\\}" \
|
||||
"output large_1d_array from history"
|
||||
|
||||
gdb_test "print \$\$2" \
|
||||
" = \\\{\\\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9\\\},\
|
||||
\\\{10, 11, 12, 13, 14, 15, 16, 17, 18, 19\\\},\
|
||||
\\\{20, 21, 22, 23, 24, 25, 26, 27, 28, 29\\\},\
|
||||
\\\{30, 31, 32, 33, 34, 35, 36, 37, 38, 39\\\},\
|
||||
\\\{40, 41, 42, 43, 44, 45, 46, 47, 48, 49\\\},\
|
||||
\\\{50(?:, <unavailable>)\{9\}\\\}(?:,\
|
||||
\\\{<unavailable>(?:, <unavailable>)\{9\}\\\})\{4\}\\\}" \
|
||||
"print large_2d_array from history"
|
||||
gdb_test -nonl "output \$\$3" \
|
||||
"\\\{\\\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9\\\},\
|
||||
\\\{10, 11, 12, 13, 14, 15, 16, 17, 18, 19\\\},\
|
||||
\\\{20, 21, 22, 23, 24, 25, 26, 27, 28, 29\\\},\
|
||||
\\\{30, 31, 32, 33, 34, 35, 36, 37, 38, 39\\\},\
|
||||
\\\{40, 41, 42, 43, 44, 45, 46, 47, 48, 49\\\},\
|
||||
\\\{50(?:, <unavailable>)\{9\}\\\}(?:,\
|
||||
\\\{<unavailable>(?:, <unavailable>)\{9\}\\\})\{4\}\\\}" \
|
||||
"output large_2d_array from history"
|
||||
}
|
||||
|
||||
gdb_test_no_output "set max-value-size unlimited"
|
||||
gdb_test_no_output "set print elements unlimited"
|
||||
gdb_test_no_output "set print repeats 3"
|
||||
|
||||
with_test_prefix "with unlimited print elements" {
|
||||
gdb_test "print \$\$" \
|
||||
" = \\\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,\
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,\
|
||||
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\
|
||||
48, 49, 50, <unavailable> <repeats 49 times>\\\}" \
|
||||
"print large_1d_array from history"
|
||||
gdb_test -nonl "output \$\$2" \
|
||||
"\\\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,\
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,\
|
||||
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\
|
||||
48, 49, 50, <unavailable> <repeats 49 times>\\\}" \
|
||||
"output large_1d_array from history"
|
||||
|
||||
gdb_test "print \$\$" \
|
||||
" = \\\{\\\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9\\\},\
|
||||
\\\{10, 11, 12, 13, 14, 15, 16, 17, 18, 19\\\},\
|
||||
\\\{20, 21, 22, 23, 24, 25, 26, 27, 28, 29\\\},\
|
||||
\\\{30, 31, 32, 33, 34, 35, 36, 37, 38, 39\\\},\
|
||||
\\\{40, 41, 42, 43, 44, 45, 46, 47, 48, 49\\\},\
|
||||
\\\{50, <unavailable> <repeats 9 times>\\\},\
|
||||
\\\{<unavailable> <repeats 10 times>\\\}\
|
||||
<repeats 4 times>\\\}" \
|
||||
"print large_2d_array from history"
|
||||
gdb_test -nonl "output \$\$2" \
|
||||
"\\\{\\\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9\\\},\
|
||||
\\\{10, 11, 12, 13, 14, 15, 16, 17, 18, 19\\\},\
|
||||
\\\{20, 21, 22, 23, 24, 25, 26, 27, 28, 29\\\},\
|
||||
\\\{30, 31, 32, 33, 34, 35, 36, 37, 38, 39\\\},\
|
||||
\\\{40, 41, 42, 43, 44, 45, 46, 47, 48, 49\\\},\
|
||||
\\\{50, <unavailable> <repeats 9 times>\\\},\
|
||||
\\\{<unavailable> <repeats 10 times>\\\}\
|
||||
<repeats 4 times>\\\}" \
|
||||
"output large_2d_array from history"
|
||||
|
||||
gdb_test "print \$\[4\]" \
|
||||
" = \\\{40, 41, 42, 43, 44, 45, 46, 47, 48, 49\\\}" \
|
||||
"print available large_2d_array row from history"
|
||||
gdb_test -nonl "output \$\$\[4\]" \
|
||||
"\\\{40, 41, 42, 43, 44, 45, 46, 47, 48, 49\\\}" \
|
||||
"output available large_2d_array row from history"
|
||||
|
||||
gdb_test "print \$\$\[5\]" \
|
||||
" = \\\{50, <unavailable> <repeats 9 times>\\\}" \
|
||||
"print partially available large_2d_array row from history"
|
||||
gdb_test -nonl "output \$\$2\[5\]" \
|
||||
"\\\{50, <unavailable> <repeats 9 times>\\\}" \
|
||||
"output partially available large_2d_array row from history"
|
||||
|
||||
gdb_test "print \$\$2\[6\]" \
|
||||
" = <unavailable>" \
|
||||
"print unavailable large_2d_array row from history"
|
||||
gdb_test -nonl "output \$\$3\[6\]" \
|
||||
"<unavailable>" \
|
||||
"output unavailable large_2d_array row from history"
|
||||
|
||||
gdb_test "print \$\$3\[5\]\[0\]" \
|
||||
" = 50" \
|
||||
"print available large_2d_array element from history"
|
||||
gdb_test -nonl "output \$\$4\[5\]\[0\]" \
|
||||
"50" \
|
||||
"output available large_2d_array element from history"
|
||||
|
||||
gdb_test "print \$\$4\[5\]\[1\]" \
|
||||
" = <unavailable>" \
|
||||
"print unavailable large_2d_array element from history"
|
||||
gdb_test -nonl "output \$\$5\[5\]\[1\]" \
|
||||
"<unavailable>" \
|
||||
"output unavailable large_2d_array element from history"
|
||||
|
||||
gdb_test "print \$\$5\[5\]\[0\] + \$\$5\[5\]\[1\]" \
|
||||
"value is not available" \
|
||||
"print expression referring unavailable element from history"
|
||||
gdb_test "output \$\$5\[5\]\[0\] + \$\$5\[5\]\[1\]" \
|
||||
"value is not available" \
|
||||
"output expression referring unavailable element from history"
|
||||
}
|
220
gdb/testsuite/gdb.fortran/limited-length.exp
Normal file
220
gdb/testsuite/gdb.fortran/limited-length.exp
Normal file
@ -0,0 +1,220 @@
|
||||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This file tests GDB's limited length array printing.
|
||||
|
||||
load_lib "fortran.exp"
|
||||
|
||||
require allow_fortran_tests
|
||||
|
||||
standard_testfile .f90
|
||||
|
||||
if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
|
||||
return -1
|
||||
}
|
||||
|
||||
if {![fortran_runto_main]} {
|
||||
perror "Could not run to main."
|
||||
continue
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "Break Here"]
|
||||
gdb_continue_to_breakpoint "stop-here" ".*Break Here.*"
|
||||
|
||||
with_test_prefix "with standard max-value size" {
|
||||
gdb_test "print large_4d_array" \
|
||||
" = \\(\\(\\(\\(1, 2, 3\\) \\(4, 5, 6\\) \\(7, 8, 9\\)\\)\
|
||||
\\(\\(10, 11, 12\\) \\(13, 14, 15\\) \\(16, 17, 18\\)\\)\
|
||||
\\(\\(19, 20, 21\\) \\(22, 23, 24\\) \\(25, 26, 27\\)\\)\\)\
|
||||
\\(\\(\\(28, 29, 30\\) \\(31, 32, 33\\) \\(34, 35, 36\\)\\)\
|
||||
\\(\\(37, 38, 39\\) \\(40, 41, 42\\) \\(43, 44, 45\\)\\)\
|
||||
\\(\\(46, 47, 48\\) \\(49, 50, 51\\) \\(52, 53, 54\\)\\)\\)\
|
||||
\\(\\(\\(55, 56, 57\\) \\(58, 59, 60\\) \\(61, 62, 63\\)\\)\
|
||||
\\(\\(64, 65, 66\\) \\(67, 68, 69\\) \\(70, 71, 72\\)\\)\
|
||||
\\(\\(73, 74, 75\\) \\(76, 77, 78\\)\
|
||||
\\(79, 80, 81\\)\\)\\)\\)"
|
||||
gdb_test -nonl "output large_4d_array" \
|
||||
"\\(\\(\\(\\(1, 2, 3\\) \\(4, 5, 6\\) \\(7, 8, 9\\)\\)\
|
||||
\\(\\(10, 11, 12\\) \\(13, 14, 15\\) \\(16, 17, 18\\)\\)\
|
||||
\\(\\(19, 20, 21\\) \\(22, 23, 24\\) \\(25, 26, 27\\)\\)\\)\
|
||||
\\(\\(\\(28, 29, 30\\) \\(31, 32, 33\\) \\(34, 35, 36\\)\\)\
|
||||
\\(\\(37, 38, 39\\) \\(40, 41, 42\\) \\(43, 44, 45\\)\\)\
|
||||
\\(\\(46, 47, 48\\) \\(49, 50, 51\\) \\(52, 53, 54\\)\\)\\)\
|
||||
\\(\\(\\(55, 56, 57\\) \\(58, 59, 60\\) \\(61, 62, 63\\)\\)\
|
||||
\\(\\(64, 65, 66\\) \\(67, 68, 69\\) \\(70, 71, 72\\)\\)\
|
||||
\\(\\(73, 74, 75\\) \\(76, 77, 78\\) \\(79, 80, 81\\)\\)\\)\\)"
|
||||
gdb_test "print large_1d_array" \
|
||||
" = \\(1, 2, 3, 4, 5, 6, 7, 8, 9,\
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18,\
|
||||
19, 20, 21, 22, 23, 24, 25, 26, 27,\
|
||||
28, 29, 30, 31, 32, 33, 34, 35, 36,\
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45,\
|
||||
46, 47, 48, 49, 50, 51, 52, 53, 54,\
|
||||
55, 56, 57, 58, 59, 60, 61, 62, 63,\
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72,\
|
||||
73, 74, 75, 76, 77, 78, 79, 80, 81\\)"
|
||||
gdb_test -nonl "output large_1d_array" \
|
||||
"\\(1, 2, 3, 4, 5, 6, 7, 8, 9,\
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18,\
|
||||
19, 20, 21, 22, 23, 24, 25, 26, 27,\
|
||||
28, 29, 30, 31, 32, 33, 34, 35, 36,\
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45,\
|
||||
46, 47, 48, 49, 50, 51, 52, 53, 54,\
|
||||
55, 56, 57, 58, 59, 60, 61, 62, 63,\
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72,\
|
||||
73, 74, 75, 76, 77, 78, 79, 80, 81\\)"
|
||||
}
|
||||
|
||||
# Set the max-value-size so we can only print 50 elements.
|
||||
set elements 50
|
||||
set elem_size [get_valueof "/d" "sizeof(large_1d_array(1))" "*unknown*"]
|
||||
gdb_test_no_output "set max-value-size [expr $elem_size * $elements]"
|
||||
|
||||
with_test_prefix "with reduced max-value size" {
|
||||
gdb_test "print large_4d_array" \
|
||||
"value requires $decimal bytes, which is more than max-value-size"
|
||||
gdb_test "output large_4d_array" \
|
||||
"value requires $decimal bytes, which is more than max-value-size"
|
||||
gdb_test "print large_1d_array" \
|
||||
"value requires $decimal bytes, which is more than max-value-size"
|
||||
gdb_test "output large_1d_array" \
|
||||
"value requires $decimal bytes, which is more than max-value-size"
|
||||
}
|
||||
|
||||
with_test_prefix "with reduced print -elements flag" {
|
||||
gdb_test "print -elements 5 -- large_4d_array" \
|
||||
" = \\(\\(\\(\\(1, 2, 3\\) \\(4, 5, \\.\\.\\.\\)\
|
||||
\\.\\.\\.\\) \\.\\.\\.\\) \\.\\.\\.\\)"
|
||||
gdb_test "print -elements 5 -- large_1d_array" \
|
||||
" = \\(1, 2, 3, 4, 5, \\.\\.\\.\\)"
|
||||
}
|
||||
|
||||
gdb_test_no_output "set print elements 5"
|
||||
|
||||
with_test_prefix "with reduced print elements" {
|
||||
gdb_test "print large_4d_array" \
|
||||
" = \\(\\(\\(\\(1, 2, 3\\) \\(4, 5, \\.\\.\\.\\)\
|
||||
\\.\\.\\.\\) \\.\\.\\.\\) \\.\\.\\.\\)"
|
||||
gdb_test -nonl "output large_4d_array" \
|
||||
"\\(\\(\\(\\(1, 2, 3\\) \\(4, 5, \\.\\.\\.\\)\
|
||||
\\.\\.\\.\\) \\.\\.\\.\\) \\.\\.\\.\\)"
|
||||
|
||||
gdb_test "print \$" \
|
||||
" = \\(\\(\\(\\(1, 2, 3\\) \\(4, 5, \\.\\.\\.\\)\
|
||||
\\.\\.\\.\\) \\.\\.\\.\\) \\.\\.\\.\\)" \
|
||||
"print large_4d_array from history"
|
||||
gdb_test -nonl "output \$\$" \
|
||||
"\\(\\(\\(\\(1, 2, 3\\) \\(4, 5, \\.\\.\\.\\)\
|
||||
\\.\\.\\.\\) \\.\\.\\.\\) \\.\\.\\.\\)" \
|
||||
"output large_4d_array from history"
|
||||
|
||||
gdb_test "print large_1d_array" \
|
||||
" = \\(1, 2, 3, 4, 5, \\.\\.\\.\\)"
|
||||
gdb_test -nonl "output large_1d_array" \
|
||||
"\\(1, 2, 3, 4, 5, \\.\\.\\.\\)"
|
||||
|
||||
gdb_test "print \$" \
|
||||
" = \\(1, 2, 3, 4, 5, \\.\\.\\.\\)" \
|
||||
"print large_1d_array from history"
|
||||
gdb_test -nonl "output \$\$" \
|
||||
"\\(1, 2, 3, 4, 5, \\.\\.\\.\\)" \
|
||||
"output large_1d_array from history"
|
||||
}
|
||||
|
||||
gdb_test_no_output "set print elements $elements"
|
||||
|
||||
with_test_prefix "with print elements matching max-value size" {
|
||||
gdb_test "print \$\$2" \
|
||||
" = \\(\\(\\(\\(1, 2, 3\\) \\(4, 5, 6\\) \\(7, 8, 9\\)\\)\
|
||||
\\(\\(10, 11, 12\\) \\(13, 14, 15\\) \\(16, 17, 18\\)\\)\
|
||||
\\(\\(19, 20, 21\\) \\(22, 23, 24\\) \\(25, 26, 27\\)\\)\\)\
|
||||
\\(\\(\\(28, 29, 30\\) \\(31, 32, 33\\) \\(34, 35, 36\\)\\)\
|
||||
\\(\\(37, 38, 39\\) \\(40, 41, 42\\) \\(43, 44, 45\\)\\)\
|
||||
\\(\\(46, 47, 48\\) \\(49, 50, \\.\\.\\.\\) \\.\\.\\.\\)\\)\
|
||||
\\.\\.\\.\\)" \
|
||||
"print large_4d_array from history"
|
||||
gdb_test -nonl "output \$\$3" \
|
||||
"\\(\\(\\(\\(1, 2, 3\\) \\(4, 5, 6\\) \\(7, 8, 9\\)\\)\
|
||||
\\(\\(10, 11, 12\\) \\(13, 14, 15\\) \\(16, 17, 18\\)\\)\
|
||||
\\(\\(19, 20, 21\\) \\(22, 23, 24\\) \\(25, 26, 27\\)\\)\\)\
|
||||
\\(\\(\\(28, 29, 30\\) \\(31, 32, 33\\) \\(34, 35, 36\\)\\)\
|
||||
\\(\\(37, 38, 39\\) \\(40, 41, 42\\) \\(43, 44, 45\\)\\)\
|
||||
\\(\\(46, 47, 48\\) \\(49, 50, \\.\\.\\.\\) \\.\\.\\.\\)\\)\
|
||||
\\.\\.\\.\\)" \
|
||||
"output large_4d_array from history"
|
||||
|
||||
gdb_test "print \$\$2" \
|
||||
" = \\(1, 2, 3, 4, 5, 6, 7, 8, 9,\
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18,\
|
||||
19, 20, 21, 22, 23, 24, 25, 26, 27,\
|
||||
28, 29, 30, 31, 32, 33, 34, 35, 36,\
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45,\
|
||||
46, 47, 48, 49, 50, \\.\\.\\.\\)" \
|
||||
"print large_1d_array from history"
|
||||
gdb_test -nonl "output \$\$2" \
|
||||
"\\(1, 2, 3, 4, 5, 6, 7, 8, 9,\
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18,\
|
||||
19, 20, 21, 22, 23, 24, 25, 26, 27,\
|
||||
28, 29, 30, 31, 32, 33, 34, 35, 36,\
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45,\
|
||||
46, 47, 48, 49, 50, \\.\\.\\.\\)" \
|
||||
"output large_1d_array from history"
|
||||
}
|
||||
|
||||
gdb_test_no_output "set max-value-size unlimited"
|
||||
gdb_test_no_output "set print elements unlimited"
|
||||
gdb_test_no_output "set print repeats 2"
|
||||
|
||||
with_test_prefix "with unlimited print elements" {
|
||||
gdb_test "print \$\$" \
|
||||
" = \\(\\(\\(\\(1, 2, 3\\) \\(4, 5, 6\\) \\(7, 8, 9\\)\\)\
|
||||
\\(\\(10, 11, 12\\) \\(13, 14, 15\\) \\(16, 17, 18\\)\\)\
|
||||
\\(\\(19, 20, 21\\) \\(22, 23, 24\\) \\(25, 26, 27\\)\\)\\)\
|
||||
\\(\\(\\(28, 29, 30\\) \\(31, 32, 33\\) \\(34, 35, 36\\)\\)\
|
||||
\\(\\(37, 38, 39\\) \\(40, 41, 42\\) \\(43, 44, 45\\)\\)\
|
||||
\\(\\(46, 47, 48\\) \\(49, 50, <unavailable>\\)\
|
||||
\\(<unavailable>, <repeats 3 times>\\)\\)\\)\
|
||||
\\(\\(\\(<unavailable>, <repeats 3 times>\\)\
|
||||
<repeats 3 times>\\) <repeats 3 times>\\)\\)" \
|
||||
"print large_4d_array from history"
|
||||
gdb_test -nonl "output \$\$2" \
|
||||
"\\(\\(\\(\\(1, 2, 3\\) \\(4, 5, 6\\) \\(7, 8, 9\\)\\)\
|
||||
\\(\\(10, 11, 12\\) \\(13, 14, 15\\) \\(16, 17, 18\\)\\)\
|
||||
\\(\\(19, 20, 21\\) \\(22, 23, 24\\) \\(25, 26, 27\\)\\)\\)\
|
||||
\\(\\(\\(28, 29, 30\\) \\(31, 32, 33\\) \\(34, 35, 36\\)\\)\
|
||||
\\(\\(37, 38, 39\\) \\(40, 41, 42\\) \\(43, 44, 45\\)\\)\
|
||||
\\(\\(46, 47, 48\\) \\(49, 50, <unavailable>\\)\
|
||||
\\(<unavailable>, <repeats 3 times>\\)\\)\\)\
|
||||
\\(\\(\\(<unavailable>, <repeats 3 times>\\)\
|
||||
<repeats 3 times>\\) <repeats 3 times>\\)\\)" \
|
||||
"output large_4d_array from history"
|
||||
|
||||
gdb_test "print \$\$" \
|
||||
" = \\(1, 2, 3, 4, 5, 6, 7, 8, 9,\
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18,\
|
||||
19, 20, 21, 22, 23, 24, 25, 26, 27,\
|
||||
28, 29, 30, 31, 32, 33, 34, 35, 36,\
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45,\
|
||||
46, 47, 48, 49, 50, <unavailable>, <repeats 31 times>\\)" \
|
||||
"print large_1d_array from history"
|
||||
gdb_test -nonl "output \$\$2" \
|
||||
"\\(1, 2, 3, 4, 5, 6, 7, 8, 9,\
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18,\
|
||||
19, 20, 21, 22, 23, 24, 25, 26, 27,\
|
||||
28, 29, 30, 31, 32, 33, 34, 35, 36,\
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45,\
|
||||
46, 47, 48, 49, 50, <unavailable>, <repeats 31 times>\\)" \
|
||||
"output large_1d_array from history"
|
||||
}
|
39
gdb/testsuite/gdb.fortran/limited-length.f90
Normal file
39
gdb/testsuite/gdb.fortran/limited-length.f90
Normal file
@ -0,0 +1,39 @@
|
||||
! This testcase is part of GDB, the GNU debugger.
|
||||
!
|
||||
! Copyright 2023 Free Software Foundation, Inc.
|
||||
!
|
||||
! This program is free software; you can redistribute it and/or modify
|
||||
! it under the terms of the GNU General Public License as published by
|
||||
! the Free Software Foundation; either version 2 of the License, or
|
||||
! (at your option) any later version.
|
||||
!
|
||||
! This program is distributed in the hope that it will be useful,
|
||||
! but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
! GNU General Public License for more details.
|
||||
!
|
||||
! You should have received a copy of the GNU General Public License
|
||||
! along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
program main
|
||||
integer(kind=8), dimension (3, 3, 3, 3) :: large_4d_array = reshape ((/ &
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, &
|
||||
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, &
|
||||
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, &
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, &
|
||||
63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, &
|
||||
78, 79, 80, 81/), (/3, 3, 3, 3/))
|
||||
|
||||
integer(kind=8), dimension (81) :: large_1d_array = reshape ((/ &
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, &
|
||||
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, &
|
||||
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, &
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, &
|
||||
63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, &
|
||||
78, 79, 80, 81/), (/81/))
|
||||
|
||||
print *, ""
|
||||
print *, "" ! Break Here
|
||||
print *, large_4d_array
|
||||
print *, large_1d_array
|
||||
end program main
|
@ -2018,13 +2018,21 @@ value_print_array_elements (struct value *val, struct ui_file *stream,
|
||||
UINT_MAX (unlimited). */
|
||||
if (options->repeat_count_threshold < UINT_MAX)
|
||||
{
|
||||
bool unavailable = value_entirely_unavailable (element);
|
||||
bool available = value_entirely_available (element);
|
||||
|
||||
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))
|
||||
bool repeated = ((available
|
||||
&& value_entirely_available (rep_elt)
|
||||
&& value_contents_eq (element, rep_elt))
|
||||
|| (unavailable
|
||||
&& value_entirely_unavailable (rep_elt)));
|
||||
if (!repeated)
|
||||
break;
|
||||
++reps;
|
||||
++rep1;
|
||||
|
187
gdb/value.c
187
gdb/value.c
@ -373,6 +373,14 @@ struct value
|
||||
treated pretty much the same, except not-saved registers have a
|
||||
different string representation and related error strings. */
|
||||
std::vector<range> optimized_out;
|
||||
|
||||
/* This is only non-zero for values of TYPE_CODE_ARRAY and if the size of
|
||||
the array in inferior memory is greater than max_value_size. If these
|
||||
conditions are met then, when the value is loaded from the inferior
|
||||
GDB will only load a portion of the array into memory, and
|
||||
limited_length will be set to indicate the length in octets that were
|
||||
loaded from the inferior. */
|
||||
ULONGEST limited_length = 0;
|
||||
};
|
||||
|
||||
/* See value.h. */
|
||||
@ -1053,6 +1061,94 @@ check_type_length_before_alloc (const struct type *type)
|
||||
}
|
||||
}
|
||||
|
||||
/* When this has a value, it is used to limit the number of array elements
|
||||
of an array that are loaded into memory when an array value is made
|
||||
non-lazy. */
|
||||
static gdb::optional<int> array_length_limiting_element_count;
|
||||
|
||||
/* See value.h. */
|
||||
scoped_array_length_limiting::scoped_array_length_limiting (int elements)
|
||||
{
|
||||
m_old_value = array_length_limiting_element_count;
|
||||
array_length_limiting_element_count.emplace (elements);
|
||||
}
|
||||
|
||||
/* See value.h. */
|
||||
scoped_array_length_limiting::~scoped_array_length_limiting ()
|
||||
{
|
||||
array_length_limiting_element_count = m_old_value;
|
||||
}
|
||||
|
||||
/* Find the inner element type for ARRAY_TYPE. */
|
||||
|
||||
static struct type *
|
||||
find_array_element_type (struct type *array_type)
|
||||
{
|
||||
array_type = check_typedef (array_type);
|
||||
gdb_assert (array_type->code () == TYPE_CODE_ARRAY);
|
||||
|
||||
if (current_language->la_language == language_fortran)
|
||||
while (array_type->code () == TYPE_CODE_ARRAY)
|
||||
{
|
||||
array_type = array_type->target_type ();
|
||||
array_type = check_typedef (array_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
array_type = array_type->target_type ();
|
||||
array_type = check_typedef (array_type);
|
||||
}
|
||||
|
||||
return array_type;
|
||||
}
|
||||
|
||||
/* Return the limited length of ARRAY_TYPE, which must be of
|
||||
TYPE_CODE_ARRAY. This function can only be called when the global
|
||||
ARRAY_LENGTH_LIMITING_ELEMENT_COUNT has a value.
|
||||
|
||||
The limited length of an array is the smallest of either (1) the total
|
||||
size of the array type, or (2) the array target type multiplies by the
|
||||
array_length_limiting_element_count. */
|
||||
|
||||
static ULONGEST
|
||||
calculate_limited_array_length (struct type *array_type)
|
||||
{
|
||||
gdb_assert (array_length_limiting_element_count.has_value ());
|
||||
|
||||
array_type = check_typedef (array_type);
|
||||
gdb_assert (array_type->code () == TYPE_CODE_ARRAY);
|
||||
|
||||
struct type *elm_type = find_array_element_type (array_type);
|
||||
ULONGEST len = (elm_type->length ()
|
||||
* (*array_length_limiting_element_count));
|
||||
len = std::min (len, array_type->length ());
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Try to limit ourselves to only fetching the limited number of
|
||||
elements. However, if this limited number of elements still
|
||||
puts us over max_value_size, then we still refuse it and
|
||||
return failure here, which will ultimately throw an error. */
|
||||
|
||||
static bool
|
||||
set_limited_array_length (struct value *val)
|
||||
{
|
||||
ULONGEST limit = val->limited_length;
|
||||
ULONGEST len = value_type (val)->length ();
|
||||
|
||||
if (array_length_limiting_element_count.has_value ())
|
||||
len = calculate_limited_array_length (value_type (val));
|
||||
|
||||
if (limit != 0 && len > limit)
|
||||
len = limit;
|
||||
if (len > max_value_size)
|
||||
return false;
|
||||
|
||||
val->limited_length = max_value_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Allocate the contents of VAL if it has not been allocated yet.
|
||||
If CHECK_SIZE is true, then apply the usual max-value-size checks. */
|
||||
|
||||
@ -1061,10 +1157,26 @@ allocate_value_contents (struct value *val, bool check_size)
|
||||
{
|
||||
if (!val->contents)
|
||||
{
|
||||
struct type *enclosing_type = value_enclosing_type (val);
|
||||
ULONGEST len = enclosing_type->length ();
|
||||
|
||||
if (check_size)
|
||||
check_type_length_before_alloc (val->enclosing_type);
|
||||
val->contents.reset
|
||||
((gdb_byte *) xzalloc (val->enclosing_type->length ()));
|
||||
{
|
||||
/* If we are allocating the contents of an array, which
|
||||
is greater in size than max_value_size, and there is
|
||||
an element limit in effect, then we can possibly try
|
||||
to load only a sub-set of the array contents into
|
||||
GDB's memory. */
|
||||
if (value_type (val) == enclosing_type
|
||||
&& value_type (val)->code () == TYPE_CODE_ARRAY
|
||||
&& len > max_value_size
|
||||
&& set_limited_array_length (val))
|
||||
len = val->limited_length;
|
||||
else
|
||||
check_type_length_before_alloc (enclosing_type);
|
||||
}
|
||||
|
||||
val->contents.reset ((gdb_byte *) xzalloc (len));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1791,10 +1903,7 @@ value_copy (const value *arg)
|
||||
struct type *encl_type = value_enclosing_type (arg);
|
||||
struct value *val;
|
||||
|
||||
if (value_lazy (arg))
|
||||
val = allocate_value_lazy (encl_type);
|
||||
else
|
||||
val = allocate_value (encl_type, false);
|
||||
val = allocate_value_lazy (encl_type);
|
||||
val->type = arg->type;
|
||||
VALUE_LVAL (val) = arg->lval;
|
||||
val->location = arg->location;
|
||||
@ -1811,17 +1920,28 @@ value_copy (const value *arg)
|
||||
val->initialized = arg->initialized;
|
||||
val->unavailable = arg->unavailable;
|
||||
val->optimized_out = arg->optimized_out;
|
||||
val->parent = arg->parent;
|
||||
val->limited_length = arg->limited_length;
|
||||
|
||||
if (!value_lazy (val) && !value_entirely_optimized_out (val))
|
||||
if (!value_lazy (val)
|
||||
&& !(value_entirely_optimized_out (val)
|
||||
|| value_entirely_unavailable (val)))
|
||||
{
|
||||
ULONGEST length = val->limited_length;
|
||||
if (length == 0)
|
||||
length = value_enclosing_type (val)->length ();
|
||||
|
||||
gdb_assert (arg->contents != nullptr);
|
||||
ULONGEST length = value_enclosing_type (arg)->length ();
|
||||
const auto &arg_view
|
||||
= gdb::make_array_view (arg->contents.get (), length);
|
||||
copy (arg_view, value_contents_all_raw (val));
|
||||
|
||||
allocate_value_contents (val, false);
|
||||
gdb::array_view<gdb_byte> val_contents
|
||||
= value_contents_all_raw (val).slice (0, length);
|
||||
|
||||
copy (arg_view, val_contents);
|
||||
}
|
||||
|
||||
val->parent = arg->parent;
|
||||
if (VALUE_LVAL (val) == lval_computed)
|
||||
{
|
||||
const struct lval_funcs *funcs = val->location.computed.funcs;
|
||||
@ -1955,12 +2075,34 @@ set_value_component_location (struct value *component,
|
||||
int
|
||||
record_latest_value (struct value *val)
|
||||
{
|
||||
struct type *enclosing_type = value_enclosing_type (val);
|
||||
struct type *type = value_type (val);
|
||||
|
||||
/* We don't want this value to have anything to do with the inferior anymore.
|
||||
In particular, "set $1 = 50" should not affect the variable from which
|
||||
the value was taken, and fast watchpoints should be able to assume that
|
||||
a value on the value history never changes. */
|
||||
if (value_lazy (val))
|
||||
value_fetch_lazy (val);
|
||||
{
|
||||
/* We know that this is a _huge_ array, any attempt to fetch this
|
||||
is going to cause GDB to throw an error. However, to allow
|
||||
the array to still be displayed we fetch its contents up to
|
||||
`max_value_size' and mark anything beyond "unavailable" in
|
||||
the history. */
|
||||
if (type->code () == TYPE_CODE_ARRAY
|
||||
&& type->length () > max_value_size
|
||||
&& array_length_limiting_element_count.has_value ()
|
||||
&& enclosing_type == type
|
||||
&& calculate_limited_array_length (type) <= max_value_size)
|
||||
val->limited_length = max_value_size;
|
||||
|
||||
value_fetch_lazy (val);
|
||||
}
|
||||
|
||||
ULONGEST limit = val->limited_length;
|
||||
if (limit != 0)
|
||||
mark_value_bytes_unavailable (val, limit,
|
||||
enclosing_type->length () - limit);
|
||||
|
||||
/* Mark the value as recorded in the history for the availability check. */
|
||||
val->in_history = true;
|
||||
@ -4060,10 +4202,23 @@ value_fetch_lazy_memory (struct value *val)
|
||||
CORE_ADDR addr = value_address (val);
|
||||
struct type *type = check_typedef (value_enclosing_type (val));
|
||||
|
||||
if (type->length ())
|
||||
read_value_memory (val, 0, value_stack (val),
|
||||
addr, value_contents_all_raw (val).data (),
|
||||
type_length_units (type));
|
||||
/* Figure out how much we should copy from memory. Usually, this is just
|
||||
the size of the type, but, for arrays, we might only be loading a
|
||||
small part of the array (this is only done for very large arrays). */
|
||||
int len = 0;
|
||||
if (val->limited_length > 0)
|
||||
{
|
||||
gdb_assert (value_type (val)->code () == TYPE_CODE_ARRAY);
|
||||
len = val->limited_length;
|
||||
}
|
||||
else if (type->length () > 0)
|
||||
len = type_length_units (type);
|
||||
|
||||
gdb_assert (len >= 0);
|
||||
|
||||
if (len > 0)
|
||||
read_value_memory (val, 0, value_stack (val), addr,
|
||||
value_contents_all_raw (val).data (), len);
|
||||
}
|
||||
|
||||
/* Helper for value_fetch_lazy when the value is in a register. */
|
||||
|
17
gdb/value.h
17
gdb/value.h
@ -1228,4 +1228,21 @@ extern void finalize_values ();
|
||||
of floating-point, fixed-point, or integer type. */
|
||||
extern gdb_mpq value_to_gdb_mpq (struct value *value);
|
||||
|
||||
/* While an instance of this class is live, and array values that are
|
||||
created, that are larger than max_value_size, will be restricted in size
|
||||
to a particular number of elements. */
|
||||
|
||||
struct scoped_array_length_limiting
|
||||
{
|
||||
/* Limit any large array values to only contain ELEMENTS elements. */
|
||||
scoped_array_length_limiting (int elements);
|
||||
|
||||
/* Restore the previous array value limit. */
|
||||
~scoped_array_length_limiting ();
|
||||
|
||||
private:
|
||||
/* Used to hold the previous array value element limit. */
|
||||
gdb::optional<int> m_old_value;
|
||||
};
|
||||
|
||||
#endif /* !defined (VALUE_H) */
|
||||
|
Loading…
Reference in New Issue
Block a user