From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1726) id C65CB3850227; Thu, 20 Oct 2022 15:58:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C65CB3850227 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1666281490; bh=89IBT+zAQu+ei7j1eV0S1Hp4bdF9Sd3LvIE4+DRtxyc=; h=From:To:Subject:Date:From; b=Ignzk2QUx064Q110bOKwytAjGpjTpRLW71rayo93jZyqW8oI5xZSmTDmaBCJxPhKE H/4tTfOIHUYT1dUWjey32ROBMAz1syrNgmVklKWxJBxkmkxx1e4mpzuWP9iAUgXclP 1OQzYqo49gyNPl9ytQDRgSTbvidvmoVhJjvv4y14= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Andrew Burgess To: gdb-cvs@sourceware.org Subject: [binutils-gdb] gdb/python: break more dependencies between gdbpy_initialize_* functions X-Act-Checkin: binutils-gdb X-Git-Author: Andrew Burgess X-Git-Refname: refs/heads/master X-Git-Oldrev: 66bd1b294d8e5b460d6b9c645d2db529f4c441de X-Git-Newrev: 8a3b17063e86ba7687896de7b5de870006a02ef5 Message-Id: <20221020155810.C65CB3850227@sourceware.org> Date: Thu, 20 Oct 2022 15:58:10 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D8a3b17063e86= ba7687896de7b5de870006a02ef5 commit 8a3b17063e86ba7687896de7b5de870006a02ef5 Author: Andrew Burgess Date: Wed Sep 21 16:23:02 2022 +0100 gdb/python: break more dependencies between gdbpy_initialize_* functions =20 In a later commit in this series I will propose removing all of the explicit gdbpy_initialize_* calls from python.c and replace these calls with a more generic mechanism. =20 One of the side effects of this generic mechanism is that the order in which the various Python sub-systems within GDB are initialized is no longer guaranteed. =20 On the whole I don't think this matters, most of the sub-systems are independent of each other, though testing did reveal a few places where we did have dependencies, though I don't think those dependencies were explicitly documented in comment anywhere. =20 This commit is similar to the previous one, and fixes the second dependency issue that I found. =20 In this case the finish_breakpoint_object_type uses the breakpoint_object_type as its tp_base, this means that breakpoint_object_type must have been initialized with a call to PyType_Ready before finish_breakpoint_object_type can be initialized. =20 Previously we depended on the ordering of calls to gdbpy_initialize_breakpoints and gdbpy_initialize_finishbreakpoints in python.c. =20 After this commit a new function gdbpy_breakpoint_init_breakpoint_type exists, this function ensures that breakpoint_object_type has been initialized, and can be called from any gdbpy_initialize_* function. =20 I feel that this change makes the dependency explicit, which I think is a good thing. =20 There should be no user visible changes after this commit. Diff: --- gdb/python/py-breakpoint.c | 23 +++++++++++++++++++++-- gdb/python/py-finishbreakpoint.c | 3 +++ gdb/python/python-internal.h | 12 ++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index dd4519a1b05..7a757432948 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -989,6 +989,26 @@ build_bp_list (struct breakpoint *b, PyObject *list) return PyList_Append (list, bp) =3D=3D 0; } =20 +/* See python-internal.h. */ + +bool +gdbpy_breakpoint_init_breakpoint_type () +{ + if (breakpoint_object_type.tp_new =3D=3D nullptr) + { + breakpoint_object_type.tp_new =3D PyType_GenericNew; + if (PyType_Ready (&breakpoint_object_type) < 0) + { + /* Reset tp_new back to nullptr so future calls to this function + will try calling PyType_Ready again. */ + breakpoint_object_type.tp_new =3D nullptr; + return false; + } + } + + return true; +} + /* Static function to return a tuple holding all breakpoints. */ =20 PyObject * @@ -1216,8 +1236,7 @@ gdbpy_initialize_breakpoints (void) { int i; =20 - breakpoint_object_type.tp_new =3D PyType_GenericNew; - if (PyType_Ready (&breakpoint_object_type) < 0) + if (!gdbpy_breakpoint_init_breakpoint_type ()) return -1; =20 if (gdb_pymodule_addobject (gdb_module, "Breakpoint", diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpo= int.c index 0255bd1fead..fdbff5cf6bf 100644 --- a/gdb/python/py-finishbreakpoint.c +++ b/gdb/python/py-finishbreakpoint.c @@ -403,6 +403,9 @@ bpfinishpy_handle_exit (struct inferior *inf) int gdbpy_initialize_finishbreakpoints (void) { + if (!gdbpy_breakpoint_init_breakpoint_type ()) + return -1; + if (PyType_Ready (&finish_breakpoint_object_type) < 0) return -1; =20 diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index c2ac96de326..06357cc8c0b 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -290,6 +290,18 @@ extern PyTypeObject frame_object_type extern PyTypeObject thread_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("thread_object"); =20 +/* Ensure that breakpoint_object_type is initialized and return true. If + breakpoint_object_type can't be initialized then set a suitable Python + error and return false. + + This function needs to be called from any gdbpy_initialize_* function + that wants to reference breakpoint_object_type. After all the + gdbpy_initialize_* functions have been called then breakpoint_object_ty= pe + is guaranteed to have been initialized, and this function does not need + calling before referencing breakpoint_object_type. */ + +extern bool gdbpy_breakpoint_init_breakpoint_type (); + struct gdbpy_breakpoint_object { PyObject_HEAD