[PATCH v2][PR gdb/24052] Implement 'set print zero-values on|off'
Hannes Domani
ssbssa@yahoo.de
Sat May 30 16:12:53 GMT 2020
With this option it's possible to suppress any zero value members when
printing a structure or array.
Consider this example:
(gdb) p t1
$1 = {
i1 = 0,
i2 = 0,
i3 = 1,
d1 = 0,
d2 = 2.5,
d3 = 0,
p1 = 0x407980 <ix>,
p2 = 0x0,
p3 = 0x0,
t1 = {
v1 = 0,
v2 = 0
},
t2 = {
v1 = 3,
v2 = 0
},
t3 = {
v1 = 4,
v2 = 5
},
ia = {0, 1, 2, 0, 0, 3, 4, 5, 0, 6},
ea = {0, 0, 0},
ipa = {0x0, 0x407980 <ix>, 0x0, 0x0, 0x403020 <t1>}
}
With suppressed zero value members, the ouput is concise:
(gdb) set print zero-values off
(gdb) p t1
$2 = {
i3 = 1,
d2 = 2.5,
p1 = 0x407980 <ix>,
t2 = {
v1 = 3
},
t3 = {
v1 = 4,
v2 = 5
},
ia = {1, 2, 3, 4, 5, 6},
ipa = {0x407980 <ix>, 0x403020 <t1>}
}
gdb/ChangeLog:
2020-05-30 Hannes Domani <ssbssa@yahoo.de>
PR gdb/24052
* cp-valprint.c (cp_print_value_fields): Skip zero value members
if requested.
* python/py-value.c (valpy_format_string): Add zero_values keyword.
* valprint.c (struct value_print_options): Add zero_value_print.
(value_is_zero): New function.
(value_print_array_elements): Skip zero value members if requested.
(show_zero_value_print): New function.
* valprint.h (struct value_print_options): Add zero_value_print.
(value_is_zero): Declare.
gdb/doc/ChangeLog:
2020-05-30 Hannes Domani <ssbssa@yahoo.de>
PR gdb/24052
* gdb.texinfo: Document 'print zero-values'.
* python.texi: Document format_string keyword 'zero_values'.
gdb/testsuite/ChangeLog:
2020-05-30 Hannes Domani <ssbssa@yahoo.de>
PR gdb/24052
* gdb.base/options.exp: Add -zero-values in the print completion
list.
* gdb.base/zero-values.c: New test.
* gdb.base/zero-values.exp: New file.
* gdb.python/py-format-string.c (main): Add variables with
zero-value members.
* gdb.python/py-format-string.exp (test_zero_values): New proc.
(test_all_common): Call test_zero_values.
---
v2:
- Add python format_string keyword.
- Don't print zero value array elements.
---
gdb/cp-valprint.c | 12 +++++
gdb/doc/gdb.texinfo | 18 ++++++-
gdb/doc/python.texi | 5 ++
gdb/python/py-value.c | 7 ++-
gdb/testsuite/gdb.base/options.exp | 1 +
gdb/testsuite/gdb.base/zero-values.c | 40 ++++++++++++++
gdb/testsuite/gdb.base/zero-values.exp | 32 +++++++++++
gdb/testsuite/gdb.python/py-format-string.c | 3 ++
gdb/testsuite/gdb.python/py-format-string.exp | 17 ++++++
gdb/valprint.c | 54 ++++++++++++++++++-
gdb/valprint.h | 7 +++
11 files changed, 192 insertions(+), 4 deletions(-)
create mode 100644 gdb/testsuite/gdb.base/zero-values.c
create mode 100644 gdb/testsuite/gdb.base/zero-values.exp
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 0c79b025bd..6be63eea10 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -194,6 +194,18 @@ cp_print_value_fields (struct value *val, struct ui_file *stream,
&& field_is_static (&type->field (i)))
continue;
+ /* If requested, skip printing of zero value fields. */
+ if (!options->zero_value_print
+ && !field_is_static (&type->field (i)))
+ {
+ if (TYPE_FIELD_IGNORE (type, i))
+ continue;
+
+ struct value *v = value_primitive_field (val, 0, i, type);
+ if (value_is_zero (v))
+ continue;
+ }
+
if (fields_seen)
{
fputs_filtered (",", stream);
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 84755d374e..810fe52858 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -1978,7 +1978,7 @@ on @code{-} after the command name. For example:
(@value{GDBP}) print -@key{TAB}@key{TAB}
-address -max-depth -raw-values -union
-array -null-stop -repeats -vtbl
--array-indexes -object -static-members
+-array-indexes -object -static-members -zero-values
-elements -pretty -symbol
@end smallexample
@@ -9757,6 +9757,10 @@ Set printing of unions interior to structures. Related setting:
@item -vtbl [@code{on}|@code{off}]
Set printing of C++ virtual function tables. Related setting:
@ref{set print vtbl}.
+
+@item -zero-values [@code{on}|@code{off}]
+Set printing of zero value members. Related setting: @ref{set print
+zero-values}.
@end table
Because the @code{print} command accepts arbitrary expressions which
@@ -11546,6 +11550,18 @@ Do not pretty print C@t{++} virtual function tables.
@item show print vtbl
Show whether C@t{++} virtual function tables are pretty printed, or not.
+
+@anchor{set print zero-values}
+@item set print zero-values
+@itemx set print zero-values on
+@cindex zero value members
+Print zero value members of structures and arrays. The default is on.
+
+@item set print zero-values off
+Do not print zero value members of structures and arrays.
+
+@item show print zero-values
+Show whether zero value members are printed or not.
@end table
@node Pretty Printing
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index a38f1dab42..e86fb7eab9 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -905,6 +905,11 @@ corresponding symbol name (if one exists), @code{False} if it shouldn't
should be expanded, @code{False} if they shouldn't (see @code{set print
union} in @ref{Print Settings}).
+@item zero_values
+@code{True} if zero value members should be included in the string
+representation of structures and arrays, @code{False} if they shouldn't
+(see @code{set print zero-values} in @ref{Print Settings}).
+
@item deref_refs
@code{True} if C@t{++} references should be resolved to the value they
refer to, @code{False} (the default) if they shouldn't. Note that, unlike
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 2ebbe0a356..c45705c377 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -617,6 +617,7 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
"array_indexes", /* See set print array-indexes on|off. */
"symbols", /* See set print symbol on|off. */
"unions", /* See set print union on|off. */
+ "zero_values", /* See set print zero-values on|off. */
/* C++ options. */
"deref_refs", /* No corresponding setting. */
"actual_objects", /* See set print object on|off. */
@@ -660,13 +661,14 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
PyObject *array_indexes_obj = NULL;
PyObject *symbols_obj = NULL;
PyObject *unions_obj = NULL;
+ PyObject *zero_values_obj = NULL;
PyObject *deref_refs_obj = NULL;
PyObject *actual_objects_obj = NULL;
PyObject *static_members_obj = NULL;
char *format = NULL;
if (!gdb_PyArg_ParseTupleAndKeywords (args,
kw,
- "|O!O!O!O!O!O!O!O!O!IIIs",
+ "|O!O!O!O!O!O!O!O!O!O!IIIs",
keywords,
&PyBool_Type, &raw_obj,
&PyBool_Type, &pretty_arrays_obj,
@@ -674,6 +676,7 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
&PyBool_Type, &array_indexes_obj,
&PyBool_Type, &symbols_obj,
&PyBool_Type, &unions_obj,
+ &PyBool_Type, &zero_values_obj,
&PyBool_Type, &deref_refs_obj,
&PyBool_Type, &actual_objects_obj,
&PyBool_Type, &static_members_obj,
@@ -696,6 +699,8 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
return NULL;
if (!copy_py_bool_obj (&opts.unionprint, unions_obj))
return NULL;
+ if (!copy_py_bool_obj (&opts.zero_value_print, zero_values_obj))
+ return NULL;
if (!copy_py_bool_obj (&opts.deref_ref, deref_refs_obj))
return NULL;
if (!copy_py_bool_obj (&opts.objectprint, actual_objects_obj))
diff --git a/gdb/testsuite/gdb.base/options.exp b/gdb/testsuite/gdb.base/options.exp
index 37a7e1ec8a..1c8bb923e6 100644
--- a/gdb/testsuite/gdb.base/options.exp
+++ b/gdb/testsuite/gdb.base/options.exp
@@ -174,6 +174,7 @@ proc_with_prefix test-print {{prefix ""}} {
"-symbol"
"-union"
"-vtbl"
+ "-zero-values"
}
global binfile
diff --git a/gdb/testsuite/gdb.base/zero-values.c b/gdb/testsuite/gdb.base/zero-values.c
new file mode 100644
index 0000000000..0a281d9671
--- /dev/null
+++ b/gdb/testsuite/gdb.base/zero-values.c
@@ -0,0 +1,40 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2020 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 ix;
+struct two
+{
+ int v1, v2;
+};
+struct t
+{
+ int i1, i2, i3;
+ double d1, d2, d3;
+ int *p1, *p2, *p3;
+ struct two t1, t2, t3;
+ int ia[10];
+ int ea[3];
+ int *ipa[5];
+} t1 = {0, 0, 1, 0, 2.5, 0, &ix, 0, 0, {0, 0}, {3, 0}, {4, 5},
+ {0, 1, 2, 0, 0, 3, 4, 5, 0, 6}, {0, 0, 0},
+ {0, &ix, 0, 0, &t1.i1}};
+
+int
+main ()
+{
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/zero-values.exp b/gdb/testsuite/gdb.base/zero-values.exp
new file mode 100644
index 0000000000..a8f377b8f7
--- /dev/null
+++ b/gdb/testsuite/gdb.base/zero-values.exp
@@ -0,0 +1,32 @@
+# Copyright 2020 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 disabled printing of zero-values in structures and arrays.
+
+standard_testfile
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile debug]} {
+ untested $testfile.exp
+ return -1
+}
+
+if ![runto_main] {
+ untested $testfile.exp
+ return -1
+}
+
+gdb_test "print t1" " = \\{i1 = 0, i2 = 0, i3 = 1, d1 = 0, d2 = 2\\.5, d3 = 0, p1 = $hex <ix>, p2 = 0x0, p3 = 0x0, t1 = \\{v1 = 0, v2 = 0\\}, t2 = \\{v1 = 3, v2 = 0\\}, t3 = \\{v1 = 4, v2 = 5\\}, ia = \\{0, 1, 2, 0, 0, 3, 4, 5, 0, 6\\}, ea = \\{0, 0, 0\\}, ipa = \\{0x0, $hex <ix>, 0x0, 0x0, $hex <t1>\\}\\}"
+
+gdb_test "print -zero-values off -- t1" " = \\{i3 = 1, d2 = 2\\.5, p1 = $hex <ix>, t2 = \\{v1 = 3\\}, t3 = \\{v1 = 4, v2 = 5\\}, ia = \\{1, 2, 3, 4, 5, 6\\}, ipa = \\{$hex <ix>, $hex <t1>\\}\\}"
diff --git a/gdb/testsuite/gdb.python/py-format-string.c b/gdb/testsuite/gdb.python/py-format-string.c
index a771370fde..ee1c4ae684 100644
--- a/gdb/testsuite/gdb.python/py-format-string.c
+++ b/gdb/testsuite/gdb.python/py-format-string.c
@@ -113,6 +113,9 @@ main ()
int *a_symbol_pointer = &global_symbol;
+ point_t zero_one_point = { 0, 1 };
+ int an_array_with_zeroes[] = { 1, 2, 0, 3, 4, 0, 5, 0 };
+
#ifdef __cplusplus
Deriv a_deriv (123);
Base &a_base_ref = a_deriv;
diff --git a/gdb/testsuite/gdb.python/py-format-string.exp b/gdb/testsuite/gdb.python/py-format-string.exp
index f809ef30cb..5b78799062 100644
--- a/gdb/testsuite/gdb.python/py-format-string.exp
+++ b/gdb/testsuite/gdb.python/py-format-string.exp
@@ -874,6 +874,22 @@ proc test_format {} {
}
}
+proc test_zero_values {} {
+ check_format_string "zero_one_point" \
+ "raw=True" \
+ "\\{x = 0, y = 1\\}"
+ check_format_string "zero_one_point" \
+ "raw=True, zero_values=False" \
+ "\\{y = 1\\}"
+
+ check_format_string "an_array_with_zeroes" \
+ "raw=True" \
+ "\\{1, 2, 0, 3, 4, 0, 5, 0\\}"
+ check_format_string "an_array_with_zeroes" \
+ "raw=True, zero_values=False" \
+ "\\{1, 2, 3, 4, 5\\}"
+}
+
# Test mixing options.
proc test_mixed {} {
global current_lang
@@ -948,6 +964,7 @@ proc test_all_common {} {
test_max_depth
test_repeat_threshold
test_format
+ test_zero_values
# Multiple options mixed together.
test_mixed
# Various error conditions.
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 2cb7779161..fccdaccb4a 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -117,7 +117,8 @@ struct value_print_options user_print_options =
0, /* summary */
1, /* symbol_print */
PRINT_MAX_DEPTH_DEFAULT, /* max_depth */
- 1 /* finish_print */
+ 1, /* finish_print */
+ 1, /* zero_value_print */
};
/* Initialize *OPTS to be a copy of the user print options. */
@@ -1859,6 +1860,23 @@ maybe_print_array_index (struct type *index_type, LONGEST index,
/* See valprint.h. */
+bool
+value_is_zero (struct value *v)
+{
+ struct type *type = check_typedef (value_type (v));
+ const gdb_byte *addr = value_contents_for_printing (v);
+ unsigned int len = TYPE_LENGTH (type);
+ unsigned int zeros;
+ for (zeros = 0; zeros < len; zeros++)
+ {
+ if (addr[zeros] != 0)
+ return false;
+ }
+ return true;
+}
+
+/* See valprint.h. */
+
void
value_print_array_elements (struct value *val, struct ui_file *stream,
int recurse,
@@ -1905,11 +1923,21 @@ value_print_array_elements (struct value *val, struct ui_file *stream,
annotate_array_section_begin (i, elttype);
+ bool need_comma = i != 0;
for (; i < len && things_printed < options->print_max; i++)
{
scoped_value_mark free_values;
- if (i != 0)
+ /* If requested, skip printing of zero value fields. */
+ if (!options->zero_value_print)
+ {
+ struct value *v = value_from_component (val, elttype,
+ eltlen * i);
+ if (value_is_zero (v))
+ continue;
+ }
+
+ if (need_comma)
{
if (options->prettyformat_arrays)
{
@@ -1963,6 +1991,8 @@ value_print_array_elements (struct value *val, struct ui_file *stream,
annotate_elt ();
things_printed++;
}
+
+ need_comma = true;
}
annotate_array_section_end ();
if (i < len)
@@ -2967,6 +2997,17 @@ show_static_field_print (struct ui_file *file, int from_tty,
value);
}
+/* Controls printing of zero value members. */
+static void
+show_zero_value_print (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ fprintf_filtered (file,
+ _("Printing of zero value members is %s.\n"),
+ value);
+}
+
/* A couple typedefs to make writing the options a bit more
@@ -3110,6 +3151,15 @@ pretty-printers for that value.")
N_("Show printing of C++ virtual function tables."),
NULL, /* help_doc */
},
+
+ boolean_option_def {
+ "zero-values",
+ [] (value_print_options *opt) { return &opt->zero_value_print; },
+ show_zero_value_print, /* show_cmd_cb */
+ N_("Set printing of zero value members."),
+ N_("Show printing of zero value members."),
+ NULL, /* help_doc */
+ },
};
/* See valprint.h. */
diff --git a/gdb/valprint.h b/gdb/valprint.h
index 57bc0339fc..81b11452a4 100644
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -100,6 +100,9 @@ struct value_print_options
/* Whether "finish" should print the value. */
bool finish_print;
+
+ /* If true, print fields with a zero value. */
+ bool zero_value_print;
};
/* Create an option_def_group for the value_print options, with OPTS
@@ -129,6 +132,10 @@ extern void maybe_print_array_index (struct type *index_type, LONGEST index,
const struct value_print_options *);
+/* Check if V only contains zero bytes. */
+
+extern bool value_is_zero (struct value *v);
+
/* Print elements of an array. */
extern void value_print_array_elements (struct value *, struct ui_file *, int,
--
2.26.2
More information about the Gdb-patches
mailing list