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] Convert py-arch.c to "safety" approach
Date: Sat,  8 Aug 2026 12:23:39 -0600	[thread overview]
Message-ID: <20260808182339.3936136-1-tom@tromey.com> (raw)

This patch converts py-arch.c to the new Python safety approach.  A
few changes outside this file were also needed: some updates to
py-register.c (changing some functions that are only called from
py-arch.c), the new noargs_function template, and the use of a wrapper
in python.c.

Regression tested on x86-64 Fedora 40.
---
 gdb/python/py-arch.c         | 306 +++++++++++++++--------------------
 gdb/python/py-registers.c    |  39 ++---
 gdb/python/py-safety.h       |  26 +++
 gdb/python/py-wrappers.h     |  11 ++
 gdb/python/python-internal.h |   8 +-
 gdb/python/python.c          |   4 +-
 6 files changed, 189 insertions(+), 205 deletions(-)

diff --git a/gdb/python/py-arch.c b/gdb/python/py-arch.c
index 5b3cfbdc876..51dfcb97b36 100644
--- a/gdb/python/py-arch.c
+++ b/gdb/python/py-arch.c
@@ -25,6 +25,56 @@
 struct arch_object : public PyObject
 {
   struct gdbarch *gdbarch;
+
+  /* Return the gdbarch associated with OBJ.  Throws an exception on
+     error.  */
+  struct gdbarch *require ()
+  {
+    if (gdbarch == nullptr)
+      gdbpy_err_set_string (PyExc_RuntimeError, _("Architecture is invalid."));
+    return gdbarch;
+  }
+
+  /* Implementation of gdb.Architecture.name (self) -> String.
+     Returns the name of the architecture as a string value.  */
+  const char *name ()
+  {
+    return gdbarch_bfd_arch_info (require ())->printable_name;
+  }
+
+  /* __repr__ implementation for gdb.Architecture.  */
+  gdbpy_ref<> repr ();
+
+  /* Implementation of gdb.void_type.  */
+  gdbpy_ref<> void_type ()
+  {
+    return type_to_type_object (builtin_type (require ())->builtin_void);
+  }
+
+  /* Implementation of gdb.Architecture.register_groups (self) -> Iterator.
+     Returns an iterator that will give up all valid register groups in the
+     architecture SELF.  */
+  gdbpy_ref<> register_groups ()
+  {
+    return gdbpy_new_reggroup_iterator (require ());
+  }
+
+  /* Implementation of
+     gdb.Architecture.disassemble (self, start_pc [, end_pc [,count]]) -> List.
+     Returns a list of instructions in a memory address range.  Each instruction
+     in the list is a Python dict object.  */
+  gdbpy_ref<> disassemble (gdbpy_borrowed_ref<> args,
+			   gdbpy_opt_borrowed_ref<> kw);
+
+  /* Implementation of gdb.integer_type.  */
+  gdbpy_ref<> integer_type (gdbpy_borrowed_ref<> args,
+			    gdbpy_opt_borrowed_ref<> kw);
+
+  /* Implementation of gdb.Architecture.registers (self, reggroup) ->
+     Iterator.  Returns an iterator over register descriptors for
+     registers in GROUP within the architecture SELF.  */
+  gdbpy_ref<> registers (gdbpy_borrowed_ref<> args,
+			 gdbpy_opt_borrowed_ref<> kw);
 };
 
 static_assert (gdb::is_python_allocatable_v<arch_object>);
@@ -32,18 +82,6 @@ static_assert (gdb::is_python_allocatable_v<arch_object>);
 static const registry<gdbarch>::key<PyObject, gdb::noop_deleter<PyObject>>
      arch_object_data;
 
