From patchwork Tue Jun 21 10:40:21 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre-Marie de Rodat X-Patchwork-Id: 13272 Received: (qmail 88143 invoked by alias); 21 Jun 2016 10:40:51 -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 88029 invoked by uid 89); 21 Jun 2016 10:40:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=bp2, advance!, Hx-languages-length:5668 X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 21 Jun 2016 10:40:34 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 4D7F481334; Tue, 21 Jun 2016 12:40:31 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2fTpNIXnAqgO; Tue, 21 Jun 2016 12:40:31 +0200 (CEST) Received: from cacatoes.act-europe.fr (cacatoes.act-europe.fr [10.10.1.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 3DCC481331; Tue, 21 Jun 2016 12:40:31 +0200 (CEST) From: Pierre-Marie de Rodat To: gdb-patches@sourceware.org Cc: Pierre-Marie de Rodat Subject: [PATCH] Fix use of a dangling pointer for Python breakpoint objects Date: Tue, 21 Jun 2016 12:40:21 +0200 Message-Id: <20160621104021.15093-1-derodat@adacore.com> X-IsSubscribed: yes Hello, When a Python script tries to create a breakpoint but fails to do so, gdb.Breakpoint.__init__ raises an exception and the breakpoint does not exist anymore in the Python interpreter. However, GDB still keeps a reference to the Python object to be used for a later hook, which is wrong. This commit adds the necessary cleanup code so that there is no stale reference to this Python object. It also adds a new testcase to reproduce the bug and check the fix. There is no regression on my x86_64-linux machine: ok to push? Thank you in advance! 2016-06-21 Pierre-Marie de Rodat gdb/ * python/py-breakpoint.c (bppy_init): Clear bppy_pending_object when there is an error during the breakpoint creation. gdb/testsuite * gdb.python/py-breakpoint2.c, gdb.python/py-breakpoint2.exp, gdb.python/py-breakpoint2.py: New testcase. --- gdb/python/py-breakpoint.c | 1 + gdb/testsuite/gdb.python/py-breakpoint2.c | 22 +++++++++++++++++++ gdb/testsuite/gdb.python/py-breakpoint2.exp | 34 +++++++++++++++++++++++++++++ gdb/testsuite/gdb.python/py-breakpoint2.py | 31 ++++++++++++++++++++++++++ 4 files changed, 88 insertions(+) create mode 100644 gdb/testsuite/gdb.python/py-breakpoint2.c create mode 100644 gdb/testsuite/gdb.python/py-breakpoint2.exp create mode 100644 gdb/testsuite/gdb.python/py-breakpoint2.py diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index ed9cae6..5918bcc 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -705,6 +705,7 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) } CATCH (except, RETURN_MASK_ALL) { + bppy_pending_object = NULL; PyErr_Format (except.reason == RETURN_QUIT ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, "%s", except.message); diff --git a/gdb/testsuite/gdb.python/py-breakpoint2.c b/gdb/testsuite/gdb.python/py-breakpoint2.c new file mode 100644 index 0000000..0a535a4 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-breakpoint2.c @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2016 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 . */ + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.python/py-breakpoint2.exp b/gdb/testsuite/gdb.python/py-breakpoint2.exp new file mode 100644 index 0000000..0a3a7ca --- /dev/null +++ b/gdb/testsuite/gdb.python/py-breakpoint2.exp @@ -0,0 +1,34 @@ +# Copyright (C) 2016 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 the mechanism +# exposing breakpoints to Python. + +load_lib gdb-python.exp + +standard_testfile + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { + return -1 +} + +# Skip all tests if Python scripting is not enabled. +if { [skip_python_tests] } { continue } + +gdb_test "source py-breakpoint2.py" + +# The following used to trigger an internal error because of a dangling +# reference to a Python breakpoint object. +gdb_test "start" diff --git a/gdb/testsuite/gdb.python/py-breakpoint2.py b/gdb/testsuite/gdb.python/py-breakpoint2.py new file mode 100644 index 0000000..9e0a379 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-breakpoint2.py @@ -0,0 +1,31 @@ +# Copyright (C) 2016 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 the mechanism +# exposing breakpoints to Python. + +import gdb + +bp1 = gdb.Breakpoint('main', gdb.BP_BREAKPOINT) + +# The following will create a breakpoint whose construction will abort (there +# is no such symbol), so GDB should not keep a reference to the corresponding +# Python object. +try: + bp2 = gdb.Breakpoint('does_not_exist', gdb.BP_WATCHPOINT) +except RuntimeError: + pass +else: + assert False