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) == 0; } +/* See python-internal.h. */ + +bool +gdbpy_breakpoint_init_breakpoint_type () +{ + if (breakpoint_object_type.tp_new == nullptr) + { + breakpoint_object_type.tp_new = 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 = nullptr; + return false; + } + } + + return true; +} + /* Static function to return a tuple holding all breakpoints. */ PyObject * @@ -1216,8 +1236,7 @@ gdbpy_initialize_breakpoints (void) { int i; - breakpoint_object_type.tp_new = PyType_GenericNew; - if (PyType_Ready (&breakpoint_object_type) < 0) + if (!gdbpy_breakpoint_init_breakpoint_type ()) return -1; if (gdb_pymodule_addobject (gdb_module, "Breakpoint", diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.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; 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"); +/* 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_type + 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