auto arch_info = gdbarch_bfd_arch_info (gdbarch);
return PyUnicode_FromFormat ("<%s arch_name=%s printable_name=%s>",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
arch_info->arch_name,
arch_info->printable_name);
}
str += ", ";
}
return PyUnicode_FromFormat ("<%s %s {%s}>",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
name, str.c_str ());
}
static PyObject *
bppy_repr (PyObject *self)
{
- const char *tp_name = gdbpy_py_obj_tp_name (self);
+ const auto &tp_name = gdbpy_py_obj_tp_name (self);
const auto bp = (struct gdbpy_breakpoint_object*) self;
if (bp->bp == nullptr)
str.pop_back ();
return PyUnicode_FromFormat ("<%s%s number=%d hits=%d%s>",
- tp_name,
+ tp_name.c_str (),
(bp->bp->enable_state == bp_enabled
? "" : " disabled"), bp->bp->number,
bp->bp->hit_count, str.c_str ());
}
return PyUnicode_FromFormat ("<%s %s>",
- gdbpy_py_obj_tp_name (py_self),
+ gdbpy_py_obj_tp_name (py_self).c_str (),
str.c_str ());
}
return gdb_py_invalid_object_repr (obj);
return PyUnicode_FromFormat ("<%s num=%d, what=\"%s\">",
- gdbpy_py_obj_tp_name (obj),
+ gdbpy_py_obj_tp_name (obj).c_str (),
target->connection_number,
make_target_connection_string (target).c_str ());
}
bfd *core_bfd = get_inferior_core_bfd (obj->inferior);
gdb_assert (core_bfd != nullptr);
return PyUnicode_FromFormat ("<%s inferior=%d filename='%s'>",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
obj->inferior->num,
bfd_get_filename (core_bfd));
}
const char *arch_name
= (gdbarch_bfd_arch_info (obj->gdbarch))->printable_name;
return PyUnicode_FromFormat ("<%s address=%s architecture=%s>",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
core_addr_to_string_nz (obj->address),
arch_name);
}
{
PyErr_Format (PyExc_ValueError,
_("Cannot use 'string' and 'parts' when creating %s."),
- gdbpy_py_obj_tp_name (self));
+ gdbpy_py_obj_tp_name (self).c_str ());
return -1;
}
gdb_assert (obj->parts != nullptr);
return PyUnicode_FromFormat ("<%s length=%d string=\"%U\">",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
obj->length,
disasmpy_result_str (self));
}
PyErr_Format
(PyExc_TypeError,
_("Result from Disassembler must be gdb.DisassemblerResult, not %s."),
- gdbpy_py_obj_tp_name (result.get ()));
+ gdbpy_py_obj_tp_name (result.get ()).c_str ());
gdbpy_print_stack ();
return std::optional<int> (-1);
}
{
PyErr_Format (PyExc_RuntimeError,
_("Cannot create instances of %s."),
- gdbpy_py_obj_tp_name (self));
+ gdbpy_py_obj_tp_name (self).c_str ());
return -1;
}
gdb_assert (obj->string != nullptr);
return PyUnicode_FromFormat ("<%s string='%s', style='%s'>",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
obj->string->c_str (),
get_style_name (obj->style));
}
disasm_addr_part_object *obj = (disasm_addr_part_object *) self;
return PyUnicode_FromFormat ("<%s address='%s'>",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
core_addr_to_string_nz (obj->address));
}
const frame_id &fid = frame_obj->frame_id;
return PyUnicode_FromFormat ("<%s level=%d frame-id=%s>",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
frame_relative_level (f_info),
fid.to_string ().c_str ());
}
{
PyErr_Format (PyExc_TypeError,
_("argument 1 must be gdb.Symbol or str, not %s"),
- gdbpy_py_obj_tp_name (sym_obj));
+ gdbpy_py_obj_tp_name (sym_obj).c_str ());
return NULL;
}
thread_info *thr = thread_obj->thread;
return PyUnicode_FromFormat ("<%s id=%s target-id=\"%s\">",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
print_full_thread_id (thr),
target_pid_to_str (thr->ptid).c_str ());
}
PyErr_Format
(PyExc_ValueError,
_("MI notification data must be either None or a dictionary, not %s"),
- gdbpy_py_obj_tp_name (data));
+ gdbpy_py_obj_tp_name (data).c_str ());
return nullptr;
}
{
PyErr_Format (PyExc_TypeError,
_("gdb.MICommand.installed must be set to a bool, not %s"),
- newvalue == Py_None ? "None" : gdbpy_py_obj_tp_name (newvalue));
+ (newvalue == Py_None
+ ? "None"
+ : gdbpy_py_obj_tp_name (newvalue).c_str ()));
return -1;
}
#include "py-obj-type.h"
/* Return the type's fully qualified name from a PyTypeObject. */
-const char *
+std::string
gdb_py_tp_name (PyTypeObject *py_type) noexcept
{
+ static const std::string NO_TYPE_NAME = "<type name unavailable>";
+
+ /* This helper should be used for cases when the called CPython function
+ informs the caller that an error occurred, and a Python error was set. */
+ auto handle_err = [&]() -> std::string
+ {
+ gdbpy_print_stack ();
+ PyErr_Clear ();
+ return NO_TYPE_NAME;
+ };
+
+ /* Convert a PyObject to a UTF-8 encoded string. */
+ auto pyobj_to_str = [&](PyObject *name) -> std::string
+ {
+ const char *s = PyUnicode_AsUTF8AndSize (name, nullptr);
+ if (s == nullptr)
+ return handle_err ();
+ return s;
+ };
+
#if PY_VERSION_HEX >= 0x030d0000
- /* Note: PyType_GetFullyQualifiedName() was added in version 3.13, and is
- part of the stable ABI since version 3.13. */
- PyObject *fully_qualified_name = PyType_GetFullyQualifiedName (py_type);
+ /* Notes:
+ 1. PyType_GetFullyQualifiedName() was added in version 3.13, and is
+ part of the stable ABI since version 3.13.
+ 2. If an error occurs when looking up the module name (for instance,
+ during the destruction of the object), PyType_GetFullyQualifiedName()
+ returns NULL, and a Python error is set. */
+ gdbpy_ref<> fully_qualified_name (PyType_GetFullyQualifiedName (py_type));
if (fully_qualified_name == nullptr)
- return nullptr;
-
- return PyUnicode_AsUTF8AndSize (fully_qualified_name, nullptr);
+ return handle_err ();
+ return pyobj_to_str (fully_qualified_name.get ());
#else /* PY_VERSION_HEX < 0x030d0000 && ! defined (Py_LIMITED_API) */
- /* For non-heap types, the fully qualified name corresponds to tp_name. */
+ /* For non-heap types, the fully qualified name corresponds to tp_name,
+ which can never be NULL. */
if (! (PyType_GetFlags (py_type) & Py_TPFLAGS_HEAPTYPE))
return py_type->tp_name;
cases, e.g. the module name may be missing. */
# if PY_VERSION_HEX >= 0x030b0000
- /* Note: PyType_GetQualName() was added in version 3.11. */
- PyObject *qualname = PyType_GetQualName (py_type);
+ /* Notes:
+ 1. PyType_GetQualName() was added in version 3.11.
+ 2. On one hand, PyType_GetQualName() relies internally on ht_qualname
+ which is supposed to never be NULL, therefore, does not set any Python
+ error. On the other hand, PyType_GetQualName() calls internally
+ PyUnicode_AsUTF8AndSize(), which when erroring, sets a Python error
+ and returns NULL. */
+ gdbpy_ref<> qualname (PyType_GetQualName (py_type));
if (qualname == nullptr)
- return nullptr;
-
- return PyUnicode_AsUTF8AndSize (qualname, nullptr);
+ return handle_err ();
+ return pyobj_to_str (qualname.get ());
# else
/* In the absence of PyType_GetQualName(), fallback on using PyHeapTypeObject
when the minimum supported Python version is increased above 3.10. */
PyHeapTypeObject *ht = (PyHeapTypeObject *) py_type;
if (ht->ht_qualname == nullptr)
- return nullptr;
-
- return PyUnicode_AsUTF8AndSize (ht->ht_qualname, nullptr);
+ return NO_TYPE_NAME;
+ return pyobj_to_str (ht->ht_qualname);
# endif
#endif
}
/* Return the type's fully qualified name from a PyObject. */
-const char *
+std::string
gdbpy_py_obj_tp_name (PyObject *self) noexcept
{
/* Note: Py_TYPE () is part of the stable ABI since version 3.14. */
#define GDB_PYTHON_PY_OBJ_TYPE_H
/* Return the type's fully qualified name from a PyTypeObject. */
-extern const char *gdb_py_tp_name (PyTypeObject *py_type) noexcept;
+extern std::string gdb_py_tp_name (PyTypeObject *py_type) noexcept;
/* Return the type's fully qualified name from a PyObject. */
-extern const char *gdbpy_py_obj_tp_name (PyObject *self) noexcept;
+extern std::string gdbpy_py_obj_tp_name (PyObject *self) noexcept;
#endif /* GDB_PYTHON_PY_OBJ_TYPE_H */
PyErr_Format
(PyExc_TypeError,
_("'foreground' argument must be gdb.Color or None, not %s."),
- gdbpy_py_obj_tp_name (fg));
+ gdbpy_py_obj_tp_name (fg).c_str ());
return -1;
}
PyErr_Format
(PyExc_TypeError,
_("'background' argument must be gdb.Color or None, not %s."),
- gdbpy_py_obj_tp_name (bg));
+ gdbpy_py_obj_tp_name (bg).c_str ());
return -1;
}
if (!gdbpy_is_color (newvalue))
{
PyErr_Format (PyExc_TypeError, _("value must be gdb.Color, not %s"),
- gdbpy_py_obj_tp_name (newvalue));
+ gdbpy_py_obj_tp_name (newvalue).c_str ());
return -1;
}
if (!gdbpy_is_color (newvalue))
{
PyErr_Format (PyExc_TypeError, _("value must be gdb.Color, not %s"),
- gdbpy_py_obj_tp_name (newvalue));
+ gdbpy_py_obj_tp_name (newvalue).c_str ());
return -1;
}
PyErr_Format
(PyExc_TypeError,
_("value must be a Long (a gdb.INTENSITY constant), not %s"),
- gdbpy_py_obj_tp_name (newvalue));
+ gdbpy_py_obj_tp_name (newvalue).c_str ());
return -1;
}
if (style_obj->style_name == nullptr)
return PyUnicode_FromFormat ("<%s fg=%s, bg=%s, intensity=%s>",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
fg_str.get (), bg_str.get (),
intensity_str);
else
return PyUnicode_FromFormat ("<%s name='%s', fg=%s, bg=%s, intensity=%s>",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
style_obj->style_name, fg_str.get (),
bg_str.get (), intensity_str);
}
return gdb_py_invalid_object_repr (self);
return PyUnicode_FromFormat ("<%s print_name=%s>",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
symbol->print_name ());
}
host_charset (), NULL);
return PyUnicode_FromFormat ("<%s code=%s name=%U>",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
code, py_typename);
}
if (pending_frame->frame_info == nullptr)
return PyUnicode_FromFormat ("<%s for an invalid frame>",
- gdbpy_py_obj_tp_name (self));
+ gdbpy_py_obj_tp_name (self).c_str ());
std::string saved_reg_names;
struct gdbarch *gdbarch = pending_frame->gdbarch;
const frame_info_ptr &frame (*pending_frame->frame_info);
return PyUnicode_FromFormat ("<%s frame #%d, saved_regs=(%s)>",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
frame_relative_level (frame),
saved_reg_names.c_str ());
}
}
return PyUnicode_FromFormat ("<%s level=%d, sp=%s, pc=%s>",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
frame_relative_level (frame),
sp_str,
pc_str);
gdb_assert (pyo_unwind_info != nullptr);
if (!PyObject_TypeCheck (pyo_unwind_info, &unwind_info_object_type))
error (_("an Unwinder should return gdb.UnwindInfo, not %s."),
- gdbpy_py_obj_tp_name (pyo_unwind_info));
+ gdbpy_py_obj_tp_name (pyo_unwind_info).c_str ());
{
unwind_info_object *unwind_info =
Therefore, we must explicitly raise an AttributeError in this case. */
PyErr_Format (PyExc_AttributeError,
"'%s' object has no attribute '%s'",
- gdbpy_py_obj_tp_name (self),
+ gdbpy_py_obj_tp_name (self).c_str (),
PyUnicode_AsUTF8AndSize (attr, nullptr));
return nullptr;
}
PyObject *
gdb_py_invalid_object_repr (PyObject *self)
{
- return PyUnicode_FromFormat ("<%s (invalid)>", gdbpy_py_obj_tp_name (self));
+ return PyUnicode_FromFormat ("<%s (invalid)>",
+ gdbpy_py_obj_tp_name (self).c_str ());
}
{
if (PyType_Ready (type) < 0)
return -1;
- const char *tp_name = gdb_py_tp_name (type);
+ const auto &tp_name = gdb_py_tp_name (type);
+ std::string_view tp_name_s = tp_name;
if (mod == nullptr)
{
- gdb_assert (startswith (tp_name, "gdb."));
+ gdb_assert (startswith (tp_name_s, "gdb."));
mod = gdb_module;
}
- const char *dot = strrchr (tp_name, '.');
- gdb_assert (dot != nullptr);
- return gdb_pymodule_addobject (mod, dot + 1, (PyObject *) type);
+ const auto pos_dot = tp_name_s.find_last_of ('.');
+ gdb_assert (pos_dot != tp_name_s.npos);
+ return gdb_pymodule_addobject (mod,
+ tp_name_s.substr (pos_dot + 1).data (),
+ (PyObject *) type);
}
/* Poison PyType_Ready. Only gdbpy_type_ready should be used, to
PyErr_Format
(PyExc_TypeError,
_("'style' argument must be gdb.Style or None, not %s."),
- gdbpy_py_obj_tp_name (style_obj));
+ gdbpy_py_obj_tp_name (style_obj).c_str ());
return nullptr;
}