mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2026-08-27 00:26:02 -04:00
gdb/python: fix memory leak in gdb_py_tp_name
The current implementation of gdb_py_tp_name() leaks a reference to the object returned by PyType_GetFullyQualifiedName() for Python >= 3.13, and PyType_GetQualName() for Python >= 3.11. Managing the strong reference on the returned PyObject* with a gdbpy_ref<> fixes the reference count, but also causes the temporary object to be deallocated on function exit. As a consequence, the 'const char *' returned by PyUnicode_AsUTF8AndSize() becomes dangling and can no longer safely be returned. The proposed approach consists in changing gdb_py_tp_name() to return a std::string, and forcing a copy of the 'const char *' value, statically or dynamically allocated, stored in a temporary or non-temporary PyObject, depending on the version of Python it was compiled with. An unfortunate side effect of this fix is that every call sites where the tp_name is printed, must now use `.c_str()' because PyErr_Format() and its siblings cannot handle std::string. Approved-By: Andrew Burgess <aburgess@redhat.com>
This commit is contained in:
parent
fc7126f863
commit
dafd73bcda
19 changed files with 94 additions and 60 deletions
|
|
@ -343,7 +343,7 @@ archpy_repr (PyObject *self)
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -527,7 +527,7 @@ blpy_repr (PyObject *self)
|
|||
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 ());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1067,7 +1067,7 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
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)
|
||||
|
|
@ -1083,7 +1083,7 @@ bppy_repr (PyObject *self)
|
|||
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 ());
|
||||
|
|
@ -1776,7 +1776,7 @@ bplocpy_repr (PyObject *py_self)
|
|||
}
|
||||
|
||||
return PyUnicode_FromFormat ("<%s %s>",
|
||||
gdbpy_py_obj_tp_name (py_self),
|
||||
gdbpy_py_obj_tp_name (py_self).c_str (),
|
||||
str.c_str ());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ connpy_repr (PyObject *obj)
|
|||
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 ());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -400,7 +400,7 @@ cfpy_repr (PyObject *self)
|
|||
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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@ disasmpy_info_repr (PyObject *self)
|
|||
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);
|
||||
}
|
||||
|
|
@ -1003,7 +1003,7 @@ disasmpy_result_init (PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1087,7 +1087,7 @@ disasmpy_result_repr (PyObject *self)
|
|||
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));
|
||||
}
|
||||
|
|
@ -1302,7 +1302,7 @@ gdbpy_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
|
|||
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);
|
||||
}
|
||||
|
|
@ -1391,7 +1391,7 @@ disasmpy_part_init (PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1428,7 +1428,7 @@ disasmpy_text_part_repr (PyObject *self)
|
|||
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));
|
||||
}
|
||||
|
|
@ -1471,7 +1471,7 @@ disasmpy_addr_part_repr (PyObject *self)
|
|||
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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ frapy_repr (PyObject *self)
|
|||
|
||||
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 ());
|
||||
}
|
||||
|
|
@ -545,7 +545,7 @@ frapy_read_var (PyObject *self, PyObject *args, PyObject *kw)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ thpy_repr (PyObject *self)
|
|||
|
||||
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 ());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -379,7 +379,7 @@ gdbpy_notify_mi (PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -511,7 +511,9 @@ micmdpy_set_installed (PyObject *self, PyObject *newvalue, void *closure)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,20 +21,44 @@
|
|||
#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
|
||||
{
|
||||
#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);
|
||||
if (fully_qualified_name == nullptr)
|
||||
return nullptr;
|
||||
static const std::string NO_TYPE_NAME = "<type name unavailable>";
|
||||
|
||||
return PyUnicode_AsUTF8AndSize (fully_qualified_name, nullptr);
|
||||
/* 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
|
||||
/* 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 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;
|
||||
|
||||
|
|
@ -43,12 +67,17 @@ gdb_py_tp_name (PyTypeObject *py_type) noexcept
|
|||
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
|
||||
|
|
@ -58,15 +87,14 @@ gdb_py_tp_name (PyTypeObject *py_type) noexcept
|
|||
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. */
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
#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 */
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ stylepy_init_from_parts (PyObject *self, PyObject *fg, PyObject *bg,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -278,7 +278,7 @@ stylepy_init_from_parts (PyObject *self, PyObject *fg, PyObject *bg,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -485,7 +485,7 @@ stylepy_set_foreground (PyObject *self, PyObject *newvalue, void *closure)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -543,7 +543,7 @@ stylepy_set_background (PyObject *self, PyObject *newvalue, void *closure)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -625,7 +625,7 @@ stylepy_set_intensity (PyObject *self, PyObject *newvalue, void *closure)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -735,12 +735,12 @@ stylepy_repr (PyObject *self)
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -384,7 +384,7 @@ sympy_repr (PyObject *self)
|
|||
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 ());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1086,7 +1086,7 @@ typy_repr (PyObject *self)
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ unwind_infopy_repr (PyObject *self)
|
|||
|
||||
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;
|
||||
|
|
@ -268,7 +268,7 @@ unwind_infopy_repr (PyObject *self)
|
|||
|
||||
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 ());
|
||||
}
|
||||
|
|
@ -464,7 +464,7 @@ pending_framepy_repr (PyObject *self)
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
@ -939,7 +939,7 @@ frame_unwind_python::sniff (const frame_info_ptr &this_frame,
|
|||
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 =
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ gdb_py_generic_getattro (PyObject *self, PyObject *attr)
|
|||
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;
|
||||
}
|
||||
|
|
@ -700,5 +700,6 @@ gdbpy_fix_doc_string_indentation (gdb::unique_xmalloc_ptr<char> doc)
|
|||
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 ());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1132,15 +1132,18 @@ gdbpy_type_ready (PyTypeObject *type, PyObject *mod = nullptr)
|
|||
{
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1581,7 +1581,7 @@ gdbpy_write (PyObject *self, PyObject *args, PyObject *kw)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue