Commit Message
Hi.
This patch is based on the one posted here:
https://sourceware.org/ml/gdb-patches/2015-03/msg00312.html
I found a couple more issues and fixed them as well.
I plan to push this to the 7.9.1 branch as well as trunk.
2015-04-22 Martin Galvan <martin.galvan@tallertechnologies.com>
Doug Evans <dje@google.com>
PR python/18299
* python/lib/gdb/printing.py (register_pretty_printer): Handle
name or __name__ attributes. Handle gdb module as first argument.
testsuite/
* gdb.python/py-pp-maint.py: Move "replace" testing to ...
* gdb.python/py-pp-registration.exp: ... here. New file.
* gdb.python/py-pp-registration.c: New file.
* gdb.python/py-pp-registration.py: New file.
Comments
On Wed, Apr 22, 2015 at 12:34 PM, Doug Evans <dje@google.com> wrote:
> Hi.
>
> This patch is based on the one posted here:
>
> https://sourceware.org/ml/gdb-patches/2015-03/msg00312.html
>
> I found a couple more issues and fixed them as well.
>
> I plan to push this to the 7.9.1 branch as well as trunk.
>
> 2015-04-22 Martin Galvan <martin.galvan@tallertechnologies.com>
> Doug Evans <dje@google.com>
>
> PR python/18299
> * python/lib/gdb/printing.py (register_pretty_printer): Handle
> name or __name__ attributes. Handle gdb module as first argument.
>
> testsuite/
> * gdb.python/py-pp-maint.py: Move "replace" testing to ...
> * gdb.python/py-pp-registration.exp: ... here. New file.
> * gdb.python/py-pp-registration.c: New file.
> * gdb.python/py-pp-registration.py: New file.
Committed.
Thanks a lot!
On Wed, Apr 29, 2015 at 2:20 AM, Doug Evans <dje@google.com> wrote:
> On Wed, Apr 22, 2015 at 12:34 PM, Doug Evans <dje@google.com> wrote:
>> Hi.
>>
>> This patch is based on the one posted here:
>>
>> https://sourceware.org/ml/gdb-patches/2015-03/msg00312.html
>>
>> I found a couple more issues and fixed them as well.
>>
>> I plan to push this to the 7.9.1 branch as well as trunk.
>>
>> 2015-04-22 Martin Galvan <martin.galvan@tallertechnologies.com>
>> Doug Evans <dje@google.com>
>>
>> PR python/18299
>> * python/lib/gdb/printing.py (register_pretty_printer): Handle
>> name or __name__ attributes. Handle gdb module as first argument.
>>
>> testsuite/
>> * gdb.python/py-pp-maint.py: Move "replace" testing to ...
>> * gdb.python/py-pp-registration.exp: ... here. New file.
>> * gdb.python/py-pp-registration.c: New file.
>> * gdb.python/py-pp-registration.py: New file.
>
> Committed.
@@ -114,15 +114,21 @@ def register_pretty_printer(obj, printer, replace=False):
if not hasattr(printer, "__call__"):
raise TypeError("printer missing attribute: __call__")
- if obj is None:
+ if hasattr(printer, "name"):
+ name = printer.name
+ else:
+ name = printer.__name__
+ if obj is None or obj is gdb:
if gdb.parameter("verbose"):
gdb.write("Registering global %s pretty-printer ...\n" % name)
obj = gdb
else:
if gdb.parameter("verbose"):
- gdb.write("Registering %s pretty-printer for %s ...\n" %
- (printer.name, obj.filename))
+ gdb.write("Registering %s pretty-printer for %s ...\n" % (
+ name, obj.filename))
+ # Printers implemented as functions are old-style. In order to not risk
+ # breaking anything we do not check __name__ here.
if hasattr(printer, "name"):
if not isinstance(printer.name, basestring):
raise TypeError("printer name is not a string")
@@ -76,14 +76,3 @@ def build_pretty_printer():
gdb.printing.register_pretty_printer(gdb, lookup_function_lookup_test)
my_pretty_printer = build_pretty_printer()
gdb.printing.register_pretty_printer(gdb, my_pretty_printer)
-
-# Exercise the "replace" argument to register pretty_printer.
-saw_runtime_error = False
-try:
- gdb.printing.register_pretty_printer(gdb, my_pretty_printer, replace=False)
-except RuntimeError:
- saw_runtime_error = True
- pass
-if not saw_runtime_error:
- raise RuntimeError("Missing RuntimeError from register_pretty_printer")
-gdb.printing.register_pretty_printer(gdb, my_pretty_printer, replace=True)
new file mode 100644
@@ -0,0 +1,55 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2010-2015 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 <string.h>
+
+struct function_lookup_test
+{
+ int x,y;
+};
+
+void
+init_flt (struct function_lookup_test *p, int x, int y)
+{
+ p->x = x;
+ p->y = y;
+}
+
+struct s
+{
+ int a;
+ int *b;
+};
+
+void
+init_s (struct s *s, int a)
+{
+ s->a = a;
+ s->b = &s->a;
+}
+
+int
+main ()
+{
+ struct function_lookup_test flt;
+ struct s s;
+
+ init_flt (&flt, 42, 43);
+ init_s (&s, 1);
+
+ return 0; /* break to inspect */
+}
new file mode 100644
@@ -0,0 +1,116 @@
+# Copyright (C) 2010-2015 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 pretty
+# printer registration.
+
+load_lib gdb-python.exp
+
+standard_testfile
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile debug]} {
+ return -1
+}
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+set remote_python_file [gdb_remote_download host \
+ ${srcdir}/${subdir}/${testfile}.py]
+
+if ![runto_main ] {
+ fail "Can't run to main"
+ return -1
+}
+
+proc prepare_test { } {
+ global testfile remote_python_file
+
+ # Start with a fresh gdb.
+ clean_restart ${testfile}
+
+ set run_to_here [gdb_get_line_number {break to inspect} ${testfile}.c ]
+ if ![runto ${testfile}.c:$run_to_here message] {
+ return 0
+ }
+
+ gdb_test_no_output "python exec (open ('${remote_python_file}').read ())"
+
+ gdb_test_no_output "py progspace = gdb.current_progspace()"
+ gdb_test_no_output "py my_pretty_printer1 = build_pretty_printer1()"
+ gdb_test_no_output "py my_pretty_printer2 = build_pretty_printer2()"
+
+ return 1
+}
+
+proc test_printers { s_prefix } {
+ global hex
+
+ gdb_test "print flt" " = x=<42> y=<43>" \
+ "print flt"
+ gdb_test "print s" " = ${s_prefix} a=<1> b=<$hex>" \
+ "print s"
+}
+
+# Test registration with verbose off.
+
+with_test_prefix "verbose off" {
+ if ![prepare_test] {
+ return -1
+ }
+
+ gdb_test_no_output "set verbose off"
+
+ gdb_test_no_output "py gdb.printing.register_pretty_printer(gdb, lookup_function_lookup_test)"
+ gdb_test_no_output "py gdb.printing.register_pretty_printer(progspace, my_pretty_printer1)"
+
+ test_printers "s1"
+}
+
+# Test registration with verbose on.
+
+with_test_prefix "verbose on" {
+ if ![prepare_test] {
+ return -1
+ }
+
+ gdb_test_no_output "set verbose on"
+
+ gdb_test "py gdb.printing.register_pretty_printer(gdb, lookup_function_lookup_test)" \
+ "Registering global lookup_function_lookup_test pretty-printer ..."
+ gdb_test "py gdb.printing.register_pretty_printer(progspace, my_pretty_printer1)" \
+ "Registering pp-test pretty-printer for .*/py-pp-registration ..."
+
+ test_printers "s1"
+}
+
+# Exercise the "replace" argument to register_pretty_printer.
+
+with_test_prefix "replace" {
+ if ![prepare_test] {
+ return -1
+ }
+
+ gdb_test_no_output "py gdb.printing.register_pretty_printer(gdb, lookup_function_lookup_test)"
+ gdb_test_no_output "py gdb.printing.register_pretty_printer(progspace, my_pretty_printer1)"
+ gdb_test "py gdb.printing.register_pretty_printer(progspace, my_pretty_printer2, replace=False)" \
+ "RuntimeError: pretty-printer already registered: pp-test\r\nError while executing Python code."
+
+ test_printers "s1"
+
+ gdb_test_no_output "py gdb.printing.register_pretty_printer(progspace, my_pretty_printer2, replace=True)"
+
+ test_printers "s2"
+}
new file mode 100644
@@ -0,0 +1,80 @@
+# Copyright (C) 2010-2015 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 pretty
+# printer registration.
+
+import re
+import gdb.types
+import gdb.printing
+
+
+def lookup_function_lookup_test(val):
+ class PrintFunctionLookup(object):
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return ("x=<" + str(self.val["x"]) +
+ "> y=<" + str(self.val["y"]) + ">")
+
+ typename = gdb.types.get_basic_type(val.type).tag
+ # Note: typename could be None.
+ if typename == "function_lookup_test":
+ return PrintFunctionLookup(val)
+ return None
+
+
+class pp_s1 (object):
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ a = self.val["a"]
+ b = self.val["b"]
+ return "s1 a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
+
+
+class pp_s2 (object):
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ a = self.val["a"]
+ b = self.val["b"]
+ return "s2 a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
+
+
+def build_pretty_printer1():
+ pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-test")
+
+ pp.add_printer('struct s', '^struct s$', pp_s1)
+ pp.add_printer('s', '^s$', pp_s1)
+
+ return pp
+
+
+def build_pretty_printer2():
+ # This intentionally has the same name as build_pretty_printer1.
+ # It is used to test the "replace" functionality of
+ # register_pretty_printer.
+ pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-test")
+
+ pp.add_printer('struct s', '^struct s$', pp_s2)
+ pp.add_printer('s', '^s$', pp_s2)
+
+ return pp
+
+# Note: Registering the printers is done in the .exp file.