From patchwork Wed Apr 22 19:34:10 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Evans X-Patchwork-Id: 6389 Received: (qmail 27756 invoked by alias); 22 Apr 2015 19:34:16 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 27743 invoked by uid 89); 22 Apr 2015 19:34:15 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mail-oi0-f73.google.com Received: from mail-oi0-f73.google.com (HELO mail-oi0-f73.google.com) (209.85.218.73) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 22 Apr 2015 19:34:13 +0000 Received: by oiax69 with SMTP id x69so13503588oia.1 for ; Wed, 22 Apr 2015 12:34:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:cc:date:message-id:mime-version :content-type; bh=YkKpVhi/m+K7ZKqyJibrkjAFCM7TGMFN2gxyVvG0zeE=; b=cNeQQ2LF6vIawOX8KCACfKZOJCOIMF6ejRf4/vfV9e+Oa94i53GNHR9HJQGmfHXrqI 58mSVnzQcq6UfpnCTIE3YpU62QFxq2Rmhv21KeZ7nY+rNhraLFCoOE0vUih0dixuprpt OOYGhSG8pLA8VvsKlh6WtiPupjeeWJvRKtyhylGTDxsjwEmYE5w6ab3xIgkACs9tsDZj LWatZNR60YRiGBa94VT61+iNXqEX0b76dHFJ3kUa+RNnGo1TtMJ/720qeT1lXPzeelZk Zw/uJLVY6vqiDrFiRda/9Ih4CZCdyYJqd2DvDORvop5CHbAQQQ/1Tb8fw+C2zneavNwz L0gA== X-Gm-Message-State: ALoCoQkl2Gi8+M4ehJy7Rbm+v/UpD7BWfTPeXP43P3J5bNb9Kqsd4l909+95Jb3FXTNK0Zb0yF63 X-Received: by 10.50.128.40 with SMTP id nl8mr6499881igb.4.1429731251380; Wed, 22 Apr 2015 12:34:11 -0700 (PDT) Received: from corpmail-nozzle1-1.hot.corp.google.com ([100.108.1.104]) by gmr-mx.google.com with ESMTPS id i27si387297yha.6.2015.04.22.12.34.10 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 22 Apr 2015 12:34:11 -0700 (PDT) Received: from ruffy.mtv.corp.google.com ([172.17.128.44]) by corpmail-nozzle1-1.hot.corp.google.com with ESMTPS id 8ncN8vBm.1; Wed, 22 Apr 2015 12:34:11 -0700 From: Doug Evans To: gdb-patches@sourceware.org Subject: [PATCH] [PR python/18299] Fix. cc: martin.galvan@tallertechnologies.com Date: Wed, 22 Apr 2015 12:34:10 -0700 Message-ID: MIME-Version: 1.0 X-IsSubscribed: yes 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 Doug Evans 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. diff --git a/gdb/python/lib/gdb/printing.py b/gdb/python/lib/gdb/printing.py index e384e41..ff20f71 100644 --- a/gdb/python/lib/gdb/printing.py +++ b/gdb/python/lib/gdb/printing.py @@ -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") diff --git a/gdb/testsuite/gdb.python/py-pp-maint.py b/gdb/testsuite/gdb.python/py-pp-maint.py index 797f975..f4e5ecf 100644 --- a/gdb/testsuite/gdb.python/py-pp-maint.py +++ b/gdb/testsuite/gdb.python/py-pp-maint.py @@ -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) diff --git a/gdb/testsuite/gdb.python/py-pp-registration.c b/gdb/testsuite/gdb.python/py-pp-registration.c new file mode 100644 index 0000000..6891abf --- /dev/null +++ b/gdb/testsuite/gdb.python/py-pp-registration.c @@ -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 . */ + +#include + +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 */ +} diff --git a/gdb/testsuite/gdb.python/py-pp-registration.exp b/gdb/testsuite/gdb.python/py-pp-registration.exp new file mode 100644 index 0000000..2193407 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-pp-registration.exp @@ -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 . + +# 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" +} diff --git a/gdb/testsuite/gdb.python/py-pp-registration.py b/gdb/testsuite/gdb.python/py-pp-registration.py new file mode 100644 index 0000000..7cca270 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-pp-registration.py @@ -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 . + +# 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.