Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
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


      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