-/* Require a valid Architecture.  */
-#define ARCHPY_REQUIRE_VALID(arch_obj, arch)			\
-  do {								\
-    arch = arch_object_to_gdbarch (arch_obj);			\
-    if (arch == NULL)						\
-      {								\
-	PyErr_SetString (PyExc_RuntimeError,			\
-			 _("Architecture is invalid."));	\
-	return NULL;						\
-      }								\
-  } while (0)
-
 extern PyTypeObject arch_object_type;
 
 /* Associates an arch_object with GDBARCH as gdbarch_data via the gdbarch
@@ -102,80 +140,46 @@ gdbarch_to_arch_object (struct gdbarch *gdbarch)
   return gdbpy_ref<> (new_ref);
 }
 
-/* Implementation of gdb.Architecture.name (self) -> String.
-   Returns the name of the architecture as a string value.  */
-
-static PyObject *
-archpy_name (PyObject *self, PyObject *args)
-{
-  struct gdbarch *gdbarch = NULL;
-  const char *name;
-
-  ARCHPY_REQUIRE_VALID (self, gdbarch);
-
-  name = (gdbarch_bfd_arch_info (gdbarch))->printable_name;
-  return PyUnicode_FromString (name);
-}
-
-/* Implementation of
-   gdb.Architecture.disassemble (self, start_pc [, end_pc [,count]]) -> List.
-   Returns a list of instructions in a memory address range.  Each instruction
-   in the list is a Python dict object.
-*/
-
-static PyObject *
-archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw)
+gdbpy_ref<>
+arch_object::disassemble (gdbpy_borrowed_ref<> args,
+			  gdbpy_opt_borrowed_ref<> kw)
 {
   static const char *keywords[] = {
     "start_pc", "end_pc", "count", "styling", nullptr
   };
-  CORE_ADDR start = 0, end = 0;
   CORE_ADDR pc;
   long count = 0, i;
   PyObject *start_obj = nullptr, *end_obj = nullptr, *count_obj = nullptr;
-  struct gdbarch *gdbarch = NULL;
   int styling_p = 0;
 
-  ARCHPY_REQUIRE_VALID (self, gdbarch);
+  struct gdbarch *gdbarch = require ();
 
-  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O|OOp",
-					keywords, &start_obj, &end_obj,
-					&count_obj, &styling_p))
-    return NULL;
+  gdbpy_arg_parse_tuple_and_keywords (args, kw, "O|OOp",
+				      keywords, &start_obj, &end_obj,
+				      &count_obj, &styling_p);
 
-  if (get_addr_from_python (start_obj, &start) < 0)
-    return nullptr;
+  CORE_ADDR start = gdbpy_get_address (start_obj);
 
+  CORE_ADDR end = 0;
   if (end_obj != nullptr)
     {
-      if (get_addr_from_python (end_obj, &end) < 0)
-	return nullptr;
+      end = gdbpy_get_address (end_obj);
 
       if (end < start)
-	{
-	  PyErr_SetString (PyExc_ValueError,
-			   _("Argument 'end_pc' should be greater than or "
-			     "equal to the argument 'start_pc'."));
-
-	  return NULL;
-	}
+	gdbpy_err_set_string (PyExc_ValueError,
+			      _("Argument 'end_pc' should be greater than or "
+				"equal to the argument 'start_pc'."));
     }
   if (count_obj)
     {
-      count = PyLong_AsLong (count_obj);
-      if (PyErr_Occurred () || count < 0)
-	{
-	  PyErr_SetString (PyExc_TypeError,
-			   _("Argument 'count' should be an non-negative "
-			     "integer."));
-
-	  return NULL;
-	}
+      count = gdbpy_long_as_long (count_obj);
+      if (count < 0)
+	gdbpy_err_set_string (PyExc_TypeError,
+			      _("Argument 'count' should be an non-negative "
+				"integer."));
     }
 
-  gdbpy_ref<> result_list (PyList_New (0));
-  if (result_list == NULL)
-    return NULL;
+  gdbpy_ref<> result_list = gdbpy_new_list (0);
 
   for (pc = start, i = 0;
        /* All args are specified.  */
@@ -187,105 +191,72 @@ archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw)
        /* Both end_pc and count are not specified.  */
        || (end_obj == NULL && count_obj == NULL && pc == start);)
     {
-      int insn_len = 0;
-      gdbpy_ref<> insn_dict (PyDict_New ());
+      gdbpy_ref<> insn_dict = gdbpy_new_dict ();
 
-      if (insn_dict == NULL)
-	return NULL;
-      if (PyList_Append (result_list.get (), insn_dict.get ()))
-	return NULL;  /* PyList_Append Sets the exception.  */
+      gdbpy_list_append (result_list, insn_dict);
 
       string_file stb (styling_p);
+      int insn_len = gdb_print_insn (gdbarch, pc, &stb, NULL);
 
-      try
-	{
-	  insn_len = gdb_print_insn (gdbarch, pc, &stb, NULL);
-	}
-      catch (const gdb_exception &except)
-	{
-	  return gdbpy_handle_gdb_exception (nullptr, except);
-	}
-
+      /* FIXME: Python safety.  Eventually gdb_py_object_from_ulongest
+	 should throw.  */
       gdbpy_ref<> pc_obj = gdb_py_object_from_ulongest (pc);
       if (pc_obj == nullptr)
-	return nullptr;
+	throw gdb_python_exception ();
 
-      gdbpy_ref<> asm_obj
-	(PyUnicode_FromString (!stb.empty () ? stb.c_str () : "<unknown>"));
-      if (asm_obj == nullptr)
-	return nullptr;
+      gdbpy_ref<> asm_obj = gdbpy_unicode_from_string (!stb.empty ()
+						       ? stb.c_str ()
+						       : "<unknown>");
 
+      /* FIXME: Python safety.  Eventually gdb_py_object_from_longest
+	 should throw.  */
       gdbpy_ref<> len_obj = gdb_py_object_from_longest (insn_len);
       if (len_obj == nullptr)
-	return nullptr;
+	throw gdb_python_exception ();
 
-      if (PyDict_SetItemString (insn_dict.get (), "addr", pc_obj.get ())
-	  || PyDict_SetItemString (insn_dict.get (), "asm", asm_obj.get ())
-	  || PyDict_SetItemString (insn_dict.get (), "length", len_obj.get ()))
-	return NULL;
+      gdbpy_dict_set_item_string (insn_dict, "addr", pc_obj);
+      gdbpy_dict_set_item_string (insn_dict, "asm", asm_obj);
+      gdbpy_dict_set_item_string (insn_dict, "length", len_obj);
 
       pc += insn_len;
       i++;
     }
 
-  return result_list.release ();
+  return result_list;
 }
 
-/* Implementation of gdb.Architecture.registers (self, reggroup) -> Iterator.
-   Returns an iterator over register descriptors for registers in GROUP
-   within the architecture SELF.  */
-
-static PyObject *
-archpy_registers (PyObject *self, PyObject *args, PyObject *kw)
+gdbpy_ref<>
+arch_object::registers (gdbpy_borrowed_ref<> args,
+			gdbpy_opt_borrowed_ref<> kw)
 {
   static const char *keywords[] = { "reggroup", NULL };
-  struct gdbarch *gdbarch = NULL;
   const char *group_name = NULL;
 
   /* Parse method arguments.  */
-  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "|s", keywords,
-					&group_name))
-    return NULL;
+  gdbpy_arg_parse_tuple_and_keywords (args, kw, "|s", keywords, &group_name);
 
   /* Extract the gdbarch from the self object.  */
-  ARCHPY_REQUIRE_VALID (self, gdbarch);
+  struct gdbarch *gdbarch = require ();
 
   return gdbpy_new_register_descriptor_iterator (gdbarch, group_name);
 }
 
-/* Implementation of gdb.Architecture.register_groups (self) -> Iterator.
-   Returns an iterator that will give up all valid register groups in the
-   architecture SELF.  */
-
-static PyObject *
-archpy_register_groups (PyObject *self, PyObject *args)
-{
-  struct gdbarch *gdbarch = NULL;
-
-  /* Extract the gdbarch from the self object.  */
-  ARCHPY_REQUIRE_VALID (self, gdbarch);
-  return gdbpy_new_reggroup_iterator (gdbarch);
-}
-
-/* Implementation of gdb.integer_type.  */
-static PyObject *
-archpy_integer_type (PyObject *self, PyObject *args, PyObject *kw)
+gdbpy_ref<>
+arch_object::integer_type (gdbpy_borrowed_ref<> args,
+			   gdbpy_opt_borrowed_ref<> kw)
 {
   static const char *keywords[] = { "size", "signed", NULL };
   int size;
   PyObject *is_signed_obj = Py_True;
 
-  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "i|O!", keywords,
-					&size,
-					&PyBool_Type, &is_signed_obj))
-    return nullptr;
+  gdbpy_arg_parse_tuple_and_keywords (args, kw, "i|O!", keywords, &size,
+				      &PyBool_Type, &is_signed_obj);
 
   /* Assume signed by default.  */
   gdb_assert (PyBool_Check (is_signed_obj));
   bool is_signed = is_signed_obj == Py_True;
 
-  struct gdbarch *gdbarch;
-  ARCHPY_REQUIRE_VALID (self, gdbarch);
+  struct gdbarch *gdbarch = require ();
 
   const struct builtin_type *builtins = builtin_type (gdbarch);
   struct type *type = nullptr;
@@ -314,61 +285,41 @@ archpy_integer_type (PyObject *self, PyObject *args, PyObject *kw)
       break;
 
     default:
-      PyErr_SetString (PyExc_ValueError,
-		       _("no integer type of that size is available"));
-      return nullptr;
+      gdbpy_err_set_string (PyExc_ValueError,
+			    _("no integer type of that size is available"));
     }
 
-  return type_to_type_object (type).release ();
+  return type_to_type_object (type);
 }
 
-/* Implementation of gdb.void_type.  */
-static PyObject *
-archpy_void_type (PyObject *self, PyObject *args)
-{
-  struct gdbarch *gdbarch;
-  ARCHPY_REQUIRE_VALID (self, gdbarch);
-
-  return type_to_type_object (builtin_type (gdbarch)->builtin_void).release ();
-}
-
-/* __repr__ implementation for gdb.Architecture.  */
-
-static PyObject *
-archpy_repr (PyObject *self)
+gdbpy_ref<>
+arch_object::repr ()
 {
-  const auto gdbarch = arch_object_to_gdbarch (self);
   if (gdbarch == nullptr)
-    return gdb_py_invalid_object_repr (self);
+    /* FIXME: Python safety.  Eventually gdb_py_invalid_object_repr
+       should throw.  */
+    return gdbpy_ref<> (gdb_py_invalid_object_repr (this));
 
   auto arch_info = gdbarch_bfd_arch_info (gdbarch);
-  return PyUnicode_FromFormat ("<%s arch_name=%s printable_name=%s>",
-			       gdbpy_py_obj_tp_name (self).c_str (),
-			       arch_info->arch_name,
-			       arch_info->printable_name);
+  return gdbpy_unicode_from_format ("<%s arch_name=%s printable_name=%s>",
+				    gdbpy_py_obj_tp_name (this).c_str (),
+				    arch_info->arch_name,
+				    arch_info->printable_name);
 }
 
 /* Implementation of gdb.architecture_names().  Return a list of all the
    BFD architecture names that GDB understands.  */
 
