gdb/python: break more dependencies between gdbpy_initialize_* functions
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. 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. 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. This commit is similar to the previous one, and fixes the second dependency issue that I found. 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. Previously we depended on the ordering of calls to gdbpy_initialize_breakpoints and gdbpy_initialize_finishbreakpoints in python.c. 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. I feel that this change makes the dependency explicit, which I think is a good thing. There should be no user visible changes after this commit.
This commit is contained in:
parent
66bd1b294d
commit
8a3b17063e
3 changed files with 36 additions and 2 deletions
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue