forked from Imagelibrary/binutils-gdb
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:
committed by
Maciej W. Rozycki
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
|
keyword already gave an error when used multiple times with the
|
||||||
watch command, this remains unchanged.
|
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
|
* New commands
|
||||||
|
|
||||||
maintenance print record-instruction [ N ]
|
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
|
Setting @var{number-of-elements} to @code{unlimited} or zero means
|
||||||
that the number of elements to print is unlimited.
|
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
|
@item show print elements
|
||||||
Display the number of elements of a large array that @value{GDBN} will print.
|
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.
|
@value{GDBN} to try and allocate an overly large amount of memory.
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
|
@anchor{set max-value-size}
|
||||||
@kindex set max-value-size
|
@kindex set max-value-size
|
||||||
@item set max-value-size @var{bytes}
|
@item set max-value-size @var{bytes}
|
||||||
@itemx set max-value-size unlimited
|
@itemx set max-value-size unlimited
|
||||||
|
|||||||
@@ -261,10 +261,20 @@ public:
|
|||||||
size_t dim_indx = m_dimension - 1;
|
size_t dim_indx = m_dimension - 1;
|
||||||
struct type *elt_type_prev = m_elt_type_prev;
|
struct type *elt_type_prev = m_elt_type_prev;
|
||||||
LONGEST elt_off_prev = m_elt_off_prev;
|
LONGEST elt_off_prev = m_elt_off_prev;
|
||||||
bool repeated = (m_options->repeat_count_threshold < UINT_MAX
|
bool repeated = false;
|
||||||
&& elt_type_prev != nullptr
|
|
||||||
&& value_contents_eq (m_val, elt_off_prev, m_val, elt_off,
|
if (m_options->repeat_count_threshold < UINT_MAX
|
||||||
elt_type->length ()));
|
&& 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)
|
if (repeated)
|
||||||
m_nrepeats++;
|
m_nrepeats++;
|
||||||
@@ -333,7 +343,7 @@ private:
|
|||||||
have been sliced and we do not want to compare any memory contents
|
have been sliced and we do not want to compare any memory contents
|
||||||
present between the slices requested. */
|
present between the slices requested. */
|
||||||
bool
|
bool
|
||||||
dimension_contents_eq (const struct value *val, struct type *type,
|
dimension_contents_eq (struct value *val, struct type *type,
|
||||||
LONGEST offset1, LONGEST offset2)
|
LONGEST offset1, LONGEST offset2)
|
||||||
{
|
{
|
||||||
if (type->code () == TYPE_CODE_ARRAY
|
if (type->code () == TYPE_CODE_ARRAY
|
||||||
@@ -362,8 +372,16 @@ private:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
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. */
|
/* The number of elements printed so far. */
|
||||||
|
|||||||
@@ -1242,6 +1242,11 @@ print_command_parse_format (const char **expp, const char *cmdname,
|
|||||||
void
|
void
|
||||||
print_value (value *val, const value_print_options &opts)
|
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);
|
int histindex = record_latest_value (val);
|
||||||
|
|
||||||
annotate_value_history_begin (histindex, value_type (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)
|
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
|
/* VOIDPRINT is true to indicate that we do want to print a void
|
||||||
value, so invert it for parse_expression. */
|
value, so invert it for parse_expression. */
|
||||||
expression_up expr = parse_expression (exp, nullptr, !voidprint);
|
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);
|
get_formatted_print_options (&opts, format);
|
||||||
opts.raw = fmt.raw;
|
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);
|
print_formatted (val, fmt.size, &opts, gdb_stdout);
|
||||||
|
|
||||||
annotate_value_end ();
|
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). */
|
UINT_MAX (unlimited). */
|
||||||
if (options->repeat_count_threshold < UINT_MAX)
|
if (options->repeat_count_threshold < UINT_MAX)
|
||||||
{
|
{
|
||||||
|
bool unavailable = value_entirely_unavailable (element);
|
||||||
|
bool available = value_entirely_available (element);
|
||||||
|
|
||||||
while (rep1 < len)
|
while (rep1 < len)
|
||||||
{
|
{
|
||||||
struct value *rep_elt
|
struct value *rep_elt
|
||||||
= value_from_component_bitsize (val, elttype,
|
= value_from_component_bitsize (val, elttype,
|
||||||
rep1 * bit_stride,
|
rep1 * bit_stride,
|
||||||
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;
|
break;
|
||||||
++reps;
|
++reps;
|
||||||
++rep1;
|
++rep1;
|
||||||
|
|||||||
183
gdb/value.c
183
gdb/value.c
@@ -373,6 +373,14 @@ struct value
|
|||||||
treated pretty much the same, except not-saved registers have a
|
treated pretty much the same, except not-saved registers have a
|
||||||
different string representation and related error strings. */
|
different string representation and related error strings. */
|
||||||
std::vector<range> optimized_out;
|
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. */
|
/* 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.
|
/* 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. */
|
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)
|
if (!val->contents)
|
||||||
{
|
{
|
||||||
|
struct type *enclosing_type = value_enclosing_type (val);
|
||||||
|
ULONGEST len = enclosing_type->length ();
|
||||||
|
|
||||||
if (check_size)
|
if (check_size)
|
||||||
check_type_length_before_alloc (val->enclosing_type);
|
{
|
||||||
val->contents.reset
|
/* If we are allocating the contents of an array, which
|
||||||
((gdb_byte *) xzalloc (val->enclosing_type->length ()));
|
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 type *encl_type = value_enclosing_type (arg);
|
||||||
struct value *val;
|
struct value *val;
|
||||||
|
|
||||||
if (value_lazy (arg))
|
|
||||||
val = allocate_value_lazy (encl_type);
|
val = allocate_value_lazy (encl_type);
|
||||||
else
|
|
||||||
val = allocate_value (encl_type, false);
|
|
||||||
val->type = arg->type;
|
val->type = arg->type;
|
||||||
VALUE_LVAL (val) = arg->lval;
|
VALUE_LVAL (val) = arg->lval;
|
||||||
val->location = arg->location;
|
val->location = arg->location;
|
||||||
@@ -1811,17 +1920,28 @@ value_copy (const value *arg)
|
|||||||
val->initialized = arg->initialized;
|
val->initialized = arg->initialized;
|
||||||
val->unavailable = arg->unavailable;
|
val->unavailable = arg->unavailable;
|
||||||
val->optimized_out = arg->optimized_out;
|
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);
|
gdb_assert (arg->contents != nullptr);
|
||||||
ULONGEST length = value_enclosing_type (arg)->length ();
|
|
||||||
const auto &arg_view
|
const auto &arg_view
|
||||||
= gdb::make_array_view (arg->contents.get (), length);
|
= 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)
|
if (VALUE_LVAL (val) == lval_computed)
|
||||||
{
|
{
|
||||||
const struct lval_funcs *funcs = val->location.computed.funcs;
|
const struct lval_funcs *funcs = val->location.computed.funcs;
|
||||||
@@ -1955,12 +2075,34 @@ set_value_component_location (struct value *component,
|
|||||||
int
|
int
|
||||||
record_latest_value (struct value *val)
|
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.
|
/* 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
|
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
|
the value was taken, and fast watchpoints should be able to assume that
|
||||||
a value on the value history never changes. */
|
a value on the value history never changes. */
|
||||||
if (value_lazy (val))
|
if (value_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);
|
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. */
|
/* Mark the value as recorded in the history for the availability check. */
|
||||||
val->in_history = true;
|
val->in_history = true;
|
||||||
@@ -4060,10 +4202,23 @@ value_fetch_lazy_memory (struct value *val)
|
|||||||
CORE_ADDR addr = value_address (val);
|
CORE_ADDR addr = value_address (val);
|
||||||
struct type *type = check_typedef (value_enclosing_type (val));
|
struct type *type = check_typedef (value_enclosing_type (val));
|
||||||
|
|
||||||
if (type->length ())
|
/* Figure out how much we should copy from memory. Usually, this is just
|
||||||
read_value_memory (val, 0, value_stack (val),
|
the size of the type, but, for arrays, we might only be loading a
|
||||||
addr, value_contents_all_raw (val).data (),
|
small part of the array (this is only done for very large arrays). */
|
||||||
type_length_units (type));
|
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. */
|
/* 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. */
|
of floating-point, fixed-point, or integer type. */
|
||||||
extern gdb_mpq value_to_gdb_mpq (struct value *value);
|
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) */
|
#endif /* !defined (VALUE_H) */
|
||||||
|
|||||||
Reference in New Issue
Block a user