From: Tom Tromey <tom@tromey.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tom@tromey.com>
Subject: [PATCH 5/5] Rewrite gdb.BreakpointLocation setter
Date: Wed, 14 Oct 2026 08:08:53 -0600 [thread overview]
Message-ID: <20261014-python-safety-breakpoint-v1-5-c8e72d58f3cd@tromey.com> (raw)
In-Reply-To: <20261014-python-safety-breakpoint-v1-0-c8e72d58f3cd@tromey.com>
This rewrites the one gdb.BreakpointLocation setter function to use
the Python safety API.
---
gdb/python/py-breakpoint.c | 56 +++++++++++++---------------------------------
gdb/python/py-ref.h | 7 ++++++
gdb/python/py-wrappers.h | 10 +++++++++
3 files changed, 32 insertions(+), 41 deletions(-)
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index b39093ebd81..f6d3ffc01f5 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -75,6 +75,10 @@ struct gdbpy_breakpoint_location_object : public PyObject
return bp_loc->enabled;
}
+ /* Python function to set the enabled state of a breakpoint
+ location. */
+ void set_enabled (gdbpy_opt_borrowed_ref<> newvalue);
+
/* Python function to get owner of breakpoint location, which is of
type gdb.Breakpoint. */
gdbpy_ref<> get_owner () const
@@ -128,18 +132,6 @@ struct gdbpy_breakpoint_location_object : public PyObject
static_assert (gdb::is_python_allocatable_v<gdbpy_breakpoint_location_object>);
-/* 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) \
- do { \
- if ((Breakpoint)->bp != (Location)->bp_loc->owner) \
- { \
- PyErr_Format (PyExc_RuntimeError, \
- _("Breakpoint location is invalid.")); \
- return -1; \
- } \
- } while (0)
-
/* Debugging of Python breakpoints. */
static bool pybp_debug;
@@ -1606,39 +1598,20 @@ GDBPY_INITIALIZE_FILE (gdbpy_initialize_breakpoint_locations);
/* Python function to set the enabled state of a breakpoint location. */
-static int
-bplocpy_set_enabled (PyObject *py_self, PyObject *newvalue, void *closure)
+void
+gdbpy_breakpoint_location_object::set_enabled
+ (gdbpy_opt_borrowed_ref<> newvalue)
{
- auto *self = (gdbpy_breakpoint_location_object *) py_self;
- BPPY_SET_REQUIRE_VALID (self->owner);
- BPLOCPY_SET_REQUIRE_VALID (self->owner, self);
+ require_valid ();
if (newvalue == nullptr)
- {
- PyErr_SetString (PyExc_TypeError,
- _("Cannot delete 'enabled' attribute."));
- return -1;
- }
+ gdbpy_err_set_string (PyExc_TypeError,
+ _("Cannot delete 'enabled' attribute."));
else if (!PyBool_Check (newvalue))
- {
- PyErr_SetString (PyExc_TypeError,
- _("The value of 'enabled' must be a boolean."));
- return -1;
- }
+ gdbpy_err_set_string (PyExc_TypeError,
+ _("The value of 'enabled' must be a boolean."));
- int cmp = PyObject_IsTrue (newvalue);
- if (cmp < 0)
- return -1;
-
- try
- {
- enable_disable_bp_location (self->bp_loc, cmp == 1);
- }
- catch (const gdb_exception &except)
- {
- return gdbpy_handle_gdb_exception (-1, except);
- }
- return 0;
+ enable_disable_bp_location (bp_loc, gdbpy_object_is_true (newvalue));
}
/* Attempt to get fully resolved file path for symtab. */
@@ -1769,7 +1742,8 @@ static gdb_PyGetSetDef bp_location_object_getset[] = {
{ "enabled",
wrap_getter<gdbpy_breakpoint_location_object,
&gdbpy_breakpoint_location_object::get_enabled>,
- bplocpy_set_enabled,
+ wrap_setter<gdbpy_breakpoint_location_object,
+ &gdbpy_breakpoint_location_object::set_enabled>,
"Boolean telling whether the breakpoint is enabled.", NULL },
{ "owner",
wrap_getter<gdbpy_breakpoint_location_object,
diff --git a/gdb/python/py-ref.h b/gdb/python/py-ref.h
index 3d0373b7001..3e8838b3849 100644
--- a/gdb/python/py-ref.h
+++ b/gdb/python/py-ref.h
@@ -108,6 +108,13 @@ class gdbpy_borrowed_ref : public gdbpy_opt_borrowed_ref<T>
gdb_assert (this->m_obj != nullptr);
}
+ template<typename U>
+ gdbpy_borrowed_ref (const gdbpy_opt_borrowed_ref<U> &ref)
+ : gdbpy_opt_borrowed_ref<T> (ref)
+ {
+ gdb_assert (this->m_obj != nullptr);
+ }
+
gdbpy_borrowed_ref (std::nullptr_t) = delete;
/* Allow a (checked) conversion to any subclass of T. */
diff --git a/gdb/python/py-wrappers.h b/gdb/python/py-wrappers.h
index 5b1353872cc..fdb11d2a1fa 100644
--- a/gdb/python/py-wrappers.h
+++ b/gdb/python/py-wrappers.h
@@ -358,4 +358,14 @@ gdbpy_sequence_concat (gdbpy_borrowed_ref<> first, gdbpy_borrowed_ref<> second)
return result;
}
+/* Wrapper for PyObject_IsTrue. */
+static inline bool
+gdbpy_object_is_true (gdbpy_borrowed_ref<> val)
+{
+ int cmp = PyObject_IsTrue (val);
+ if (cmp < 0)
+ throw gdb_python_exception ();
+ return cmp;
+}
+
#endif /* GDB_PYTHON_PY_WRAPPERS_H */
--
2.49.0
prev parent reply other threads:[~2026-10-14 14:10 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-14 14:08 [PATCH 0/5] Use Python safety API for breakpoint locations Tom Tromey
2026-10-14 14:08 ` [PATCH 1/5] Rewrite gdb.BreakpointLocation repr method Tom Tromey
2026-10-14 14:08 ` [PATCH 2/5] Move two macros from python-internal.h to py-breakpoint.c Tom Tromey
2026-10-14 14:08 ` [PATCH 3/5] Add require_valid to Python breakpoint and breakpoint location Tom Tromey
2026-10-14 14:08 ` [PATCH 4/5] Rewrite breakpoint location getter methods Tom Tromey
2026-10-14 14:08 ` Tom Tromey [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261014-python-safety-breakpoint-v1-5-c8e72d58f3cd@tromey.com \
--to=tom@tromey.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox