From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id uc3fDSaNz2oLJgkAWB0awg (envelope-from ) for ; Wed, 14 Oct 2026 10:09:42 -0400 Authentication-Results: simark.ca; dkim=fail reason="signature verification failed" (768-bit key; unprotected) header.d=tromey.com header.i=@tromey.com header.a=rsa-sha256 header.s=default header.b=BTVlmv4B; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 319F51E050; Wed, 14 Oct 2026 10:09:42 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_INVALID,DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_BL_SPAMCOP_NET, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=no autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 376651E04E for ; Wed, 14 Oct 2026 10:09:41 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C14C34BA23E7 for ; Wed, 14 Oct 2026 14:09:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C14C34BA23E7 Authentication-Results: sourceware.org; dkim=fail reason="signature verification failed" (768-bit key, unprotected) header.d=tromey.com header.i=@tromey.com header.a=rsa-sha256 header.s=default header.b=BTVlmv4B Received: from omta36.uswest2.a.cloudfilter.net (omta36.uswest2.a.cloudfilter.net [35.89.44.35]) by sourceware.org (Postfix) with ESMTPS id 1E4844BA2E15 for ; Wed, 14 Oct 2026 14:08:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1E4844BA2E15 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=tromey.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tromey.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 1E4844BA2E15 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=35.89.44.35 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1791986936; cv=none; b=uIAK/VgFOVac9F7u+3nQkv9L0Bg3CcDisvDHjqIlgmQY0DrgAxX1k3eWsG/WQJg4quTJz1q3TI1hfprhPAiDG/LtXFgBJJCgdmSUf6vfJBrt4W81TCuCxm8NLBdzUK2E3kgjsuK0GhpBlrBRZUduHCxqk1fmEnOkx8SFZpAlnnI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1791986936; c=relaxed/simple; bh=pqjwb861S/5v617oCjy6iTBXCZAyvA0Y6PoyCe76CsY=; h=DKIM-Signature:From:Date:Subject:MIME-Version:Message-Id:To; b=YbdtE8NRZsW5hfBoyaBTuUrIgkh5zGxN+cMBzxuF4DQzzzxIc2DG82qKOlKQZYSzDzN7g4DoZTHwi+w97i5Hlq013QzS3SqvyXX9no+yN1uqkyjJm1I2pkAHCUSwQ3V5SaWDZbOr6B/+s7kNGjStmhzNsnGTmVmu4O8rCp8b4GY= ARC-Authentication-Results: i=1; sourceware.org; dkim=policy (768-bit key, unprotected) header.d=tromey.com header.i=@tromey.com header.a=rsa-sha256 header.s=default header.b=BTVlmv4B reason="signing key too small" DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1E4844BA2E15 Received: from eig-obgw-5006b.ext.cloudfilter.net ([10.0.29.217]) by cmsmtp with ESMTPS id Gr5vxtvzEusRSGzf5xJIGN; Wed, 14 Oct 2026 14:08:55 +0000 Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with ESMTPS id Gzf2xiF4UQr2oGzf3xJILC; Wed, 14 Oct 2026 14:08:53 +0000 X-Authority-Analysis: v=2.4 cv=C67pyRP+ c=1 sm=1 tr=0 ts=6acf8cf6 a=ApxJNpeYhEAb1aAlGBBbmA==:117 a=ApxJNpeYhEAb1aAlGBBbmA==:17 a=IkcTkHD0fZMA:10 a=660iZSQnnn4A:10 a=ItBw4LHWJt0A:10 a=1cHX_YoxRjl-I0eMapoA:9 a=QEXdDO2ut3YA:10 a=O8hF6Hzn-FEA:10 a=DCx65vhANUyCzuf5D8fC:22 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Unsubscribe-Post:List-Subscribe:List-Post:List-Owner:List-Archive; bh=JUL6iTeNbvUYSHML0gm7MdFVzF4b2O8ncDLyw3HNDy8=; b=BTVlmv4BU4lNP7qnu1pQ/Q/+7u fqBFJxYll1/LVe2CW5VBSZxrTHiX6ojalbA24VkGe32R6YLyG8/8tc7adCMqMB0W7PL4lqrwctfZX +JbehyaYDbQzlIkRx51tGgOZq; Received: from 97-122-110-129.hlrn.qwest.net ([97.122.110.129]:45562 helo=[192.168.0.17]) by box5379.bluehost.com with esmtpsa (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.100.1) (envelope-from ) id 1xGzf2-000000002J7-2Twj; Wed, 14 Oct 2026 08:08:52 -0600 From: Tom Tromey Date: Wed, 14 Oct 2026 08:08:52 -0600 Subject: [PATCH 4/5] Rewrite breakpoint location getter methods MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20261014-python-safety-breakpoint-v1-4-c8e72d58f3cd@tromey.com> References: <20261014-python-safety-breakpoint-v1-0-c8e72d58f3cd@tromey.com> In-Reply-To: <20261014-python-safety-breakpoint-v1-0-c8e72d58f3cd@tromey.com> To: gdb-patches@sourceware.org Cc: Tom Tromey X-Mailer: b4 0.14.3 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - box5379.bluehost.com X-AntiAbuse: Original Domain - sourceware.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - tromey.com X-BWhitelist: no X-Source-IP: 97.122.110.129 X-Source-L: No X-Exim-ID: 1xGzf2-000000002J7-2Twj X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: 97-122-110-129.hlrn.qwest.net ([192.168.0.17]) [97.122.110.129]:45562 X-Source-Auth: tom+tromey.com X-Email-Count: 6 X-Org: HG=bhshared;ORG=bluehost; X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTM3OS5ibHVlaG9zdC5jb20= X-Local-Domain: yes X-CMAE-Envelope: MS4xfLD8DPA0/gti6SqPZeUvb+QxjFMdP9oITtKcx0LKQQJCU8hgKSLszDwP6Swy7+jXKGW5sca9fpz9hdhCDvxQBxB0LUV1rl9hYIJIWpo8lTvosN8fymIF OiM17NrvDydgM2rWuDw0ED0vhBG4Rskbm5ypBN0WFY61A6Vqnqyfkwhp87ARY1KlPEUEttEUPi7pU3W8VAYlceyF+/gs2ujcNAc= X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org This rewrites the breakpoint location getter methods to use the Python safety API. --- gdb/python/py-breakpoint.c | 231 +++++++++++++++++++++------------------------ 1 file changed, 110 insertions(+), 121 deletions(-) diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index 40d1244abcf..b39093ebd81 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -67,6 +67,52 @@ struct gdbpy_breakpoint_location_object : public PyObject /* An owning reference to the location's breakpoint owner. */ gdbpy_breakpoint_object *owner; + /* Python function to test whether or not the breakpoint location is + enabled. */ + bool get_enabled () const + { + require_valid (); + return bp_loc->enabled; + } + + /* Python function to get owner of breakpoint location, which is of + type gdb.Breakpoint. */ + gdbpy_ref<> get_owner () const + { + require_valid (); + return gdbpy_ref<>::new_reference (owner); + } + + /* Python function to get address of breakpoint location. */ + CORE_ADDR get_address () const + { + require_valid (); + return bp_loc->address; + } + + /* Python function to get the function name of where this location + was set. */ + const char *get_function () const + { + require_valid (); + return bp_loc->function_name.get (); + } + + /* Return the full filename of the location. */ + const char *get_fullname () const + { + require_valid (); + if (bp_loc->symtab == nullptr) + return nullptr; + return bp_loc->symtab->fullname (); + } + + /* Accessor to get the source location. */ + gdbpy_ref<> get_source_location () const; + + /* Accessor to get the thread groups. */ + gdbpy_ref<> get_thread_groups () const; + /* Implementation of 'repr'. */ gdbpy_ref<> repr (); @@ -82,15 +128,6 @@ struct gdbpy_breakpoint_location_object : public PyObject static_assert (gdb::is_python_allocatable_v); -/* Require that BREAKPOINT and LOCATION->OWNER are the same; throw a Python - exception if they are not. */ -#define BPLOCPY_REQUIRE_VALID(Breakpoint, Location) \ - do { \ - if ((Breakpoint)->bp != (Location)->bp_loc->owner) \ - return PyErr_Format (PyExc_RuntimeError, \ - _("Breakpoint location is invalid.")); \ - } while (0) - /* Require that BREAKPOINT and LOCATION->OWNER are the same; throw a Python exception if they are not. This macro is for use in setter functions. */ #define BPLOCPY_SET_REQUIRE_VALID(Breakpoint, Location) \ @@ -1604,45 +1641,6 @@ bplocpy_set_enabled (PyObject *py_self, PyObject *newvalue, void *closure) return 0; } -/* Python function to test whether or not the breakpoint location is enabled. */ - -static PyObject * -bplocpy_get_enabled (PyObject *py_self, void *closure) -{ - auto *self = (gdbpy_breakpoint_location_object *) py_self; - BPPY_REQUIRE_VALID (self->owner); - BPLOCPY_REQUIRE_VALID (self->owner, self); - - if (self->bp_loc->enabled) - return py_true ().release (); - else - return py_false ().release (); -} - -/* Python function to get address of breakpoint location. */ - -static PyObject * -bplocpy_get_address (PyObject *py_self, void *closure) -{ - auto *self = (gdbpy_breakpoint_location_object *) py_self; - BPPY_REQUIRE_VALID (self->owner); - BPLOCPY_REQUIRE_VALID (self->owner, self); - return gdb_py_object_from_ulongest (self->bp_loc->address).release (); -} - -/* Python function to get owner of breakpoint location, which - is of type gdb.Breakpoint. */ - -static PyObject * -bplocpy_get_owner (PyObject *py_self, void *closure) -{ - auto *self = (gdbpy_breakpoint_location_object *) py_self; - BPPY_REQUIRE_VALID (self->owner); - BPLOCPY_REQUIRE_VALID (self->owner, self); - Py_INCREF (self->owner); - return self->owner; -} - /* Attempt to get fully resolved file path for symtab. */ static gdbpy_ref<> @@ -1650,99 +1648,69 @@ bploc_filepath (struct symtab *bploc_symtab) { /* The exception is not ours to handle. We should always return some string value and filename is never null. */ + const char *filename = nullptr; try { - const char *full = symtab_to_fullname (bploc_symtab); - if (full) - return host_string_to_python_string (full); + filename = symtab_to_fullname (bploc_symtab); } catch (const gdb_exception &except) { } - return host_string_to_python_string (bploc_symtab->filename ()); + if (filename == nullptr) + filename = bploc_symtab->filename (); + gdb_assert (filename != nullptr); + + gdbpy_ref<> result = host_string_to_python_string (filename); + /* FIXME: Python safety: host_string_to_python_string should + throw. */ + if (result == nullptr) + throw gdb_python_exception (); + return result; } /* Python function to get the source file name path and line number where this breakpoint location was set. */ -static PyObject * -bplocpy_get_source_location (PyObject *py_self, void *closure) +gdbpy_ref<> +gdbpy_breakpoint_location_object::get_source_location () const { - auto *self = (gdbpy_breakpoint_location_object *) py_self; - BPPY_REQUIRE_VALID (self->owner); - BPLOCPY_REQUIRE_VALID (self->owner, self); - if (self->bp_loc->symtab) + require_valid (); + if (bp_loc->symtab != nullptr) { - gdbpy_ref<> tup (PyTuple_New (2)); - if (tup == nullptr) - return nullptr; - gdbpy_ref<> filename = bploc_filepath (self->bp_loc->symtab); - if (filename == nullptr) - return nullptr; - auto line = gdb_py_object_from_ulongest (self->bp_loc->line_number); + gdbpy_ref<> tup = gdbpy_tuple_new (2); + gdbpy_ref<> filename = bploc_filepath (bp_loc->symtab); + auto line = gdb_py_object_from_ulongest (bp_loc->line_number); + /* FIXME: Python safety: gdb_py_object_from_ulongest should + throw. */ if (line == nullptr) - return nullptr; - if (PyTuple_SetItem (tup.get (), 0, filename.release ()) == -1 - || PyTuple_SetItem (tup.get (), 1, line.release ()) == -1) - return nullptr; - return tup.release (); + throw gdb_python_exception (); + gdbpy_tuple_set_item (tup, 0, std::move (filename)); + gdbpy_tuple_set_item (tup, 1, std::move (line)); + return tup; } - else - return py_none ().release (); -} -/* Python function to get the function name of where this location was set. */ - -static PyObject * -bplocpy_get_function (PyObject *py_self, void *closure) -{ - auto *self = (gdbpy_breakpoint_location_object *) py_self; - BPPY_REQUIRE_VALID (self->owner); - BPLOCPY_REQUIRE_VALID (self->owner, self); - const auto fn_name = self->bp_loc->function_name.get (); - if (fn_name != nullptr) - return host_string_to_python_string (fn_name).release (); - return py_none ().release (); + return py_none (); } -static PyObject * -bplocpy_get_thread_groups (PyObject *py_self, void *closure) +gdbpy_ref<> +gdbpy_breakpoint_location_object::get_thread_groups () const { - auto *self = (gdbpy_breakpoint_location_object *) py_self; - BPPY_REQUIRE_VALID (self->owner); - BPLOCPY_REQUIRE_VALID (self->owner, self); - gdbpy_ref<> list (PyList_New (0)); - if (list == nullptr) - return nullptr; + require_valid (); + gdbpy_ref<> list = gdbpy_list_new (0); for (inferior *inf : all_inferiors ()) { - if (inf->pspace == self->bp_loc->pspace) + if (inf->pspace == bp_loc->pspace) { gdbpy_ref<> num = gdb_py_object_from_ulongest (inf->num); + /* FIXME: Python safety: gdb_py_object_from_ulongest should + throw. */ if (num == nullptr) - return nullptr; - if (PyList_Append (list.get (), num.get ()) != 0) - return nullptr; + throw gdb_python_exception (); + gdbpy_list_append (list, num); } } - return list.release (); -} - -static PyObject * -bplocpy_get_fullname (PyObject *py_self, void *closure) -{ - auto *self = (gdbpy_breakpoint_location_object *) py_self; - BPPY_REQUIRE_VALID (self->owner); - BPLOCPY_REQUIRE_VALID (self->owner, self); - const auto symtab = self->bp_loc->symtab; - if (symtab != nullptr && symtab->fullname () != nullptr) - { - gdbpy_ref<> fullname - = host_string_to_python_string (symtab->fullname ()); - return fullname.release (); - } - return py_none ().release (); + return list; } /* De-allocation function to be called for the Python object. */ @@ -1798,19 +1766,40 @@ gdbpy_breakpoint_location_object::repr () /* Attribute get/set Python definitions. */ static gdb_PyGetSetDef bp_location_object_getset[] = { - { "enabled", bplocpy_get_enabled, bplocpy_set_enabled, + { "enabled", + wrap_getter, + bplocpy_set_enabled, "Boolean telling whether the breakpoint is enabled.", NULL }, - { "owner", bplocpy_get_owner, NULL, + { "owner", + wrap_getter, + nullptr, "Get the breakpoint owner object", NULL }, - { "address", bplocpy_get_address, NULL, + { "address", + wrap_getter, + nullptr, "Get address of where this location was set", NULL}, - { "source", bplocpy_get_source_location, NULL, + { "source", + wrap_getter, + nullptr, "Get file and line number of where this location was set", NULL}, - { "function", bplocpy_get_function, NULL, + { "function", + wrap_getter, + nullptr, "Get function of where this location was set", NULL }, - { "fullname", bplocpy_get_fullname, NULL, + { "fullname", + wrap_getter, + nullptr, "Get fullname of where this location was set", NULL }, - { "thread_groups", bplocpy_get_thread_groups, NULL, + { "thread_groups", + wrap_getter, + nullptr, "Get thread groups where this location is in", NULL }, { NULL } /* Sentinel. */ }; -- 2.49.0