Use pretty printers for struct member stubs
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
success
|
Testing passed
|
Commit Message
PR29079 shows that pretty printers can be used for an incomplete
type (stub), but only when printing it directly, not if it's
part of another struct:
```
(gdb) p s
$1 = {pp m_i = 5}
(gdb) p s2
$2 = {m_s = <incomplete type>, m_l = 20}
```
The reason is simply that in common_val_print the check for stubs
is before any pretty printer is tried.
It works if the pretty printer is tried before the stub check:
```
(gdb) p s
$1 = {pp m_i = 5}
(gdb) p s2
$2 = {m_s = {pp m_i = 10}, m_l = 20}
```
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29079
---
.../gdb.python/py-prettyprint-stub-2.cc | 26 ++++++++
.../gdb.python/py-prettyprint-stub.cc | 36 +++++++++++
.../gdb.python/py-prettyprint-stub.exp | 59 +++++++++++++++++++
.../gdb.python/py-prettyprint-stub.h | 24 ++++++++
.../gdb.python/py-prettyprint-stub.py | 38 ++++++++++++
gdb/valprint.c | 20 +++----
6 files changed, 193 insertions(+), 10 deletions(-)
create mode 100644 gdb/testsuite/gdb.python/py-prettyprint-stub-2.cc
create mode 100644 gdb/testsuite/gdb.python/py-prettyprint-stub.cc
create mode 100644 gdb/testsuite/gdb.python/py-prettyprint-stub.exp
create mode 100644 gdb/testsuite/gdb.python/py-prettyprint-stub.h
create mode 100644 gdb/testsuite/gdb.python/py-prettyprint-stub.py
Comments
>>>>> "Hannes" == Hannes Domani <ssbssa@yahoo.de> writes:
Hannes> PR29079 shows that pretty printers can be used for an incomplete
Hannes> type (stub), but only when printing it directly, not if it's
Hannes> part of another struct:
[...]
Thank you for the patch and the explanation -- I had seen that bug but
didn't realize that this already worked for the top-level.
This is ok.
Approved-By: Tom Tromey <tom@tromey.com>
Tom
Am Freitag, 8. Dezember 2023, 17:19:36 MEZ hat Tom Tromey <tom@tromey.com> Folgendes geschrieben:
> >>>>> "Hannes" == Hannes Domani <ssbssa@yahoo.de> writes:
>
> Hannes> PR29079 shows that pretty printers can be used for an incomplete
> Hannes> type (stub), but only when printing it directly, not if it's
> Hannes> part of another struct:
> [...]
>
> Thank you for the patch and the explanation -- I had seen that bug but
> didn't realize that this already worked for the top-level.
>
> This is ok.
>
> Approved-By: Tom Tromey <tom@tromey.com>
Pushed, thanks.
new file mode 100644
@@ -0,0 +1,26 @@
+/* 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/>. */
+
+#include "py-prettyprint-stub.h"
+
+S::S (int i) : m_i (i)
+{
+}
+
+S::~S ()
+{
+}
new file mode 100644
@@ -0,0 +1,36 @@
+/* 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/>. */
+
+#include "py-prettyprint-stub.h"
+
+struct S2
+{
+ S2 (int i, long l) : m_s (i), m_l (l)
+ {
+ }
+
+ S m_s;
+ long m_l;
+};
+
+int main ()
+{
+ S s (5);
+ S2 s2 (10, 20);
+
+ return 0; /* Break here. */
+}
new file mode 100644
@@ -0,0 +1,59 @@
+# 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests Python-based pretty-printing of stubs.
+
+load_lib gdb-python.exp
+
+require allow_python_tests
+
+standard_testfile .cc py-prettyprint-stub-2.cc
+
+set srcfiles [list $srcfile $srcfile2]
+
+if { [build_executable_from_specs \
+ "failed to prepare" \
+ $testfile {c++} \
+ $srcfile {c++ debug} \
+ $srcfile2 {c++}] == -1 } {
+ return -1
+}
+
+# Start with a fresh gdb.
+clean_restart $testfile
+
+if {![runto_main]} {
+ return
+}
+
+set remote_python_file [gdb_remote_download host \
+ ${srcdir}/${subdir}/${testfile}.py]
+
+gdb_breakpoint [gdb_get_line_number "Break here."]
+gdb_continue_to_breakpoint "Break here" ".*Break here.*"
+
+# First test without pretty printer.
+gdb_test "print s" " = <incomplete type>"
+gdb_test "print s2" " = {m_s = <incomplete type>, m_l = 20}"
+
+# Load pretty printer.
+gdb_test_no_output "source ${remote_python_file}" "load python file"
+
+# Test with pretty printer.
+with_test_prefix pp {
+ gdb_test "print s" " = {pp m_i = 5}"
+ gdb_test "print s2" " = {m_s = {pp m_i = 10}, m_l = 20}"
+}
new file mode 100644
@@ -0,0 +1,24 @@
+/* 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/>. */
+
+struct S
+{
+ S (int);
+ virtual ~S ();
+
+ int m_i;
+};
new file mode 100644
@@ -0,0 +1,38 @@
+# 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests Python-based pretty-printing of stubs.
+
+
+class SPrinter:
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ char_ptr = gdb.lookup_type("char").pointer()
+ int_ptr = gdb.lookup_type("int").pointer()
+ # m_i should be after the vtable, which has the size of a pointer
+ i = (
+ (self.val.address.cast(char_ptr) + int_ptr.sizeof)
+ .cast(int_ptr)
+ .dereference()
+ )
+ return "{pp m_i = %d}" % int(i)
+
+
+pp = gdb.printing.RegexpCollectionPrettyPrinter("S")
+pp.add_printer("S", "^S$", SPrinter)
+gdb.printing.register_pretty_printer(gdb.current_objfile(), pp, True)
@@ -1054,16 +1054,6 @@ common_val_print (struct value *value, struct ui_file *stream, int recurse,
QUIT;
- /* Ensure that the type is complete and not just a stub. If the type is
- only a stub and we can't find and substitute its complete type, then
- print appropriate string and return. */
-
- if (real_type->is_stub ())
- {
- fprintf_styled (stream, metadata_style.style (), _("<incomplete type>"));
- return;
- }
-
if (!valprint_check_validity (stream, real_type, 0, value))
return;
@@ -1074,6 +1064,16 @@ common_val_print (struct value *value, struct ui_file *stream, int recurse,
return;
}
+ /* Ensure that the type is complete and not just a stub. If the type is
+ only a stub and we can't find and substitute its complete type, then
+ print appropriate string and return. */
+
+ if (real_type->is_stub ())
+ {
+ fprintf_styled (stream, metadata_style.style (), _("<incomplete type>"));
+ return;
+ }
+
/* Handle summary mode. If the value is a scalar, print it;
otherwise, print an ellipsis. */
if (options->summary && !val_print_scalar_type_p (type))