From: Matthieu Longo Date: Sat, 25 Oct 2025 22:55:29 +0000 (+0100) Subject: gdb: cast all Python extension objects passed to gdbpy_ref_policy to PyObject* X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1fe7c3b74924ab69da0469fd93a9de089843e65d;p=thirdparty%2Fbinutils-gdb.git gdb: cast all Python extension objects passed to gdbpy_ref_policy to PyObject* When enabling the Python limited API, pointers to Python C extension objects can no longer be implicitly converted to 'PyObject *' by the compiler. gdbpy_ref_policy is a templated class that provides a generic interface for incrementing and decrementing the reference counter on the given object. It is used as a specialisation of the policy parameter in gdb::ref_ptr, together with PyObject as the parameter type. As a result, gdbpy_ref_policy always expects an argument derived from PyObject. This patch fixes the resulting compilation issue by adding an explicit static_cast to 'PyObject *' before passing the value to Py_INCREF and Py_DECREF. As a side effect, these casts enforce, at compile time, that the template type passed to gdbpy_ref_policy is a subclass of PyObject. To provide a clearer diagnostic when an incorrect type is used, a static_assert is added to gdbpy_ref_policy, avoiding obscure errors originating from the static_cast. Finally, all C Python extension types passed to gdbpy_ref_policy are updated to inherit from PyObject. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23830 Approved-By: Tom Tromey --- diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index fc53213966a..408d4b9d857 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -37,10 +37,8 @@ extern PyTypeObject breakpoint_location_object_type; -struct gdbpy_breakpoint_location_object +struct gdbpy_breakpoint_location_object : public PyObject { - PyObject_HEAD - /* An owning reference to the gdb breakpoint location object. */ bp_location *bp_loc; diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c index 6b40b1796c6..3fbc26b0cde 100644 --- a/gdb/python/py-cmd.c +++ b/gdb/python/py-cmd.c @@ -50,10 +50,8 @@ static const struct cmdpy_completer completers[] = /* A gdb command. For the time being only ordinary commands (not set/show commands) are allowed. */ -struct cmdpy_object +struct cmdpy_object : public PyObject { - PyObject_HEAD - /* The corresponding gdb command object, or NULL if the command is no longer installed. */ struct cmd_list_element *command; diff --git a/gdb/python/py-color.c b/gdb/python/py-color.c index b41dff2edd7..0bec51b1e52 100644 --- a/gdb/python/py-color.c +++ b/gdb/python/py-color.c @@ -37,10 +37,8 @@ static struct { }; /* A color. */ -struct colorpy_object +struct colorpy_object : public PyObject { - PyObject_HEAD - /* Underlying value. */ ui_file_style::color color; }; diff --git a/gdb/python/py-connection.c b/gdb/python/py-connection.c index bef50b07f18..e2c29f6f180 100644 --- a/gdb/python/py-connection.c +++ b/gdb/python/py-connection.c @@ -31,10 +31,8 @@ /* The Python object that represents a connection. */ -struct connection_object +struct connection_object : public PyObject { - PyObject_HEAD - /* The process target that represents this connection. When a connection_object is created this field will always point at a valid target. Later, if GDB stops using this target (the target is popped diff --git a/gdb/python/py-corefile.c b/gdb/python/py-corefile.c index 24b573b2dbd..88fedbd718c 100644 --- a/gdb/python/py-corefile.c +++ b/gdb/python/py-corefile.c @@ -45,10 +45,8 @@ extern PyTypeObject corefile_object_type; /* A gdb.CorefileMapped object. */ -struct corefile_mapped_file_object +struct corefile_mapped_file_object : public PyObject { - PyObject_HEAD - /* The name of a file that was mapped when the core file was created. This is a 'str' object. */ PyObject *filename; @@ -70,10 +68,8 @@ extern PyTypeObject corefile_mapped_file_object_type; /* A gdb.CorefileMappedFileRegion object. */ -struct corefile_mapped_file_region_object +struct corefile_mapped_file_region_object : public PyObject { - PyObject_HEAD - /* The start and end addresses for this mapping, these are addresses within the inferior's address space. */ CORE_ADDR start; diff --git a/gdb/python/py-disasm.c b/gdb/python/py-disasm.c index c1aa4d0586a..a125907948c 100644 --- a/gdb/python/py-disasm.c +++ b/gdb/python/py-disasm.c @@ -28,10 +28,8 @@ /* Implement gdb.disassembler.DisassembleInfo type. An object of this type represents a single disassembler request from GDB. */ -struct disasm_info_object +struct disasm_info_object : public PyObject { - PyObject_HEAD - /* The architecture in which we are disassembling. */ struct gdbarch *gdbarch; @@ -99,10 +97,8 @@ extern PyTypeObject disasm_part_object_type; the disassembled instruction (in bytes), and the string representing the disassembled instruction. */ -struct disasm_result_object +struct disasm_result_object : public PyObject { - PyObject_HEAD - /* The length of the disassembled instruction in bytes. */ int length; diff --git a/gdb/python/py-events.h b/gdb/python/py-events.h index 9fc7a86920e..e44b4b4a761 100644 --- a/gdb/python/py-events.h +++ b/gdb/python/py-events.h @@ -27,10 +27,8 @@ /* Stores a list of objects to be notified when the event for which this registry tracks occurs. */ -struct eventregistry_object +struct eventregistry_object : public PyObject { - PyObject_HEAD - PyObject *callbacks; }; diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c index 027ccb4112d..ab7883b4e73 100644 --- a/gdb/python/py-frame.c +++ b/gdb/python/py-frame.c @@ -28,8 +28,8 @@ #include "symfile.h" #include "objfiles.h" -struct frame_object { - PyObject_HEAD +struct frame_object : public PyObject +{ struct frame_id frame_id; struct gdbarch *gdbarch; diff --git a/gdb/python/py-membuf.c b/gdb/python/py-membuf.c index 832ab62cf52..e3bf5e2ceab 100644 --- a/gdb/python/py-membuf.c +++ b/gdb/python/py-membuf.c @@ -19,9 +19,8 @@ #include "python-internal.h" -struct membuf_object { - PyObject_HEAD - +struct membuf_object : public PyObject +{ /* Pointer to the raw data, and array of gdb_bytes. */ void *buffer; diff --git a/gdb/python/py-micmd.c b/gdb/python/py-micmd.c index c6a96dc3ad5..0c820751c56 100644 --- a/gdb/python/py-micmd.c +++ b/gdb/python/py-micmd.c @@ -55,10 +55,8 @@ struct mi_command_py; /* Representation of a Python gdb.MICommand object. */ -struct micmdpy_object +struct micmdpy_object : public PyObject { - PyObject_HEAD - /* The object representing this command in the MI command table. This pointer can be nullptr if the command is not currently installed into the MI command table (see gdb.MICommand.installed property). */ diff --git a/gdb/python/py-ref.h b/gdb/python/py-ref.h index 4d44ca90e21..1d07eeb3dc9 100644 --- a/gdb/python/py-ref.h +++ b/gdb/python/py-ref.h @@ -26,14 +26,17 @@ template struct gdbpy_ref_policy { + static_assert(std::is_base_of::value, + "T must be a subclass of PyObject"); + static void incref (T *ptr) { - Py_INCREF (ptr); + Py_INCREF (static_cast (ptr)); } static void decref (T *ptr) { - Py_DECREF (ptr); + Py_DECREF (static_cast (ptr)); } }; diff --git a/gdb/python/py-registers.c b/gdb/python/py-registers.c index ac7480caea9..3d1683805d1 100644 --- a/gdb/python/py-registers.c +++ b/gdb/python/py-registers.c @@ -49,9 +49,8 @@ struct register_descriptor_iterator_object { extern PyTypeObject register_descriptor_iterator_object_type; /* A register descriptor. */ -struct register_descriptor_object { - PyObject_HEAD - +struct register_descriptor_object : public PyObject +{ /* The register this is a descriptor for. */ int regnum; @@ -75,9 +74,8 @@ struct reggroup_iterator_object { extern PyTypeObject reggroup_iterator_object_type; /* A register group object. */ -struct reggroup_object { - PyObject_HEAD - +struct reggroup_object : public PyObject +{ /* The register group being described. */ const struct reggroup *reggroup; }; diff --git a/gdb/python/py-tui.c b/gdb/python/py-tui.c index 578ddfbcc67..be19193770f 100644 --- a/gdb/python/py-tui.c +++ b/gdb/python/py-tui.c @@ -44,10 +44,8 @@ class tui_py_window; /* A PyObject representing a TUI window. */ -struct gdbpy_tui_window +struct gdbpy_tui_window: public PyObject { - PyObject_HEAD - /* The TUI window, or nullptr if the window has been deleted. */ tui_py_window *window; diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index f6915a62b7a..722edbd1a1c 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -350,10 +350,8 @@ extern PyTypeObject thread_object_type; extern bool gdbpy_breakpoint_init_breakpoint_type (); -struct gdbpy_breakpoint_object +struct gdbpy_breakpoint_object : public PyObject { - PyObject_HEAD - /* The breakpoint number according to gdb. */ int number;