-PyObject *
-gdbpy_all_architecture_names (PyObject *self, PyObject *args)
+gdbpy_ref<>
+gdbpy_all_architecture_names ()
 {
-  gdbpy_ref<> list (PyList_New (0));
-  if (list == nullptr)
-    return nullptr;
+  gdbpy_ref<> list = gdbpy_new_list (0);
 
   std::vector<const char *> name_list = gdbarch_printable_names ();
   for (const char *name : name_list)
-    {
-      gdbpy_ref <> py_name (PyUnicode_FromString (name));
-      if (py_name == nullptr)
-	return nullptr;
-      if (PyList_Append (list.get (), py_name.get ()) < 0)
-	return nullptr;
-    }
+    gdbpy_list_append (list, gdbpy_unicode_from_string (name));
 
- return list.release ();
+ return list;
 }
 
 /* Initializes the Architecture class in the gdb module.  */
@@ -385,32 +336,27 @@ GDBPY_INITIALIZE_FILE (gdbpy_initialize_arch);
 \f
 
 static PyMethodDef arch_object_methods [] = {
-  { "name", archpy_name, METH_NOARGS,
+  noargs_method<arch_object, &arch_object::name> ("name",
     "name () -> String.\n\
-Return the name of the architecture as a string value." },
-  { "disassemble", (PyCFunction) archpy_disassemble,
-    METH_VARARGS | METH_KEYWORDS,
+Return the name of the architecture as a string value."),
+  varargs_method<arch_object, &arch_object::disassemble> ("disassemble",
     "disassemble (start_pc [, end_pc [, count]]) -> List.\n\
 Return a list of at most COUNT disassembled instructions from START_PC to\n\
-END_PC." },
-  { "integer_type", (PyCFunction) archpy_integer_type,
-    METH_VARARGS | METH_KEYWORDS,
+END_PC."),
+  varargs_method<arch_object, &arch_object::integer_type> ("integer_type",
     "integer_type (size [, signed]) -> type\n\
 Return an integer Type corresponding to the given bitsize and signed-ness.\n\
-If not specified, the type defaults to signed." },
-  { "void_type", (PyCFunction) archpy_void_type,
-    METH_NOARGS,
+If not specified, the type defaults to signed."),
+  noargs_method<arch_object, &arch_object::void_type> ("void_type",
     "void_type () -> type\n\
-Return a void Type." },
-  { "registers", (PyCFunction) archpy_registers,
-    METH_VARARGS | METH_KEYWORDS,
+Return a void Type."),
+  varargs_method<arch_object, &arch_object::registers> ("registers",
     "registers ([ group-name ]) -> Iterator.\n\
 Return an iterator of register descriptors for the registers in register\n\
-group GROUP-NAME." },
-  { "register_groups", archpy_register_groups,
-    METH_NOARGS,
+group GROUP-NAME."),
+  noargs_method<arch_object, &arch_object::register_groups> ("register_groups",
     "register_groups () -> Iterator.\n\
-Return an iterator over all of the register groups in this architecture." },
+Return an iterator over all of the register groups in this architecture."),
   {NULL}  /* Sentinel */
 };
 
@@ -424,7 +370,7 @@ PyTypeObject arch_object_type = {
   0,                                  /* tp_getattr */
   0,                                  /* tp_setattr */
   0,                                  /* tp_compare */
-  archpy_repr,                        /* tp_repr */
+  wrap_tp_callback<arch_object, &arch_object::repr>, /* tp_repr */
   0,                                  /* tp_as_number */
   0,                                  /* tp_as_sequence */
   0,                                  /* tp_as_mapping */
diff --git a/gdb/python/py-registers.c b/gdb/python/py-registers.c
index e0180660715..80a57207b0a 100644
--- a/gdb/python/py-registers.c
+++ b/gdb/python/py-registers.c
@@ -43,6 +43,8 @@ struct register_descriptor_iterator_object : public PyObject
 
   /* Pointer back to the architecture we're finding registers for.  */
   struct gdbarch *gdbarch;
+
+  static PyTypeObject *corresponding_object_type;
 };
 
 static_assert (gdb::is_python_allocatable_v<register_descriptor_iterator_object>);
@@ -71,6 +73,8 @@ struct reggroup_iterator_object : public PyObject
 
   /* Pointer back to the architecture we're finding registers for.  */
   struct gdbarch *gdbarch;
+
+  static PyTypeObject *corresponding_object_type;
 };
 
 static_assert (gdb::is_python_allocatable_v<reggroup_iterator_object>);
@@ -231,20 +235,17 @@ gdbpy_reggroup_iter_next (PyObject *self)
 /* Return a new gdb.RegisterGroupsIterator over all the register groups in
    GDBARCH.  */
 
-PyObject *
+gdbpy_ref<>
 gdbpy_new_reggroup_iterator (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != nullptr);
 
   /* Create a new object and fill in its internal state.  */
-  reggroup_iterator_object *iter
-    = PyObject_New (reggroup_iterator_object,
-		    &reggroup_iterator_object_type);
-  if (iter == NULL)
-    return NULL;
+  gdbpy_ref<reggroup_iterator_object> iter
+    = gdbpy_new<reggroup_iterator_object> ();
   iter->index = 0;
   iter->gdbarch = gdbarch;
-  return (PyObject *) iter;
+  return iter;
 }
 
 /* Create and return a new gdb.RegisterDescriptorIterator object which
@@ -255,7 +256,7 @@ gdbpy_new_reggroup_iterator (struct gdbarch *gdbarch)
 
    This function can return NULL if GROUP_NAME isn't found.  */
 
-PyObject *
+gdbpy_ref<>
 gdbpy_new_register_descriptor_iterator (struct gdbarch *gdbarch,
 					const char *group_name)
 {
@@ -268,25 +269,19 @@ gdbpy_new_register_descriptor_iterator (struct gdbarch *gdbarch,
     {
       grp = reggroup_find (gdbarch, group_name);
       if (grp == NULL)
-	{
-	  PyErr_SetString (PyExc_ValueError,
-			   _("Unknown register group name."));
-	  return NULL;
-	}
+	gdbpy_err_set_string (PyExc_ValueError,
+			      _("Unknown register group name."));
     }
   /* Create a new iterator object initialised for this architecture and
      fill in all of the details.  */
-  register_descriptor_iterator_object *iter
-    = PyObject_New (register_descriptor_iterator_object,
-		    &register_descriptor_iterator_object_type);
-  if (iter == NULL)
-    return NULL;
+  gdbpy_ref<register_descriptor_iterator_object> iter
+    = gdbpy_new<register_descriptor_iterator_object> ();
   iter->regnum = 0;
   iter->gdbarch = gdbarch;
   gdb_assert (grp != NULL);
   iter->reggroup = grp;
 
-  return (PyObject *) iter;
+  return iter;
 }
 
 /* Return a reference to the gdb.RegisterDescriptorIterator object.  */
@@ -494,6 +489,9 @@ PyTypeObject register_descriptor_iterator_object_type = {
   register_descriptor_iterator_object_methods		/*tp_methods */
 };
 
+PyTypeObject *register_descriptor_iterator_object::corresponding_object_type
+  = &register_descriptor_iterator_object_type;
+
 static gdb_PyGetSetDef gdbpy_register_descriptor_getset[] = {
   { "name", gdbpy_register_descriptor_name, NULL,
     "The name of this register.", NULL },
@@ -564,6 +562,9 @@ PyTypeObject reggroup_iterator_object_type = {
   0				  /*tp_methods */
 };
 
+PyTypeObject *reggroup_iterator_object::corresponding_object_type
+  = &reggroup_iterator_object_type;
+
 static gdb_PyGetSetDef gdbpy_reggroup_getset[] = {
   { "name", gdbpy_reggroup_name, NULL,
     "The name of this register group.", NULL },
diff --git a/gdb/python/py-safety.h b/gdb/python/py-safety.h
index 3294f38c8b6..d47a34b760f 100644
--- a/gdb/python/py-safety.h
+++ b/gdb/python/py-safety.h
@@ -233,6 +233,32 @@ varargs_wrapper (PyObject *self, PyObject *args, PyObject *kw)
 
 } /* namespace safety_details */
 
+/* Create a PyMethodDef for a no-argument function.  It takes the
+   takes the underlying implementation function as a template
+   argument, and also arguments for the method name and documentation
+   string.
+
+   The underlying function should take no arguments.
+
+   The function can return any type (see the to_python overloads); and
+   should throw an exception on error.  If gdb_python_exception is
+   thrown, the Python exception must already have been set.  */
+template<auto F>
+constexpr PyMethodDef
+noargs_function (const char *name, const char *doc)
+{
+  using namespace safety_details;
+  return {
+    name,
+    [] (PyObject *self, PyObject *args) -> PyObject *
+    {
+      return wrapped_function<F> ();
+    },
+    METH_NOARGS,
+    doc,
+  };
+}
+
 /* Create a PyMethodDef for a no-argument method.  It takes the
    underlying class C and a pointer-to-method M as template
    parameters, and the name and documentation as arguments.  The
diff --git a/gdb/python/py-wrappers.h b/gdb/python/py-wrappers.h
index 6c2b5e4d41e..d45682d1ddb 100644
--- a/gdb/python/py-wrappers.h
+++ b/gdb/python/py-wrappers.h
@@ -358,4 +358,15 @@ gdbpy_sequence_concat (gdbpy_borrowed_ref<> first, gdbpy_borrowed_ref<> second)
   return result;
 }
 
+/* A wrapper for get_addr_from_python that returns the address or
+   throws an exception.  */
+static inline CORE_ADDR
+gdbpy_get_address (gdbpy_borrowed_ref<> obj)
+{
+  CORE_ADDR result;
+  if (get_addr_from_python (obj, &result) < 0)
+    throw gdb_python_exception ();
+  return result;
+}
+
 #endif /* GDB_PYTHON_PY_WRAPPERS_H */
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 1165f165e29..a91ae4957a1 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -525,11 +525,11 @@ PyObject *objfpy_get_xmethods (PyObject *, void *);
 PyObject *gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw);
 
 gdbpy_ref<> gdbarch_to_arch_object (struct gdbarch *gdbarch);
-PyObject *gdbpy_all_architecture_names (PyObject *self, PyObject *args);
+gdbpy_ref<> gdbpy_all_architecture_names ();
 
-PyObject *gdbpy_new_register_descriptor_iterator (struct gdbarch *gdbarch,
-						  const char *group_name);
-PyObject *gdbpy_new_reggroup_iterator (struct gdbarch *gdbarch);
+gdbpy_ref<> gdbpy_new_register_descriptor_iterator (struct gdbarch *gdbarch,
+						    const char *group_name);
+gdbpy_ref<> gdbpy_new_reggroup_iterator (struct gdbarch *gdbarch);
 
 gdbpy_ref<thread_object> create_thread_object (struct thread_info *tp);
 gdbpy_ref<> thread_to_thread_object (thread_info *thr);;
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 7b5de98b903..563b212fb43 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -3279,9 +3279,9 @@ Set the value of the convenience variable $NAME." },
 Register a TUI window constructor."),
 #endif	/* TUI */
 
-  { "architecture_names", gdbpy_all_architecture_names, METH_NOARGS,
+  noargs_function<gdbpy_all_architecture_names> ("architecture_names",
     "architecture_names () -> List.\n\
-Return a list of all the architecture names GDB understands." },
+Return a list of all the architecture names GDB understands."),
 
   { "connections", gdbpy_connections, METH_NOARGS,
     "connections () -> List.\n\
-- 
2.49.0


                 reply	other threads:[~2026-08-08 18:24 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20260808182339.3936136-1-tom@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