diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2019-03-21 15:13:23 +0000 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2019-04-29 22:01:09 +0100 |
commit | 2e62ab400ff96334c92e5acf0a462cb9dc0d19a7 (patch) | |
tree | 2904968bffb30b8fbac114461b987424210de56e /gdb/valprint.c | |
parent | 4be290b2517839872ef7de47230be8dbd291a7e5 (diff) | |
download | gdb-2e62ab400ff96334c92e5acf0a462cb9dc0d19a7.zip gdb-2e62ab400ff96334c92e5acf0a462cb9dc0d19a7.tar.gz gdb-2e62ab400ff96334c92e5acf0a462cb9dc0d19a7.tar.bz2 |
gdb: Introduce 'print max-depth' feature
Introduce a new print setting max-depth which can be set with 'set
print max-depth DEPTH'. The default value of DEPTH is 20, but this
can also be set to unlimited.
When GDB is printing a value containing nested structures GDB will
stop descending at depth DEPTH. Here is a small example:
typedef struct s1 { int a; } s1;
typedef struct s2 { s1 b; } s2;
typedef struct s3 { s2 c; } s3;
typedef struct s4 { s3 d; } s4;
s4 var = { { { { 3 } } } };
The following table shows how various depth settings affect printing
of 'var':
| Depth Setting | Result of 'p var' |
|---------------+--------------------------------|
| Unlimited | $1 = {d = {c = {b = {a = 3}}}} |
| 4 | $1 = {d = {c = {b = {a = 3}}}} |
| 3 | $1 = {d = {c = {b = {...}}}} |
| 2 | $1 = {d = {c = {...}}} |
| 1 | $1 = {d = {...}} |
| 0 | $1 = {...} |
Only structures, unions, and arrays are replaced in this way, scalars
and strings are not replaced.
The replacement is counted from the level at which you print, not from
the top level of the structure. So, consider the above example and
this GDB session:
(gdb) set print max-depth 2
(gdb) p var
$1 = {d = {c = {...}}}
(gdb) p var.d
$2 = {c = {b = {...}}}
(gdb) p var.d.c
$3 = {b = {a = 3}}
Setting the max-depth to 2 doesn't prevent the user from exploring
deeper into 'var' by asking for specific sub-fields to be printed.
The motivation behind this feature is to try and give the user more
control over how much is printed when examining large, complex data
structures.
The default max-depth of 20 means that there is a change in GDB's
default behaviour. Someone printing a data structure with 20 levels
of nesting will now see '{...}' instead of their data, they would need
to adjust the max depth, or call print again naming a specific field
in order to dig deeper into their data structure. If this is
considered a problem then we could increase the default, or even make
the default unlimited.
This commit relies on the previous commit, which added a new field to
the language structure, this new field was a string that contained the
pattern that should be used when a structure/union/array is replaced
in the output, this allows languages to use a syntax that is more
appropriate, mostly this will be selecting the correct types of
bracket '(...)' or '{...}', both of which are currently in use.
This commit should have no impact on MI output, expressions are
printed through the MI using -var-create and then -var-list-children.
As each use of -var-list-children only ever displays a single level of
an expression then the max-depth setting will have no impact.
This commit also adds the max-depth mechanism to the scripting
language pretty printers following basically the same rules as for the
built in value printing.
One quirk is that when printing a value using the display hint 'map',
if the keys of the map are structs then GDB will hide the keys one
depth level after it hides the values, this ensures that GDB produces
output like this:
$1 = map_object = {[{key1}] = {...}, [{key2}] = {...}}
Instead of this less helpful output:
$1 = map_object = {[{...}] = {...}, [{...}] = {...}}
This is covered by the new tests in gdb.python/py-nested-maps.exp.
gdb/ChangeLog:
* cp-valprint.c (cp_print_value_fields): Allow an additional level
of depth when printing anonymous structs or unions.
* guile/scm-pretty-print.c (gdbscm_apply_val_pretty_printer):
Don't print either the top-level value, or the children if the
max-depth is exceeded.
(ppscm_print_children): When printing the key of a map, allow one
extra level of depth.
* python/py-prettyprint.c (gdbpy_apply_val_pretty_printer): Don't
print either the top-level value, or the children if the max-depth
is exceeded.
(print_children): When printing the key of a map, allow one extra
level of depth.
* python/py-value.c (valpy_format_string): Add max_depth keyword.
* valprint.c: (PRINT_MAX_DEPTH_DEFAULT): Define.
(user_print_options): Initialise max_depth field.
(val_print_scalar_or_string_type_p): New function.
(val_print): Check to see if the max depth has been reached.
(val_print_check_max_depth): Define new function.
(show_print_max_depth): New function.
(_initialize_valprint): Add 'print max-depth' option.
* valprint.h (struct value_print_options) <max_depth>: New field.
(val_print_check_max_depth): Declare new function.
* NEWS: Document new feature.
gdb/doc/ChangeLog:
* gdb.texinfo (Print Settings): Document 'print max-depth'.
* guile.texi (Guile Pretty Printing API): Document that 'print
max-depth' can effect the display of a values children.
* python.texi (Pretty Printing API): Likewise.
(Values From Inferior): Document max_depth keyword.
gdb/testsuite/ChangeLog:
* gdb.base/max-depth.c: New file.
* gdb.base/max-depth.exp: New file.
* gdb.python/py-nested-maps.c: New file.
* gdb.python/py-nested-maps.exp: New file.
* gdb.python/py-nested-maps.py: New file.
* gdb.python/py-format-string.exp (test_max_depth): New proc.
(test_all_common): Call test_max_depth.
* gdb.fortran/max-depth.exp: New file.
* gdb.fortran/max-depth.f90: New file.
* gdb.go/max-depth.exp: New file.
* gdb.go/max-depth.go: New file.
* gdb.modula2/max-depth.exp: New file.
* gdb.modula2/max-depth.c: New file.
* lib/gdb.exp (get_print_expr_at_depths): New proc.
Diffstat (limited to 'gdb/valprint.c')
-rw-r--r-- | gdb/valprint.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/gdb/valprint.c b/gdb/valprint.c index b02ebf6..b9d8878 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -88,6 +88,7 @@ static void val_print_type_code_flags (struct type *type, struct ui_file *stream); #define PRINT_MAX_DEFAULT 200 /* Start print_max off at this value. */ +#define PRINT_MAX_DEPTH_DEFAULT 20 /* Start print_max_depth off at this value. */ struct value_print_options user_print_options = { @@ -109,7 +110,8 @@ struct value_print_options user_print_options = 1, /* pascal_static_field_print */ 0, /* raw */ 0, /* summary */ - 1 /* symbol_print */ + 1, /* symbol_print */ + PRINT_MAX_DEPTH_DEFAULT /* max_depth */ }; /* Initialize *OPTS to be a copy of the user print options. */ @@ -281,6 +283,18 @@ val_print_scalar_type_p (struct type *type) } } +/* A helper function for val_print. When printing with limited depth we + want to print string and scalar arguments, but not aggregate arguments. + This function distinguishes between the two. */ + +static bool +val_print_scalar_or_string_type_p (struct type *type, + const struct language_defn *language) +{ + return (val_print_scalar_type_p (type) + || language->la_is_string_type_p (type)); +} + /* See its definition in value.h. */ int @@ -1054,6 +1068,11 @@ val_print (struct type *type, LONGEST embedded_offset, return; } + /* If this value is too deep then don't print it. */ + if (!val_print_scalar_or_string_type_p (type, language) + && val_print_check_max_depth (stream, recurse, options, language)) + return; + try { language->la_val_print (type, embedded_offset, address, @@ -1066,6 +1085,23 @@ val_print (struct type *type, LONGEST embedded_offset, } } +/* See valprint.h. */ + +bool +val_print_check_max_depth (struct ui_file *stream, int recurse, + const struct value_print_options *options, + const struct language_defn *language) +{ + if (options->max_depth > -1 && recurse >= options->max_depth) + { + gdb_assert (language->la_struct_too_deep_ellipsis != NULL); + fputs_filtered (language->la_struct_too_deep_ellipsis, stream); + return true; + } + + return false; +} + /* Check whether the value VAL is printable. Return 1 if it is; return 0 and print an appropriate error message to STREAM according to OPTIONS if it is not. */ @@ -2859,6 +2895,15 @@ val_print_string (struct type *elttype, const char *encoding, return (bytes_read / width); } + +/* Handle 'show print max-depth'. */ + +static void +show_print_max_depth (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Maximum print depth is %s.\n"), value); +} /* The 'set input-radix' command writes to this auxiliary variable. @@ -3152,4 +3197,14 @@ Use 'show input-radix' or 'show output-radix' to independently show each."), Set printing of array indexes."), _("\ Show printing of array indexes"), NULL, NULL, show_print_array_indexes, &setprintlist, &showprintlist); + + add_setshow_zuinteger_unlimited_cmd ("max-depth", class_support, + &user_print_options.max_depth, _("\ +Set maximum print depth for nested structures, unions and arrays."), _("\ +Show maximum print depth for nested structures, unions, and arrays."), _("\ +When structures, unions, or arrays are nested beyond this depth then they\n\ +will be replaced with either '{...}' or '(...)' depending on the language.\n\ +Use 'set print max-depth unlimited' to print the complete structure."), + NULL, show_print_max_depth, + &setprintlist, &showprintlist); } |