mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 10:35:12 +08:00
gdb/python: add mechanism to manage Python initialization functions
Currently, when we add a new python sub-system to GDB, e.g. py-inferior.c, we end up having to create a new function like gdbpy_initialize_inferior, which then has to be called from the function do_start_initialization in python.c. In some cases (py-micmd.c and py-tui.c), we have two functions gdbpy_initialize_*, and gdbpy_finalize_*, with the second being called from finalize_python which is also in python.c. This commit proposes a mechanism to manage these initialization and finalization calls, this means that adding a new Python subsystem will no longer require changes to python.c or python-internal.h, instead, the initialization and finalization functions will be registered directly from the sub-system file, e.g. py-inferior.c, or py-micmd.c. The initialization and finalization functions are managed through a new class gdbpy_initialize_file in python-internal.h. This class contains a single global vector of all the initialization and finalization functions. In each Python sub-system we create a new gdbpy_initialize_file object, the object constructor takes care of registering the two callback functions. Now from python.c we can call static functions on the gdbpy_initialize_file class which take care of walking the callback list and invoking each callback in turn. To slightly simplify the Python sub-system files I added a new macro GDBPY_INITIALIZE_FILE, which hides the need to create an object. We can now just do this: GDBPY_INITIALIZE_FILE (gdbpy_initialize_registers); One possible problem with this change is that there is now no guaranteed ordering of how the various sub-systems are initialized (or finalized). To try and avoid dependencies creeping in I have added a use of the environment variable GDB_REVERSE_INIT_FUNCTIONS, this is the same environment variable used in the generated init.c file. Just like with init.c, when this environment variable is set we reverse the list of Python initialization (and finalization) functions. As there is already a test that starts GDB with the environment variable set then this should offer some level of protection against dependencies creeping in - though for full protection I guess we'd need to run all gdb.python/*.exp tests with the variable set. I have tested this patch with the environment variable set, and saw no regressions, so I think we are fine right now. One other change of note was for gdbpy_initialize_gdb_readline, this function previously returned void. In order to make this function have the correct signature I've updated its return type to int, and we now return 0 to indicate success. All of the other initialize (and finalize) functions have been made static within their respective sub-system files. There should be no user visible changes after this commit.
This commit is contained in:
parent
a5d3f94c27
commit
3965bff5b9
@ -344,7 +344,7 @@ gdbpy_all_architecture_names (PyObject *self, PyObject *args)
|
||||
|
||||
/* Initializes the Architecture class in the gdb module. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_arch (void)
|
||||
{
|
||||
arch_object_type.tp_new = PyType_GenericNew;
|
||||
@ -355,6 +355,10 @@ gdbpy_initialize_arch (void)
|
||||
(PyObject *) &arch_object_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_arch);
|
||||
|
||||
|
||||
|
||||
static PyMethodDef arch_object_methods [] = {
|
||||
{ "name", archpy_name, METH_NOARGS,
|
||||
"name () -> String.\n\
|
||||
|
@ -56,7 +56,7 @@ info_auto_load_python_scripts (const char *pattern, int from_tty)
|
||||
auto_load_info_scripts (pattern, from_tty, &extension_language_python);
|
||||
}
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_auto_load (void)
|
||||
{
|
||||
add_setshow_boolean_cmd ("python-scripts", class_support,
|
||||
@ -95,3 +95,5 @@ Print the list of automatically loaded Python scripts, deprecated."));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_auto_load);
|
||||
|
@ -418,7 +418,7 @@ blpy_iter_is_valid (PyObject *self, PyObject *args)
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_blocks (void)
|
||||
{
|
||||
block_object_type.tp_new = PyType_GenericNew;
|
||||
@ -437,6 +437,8 @@ gdbpy_initialize_blocks (void)
|
||||
(PyObject *) &block_syms_iterator_object_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_blocks);
|
||||
|
||||
|
||||
|
||||
static PyMethodDef block_object_methods[] = {
|
||||
|
@ -1246,7 +1246,7 @@ gdbpy_breakpoint_modified (struct breakpoint *b)
|
||||
|
||||
|
||||
/* Initialize the Python breakpoint code. */
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_breakpoints (void)
|
||||
{
|
||||
int i;
|
||||
@ -1286,7 +1286,7 @@ gdbpy_initialize_breakpoints (void)
|
||||
|
||||
/* Initialize the Python BreakpointLocation code. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_breakpoint_locations ()
|
||||
{
|
||||
if (PyType_Ready (&breakpoint_location_object_type) < 0)
|
||||
@ -1450,6 +1450,9 @@ _initialize_py_breakpoint ()
|
||||
&setdebuglist, &showdebuglist);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_breakpoints);
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_breakpoint_locations);
|
||||
|
||||
/* Python function to set the enabled state of a breakpoint location. */
|
||||
|
||||
static int
|
||||
|
@ -551,7 +551,7 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
|
||||
|
||||
/* Initialize the 'commands' code. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_commands (void)
|
||||
{
|
||||
int i;
|
||||
@ -601,6 +601,8 @@ gdbpy_initialize_commands (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_commands);
|
||||
|
||||
|
||||
|
||||
static PyMethodDef cmdpy_object_methods[] =
|
||||
|
@ -285,7 +285,7 @@ connpy_get_connection_details (PyObject *self, void *closure)
|
||||
|
||||
/* Python specific initialization for this file. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_connection (void)
|
||||
{
|
||||
if (PyType_Ready (&connection_object_type) < 0)
|
||||
@ -447,6 +447,8 @@ _initialize_py_connection ()
|
||||
"py-connection");
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_connection);
|
||||
|
||||
/* Methods for the gdb.TargetConnection object type. */
|
||||
|
||||
static PyMethodDef connection_object_methods[] =
|
||||
|
@ -1019,7 +1019,7 @@ static struct PyModuleDef python_disassembler_module_def =
|
||||
|
||||
/* Called to initialize the Python structures in this file. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_disasm ()
|
||||
{
|
||||
/* Create the _gdb.disassembler module, and add it to the _gdb module. */
|
||||
@ -1053,6 +1053,10 @@ gdbpy_initialize_disasm ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_disasm);
|
||||
|
||||
|
||||
|
||||
/* Describe the gdb.disassembler.DisassembleInfo type. */
|
||||
|
||||
PyTypeObject disasm_info_object_type = {
|
||||
|
@ -54,7 +54,7 @@ evpy_add_attribute (PyObject *event, const char *name, PyObject *attr)
|
||||
|
||||
/* Initialize the Python event code. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_event (void)
|
||||
{
|
||||
return gdbpy_initialize_event_generic (&event_object_type,
|
||||
@ -114,6 +114,8 @@ evpy_emit_event (PyObject *event,
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_event);
|
||||
|
||||
static gdb_PyGetSetDef event_object_getset[] =
|
||||
{
|
||||
{ "__dict__", gdb_py_generic_dict, NULL,
|
||||
|
@ -102,7 +102,7 @@ evregpy_dealloc (PyObject *self)
|
||||
|
||||
/* Initialize the Python event registry code. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_eventregistry (void)
|
||||
{
|
||||
if (PyType_Ready (&eventregistry_object_type) < 0)
|
||||
@ -123,6 +123,8 @@ evregpy_no_listeners_p (eventregistry_object *registry)
|
||||
return registry == nullptr || PyList_Size (registry->callbacks) == 0;
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_eventregistry);
|
||||
|
||||
static PyMethodDef eventregistry_object_methods[] =
|
||||
{
|
||||
{ "connect", evregpy_connect, METH_VARARGS, "Add function" },
|
||||
|
@ -435,7 +435,7 @@ bpfinishpy_handle_exit (struct inferior *inf)
|
||||
|
||||
/* Initialize the Python finish breakpoint code. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_finishbreakpoints (void)
|
||||
{
|
||||
if (!gdbpy_breakpoint_init_breakpoint_type ())
|
||||
@ -456,6 +456,10 @@ gdbpy_initialize_finishbreakpoints (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_finishbreakpoints);
|
||||
|
||||
|
||||
|
||||
static gdb_PyGetSetDef finish_breakpoint_object_getset[] = {
|
||||
{ "return_value", bpfinishpy_get_returnvalue, NULL,
|
||||
"gdb.Value object representing the return value, if any. \
|
||||
|
@ -717,7 +717,7 @@ frapy_richcompare (PyObject *self, PyObject *other, int op)
|
||||
|
||||
/* Sets up the Frame API in the gdb module. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_frames (void)
|
||||
{
|
||||
frame_object_type.tp_new = PyType_GenericNew;
|
||||
@ -749,6 +749,8 @@ gdbpy_initialize_frames (void)
|
||||
(PyObject *) &frame_object_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_frames);
|
||||
|
||||
|
||||
|
||||
static PyMethodDef frame_object_methods[] = {
|
||||
|
@ -134,7 +134,7 @@ fnpy_init (PyObject *self, PyObject *args, PyObject *kwds)
|
||||
|
||||
/* Initialize internal function support. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_functions (void)
|
||||
{
|
||||
fnpy_object_type.tp_new = PyType_GenericNew;
|
||||
@ -145,6 +145,8 @@ gdbpy_initialize_functions (void)
|
||||
(PyObject *) &fnpy_object_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_functions);
|
||||
|
||||
|
||||
|
||||
PyTypeObject fnpy_object_type =
|
||||
|
@ -90,7 +90,7 @@ gdbpy_readline_wrapper (FILE *sys_stdin, FILE *sys_stdout,
|
||||
|
||||
/* Initialize Python readline support. */
|
||||
|
||||
void
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_gdb_readline (void)
|
||||
{
|
||||
/* Python's readline module conflicts with GDB's use of readline
|
||||
@ -114,5 +114,8 @@ class GdbRemoveReadlineFinder:\n\
|
||||
sys.meta_path.append(GdbRemoveReadlineFinder())\n\
|
||||
") == 0)
|
||||
PyOS_ReadlineFunctionPointer = gdbpy_readline_wrapper;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_gdb_readline);
|
||||
|
@ -802,7 +802,7 @@ gdbpy_selected_inferior (PyObject *self, PyObject *args)
|
||||
inferior_to_inferior_object (current_inferior ()).release ());
|
||||
}
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_inferior (void)
|
||||
{
|
||||
if (PyType_Ready (&inferior_object_type) < 0)
|
||||
@ -838,6 +838,10 @@ gdbpy_initialize_inferior (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_inferior);
|
||||
|
||||
|
||||
|
||||
static gdb_PyGetSetDef inferior_object_getset[] =
|
||||
{
|
||||
{ "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
|
||||
|
@ -361,7 +361,7 @@ gdbpy_selected_thread (PyObject *self, PyObject *args)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_thread (void)
|
||||
{
|
||||
if (PyType_Ready (&thread_object_type) < 0)
|
||||
@ -371,6 +371,10 @@ gdbpy_initialize_thread (void)
|
||||
(PyObject *) &thread_object_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_thread);
|
||||
|
||||
|
||||
|
||||
static gdb_PyGetSetDef thread_object_getset[] =
|
||||
{
|
||||
{ "name", thpy_get_name, thpy_set_name,
|
||||
|
@ -81,10 +81,12 @@ py_insn_get_insn_type ()
|
||||
|
||||
/* Sets up the gdb.Instruction type. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_instruction (void)
|
||||
{
|
||||
if (py_insn_get_insn_type () == nullptr)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_instruction);
|
||||
|
@ -234,7 +234,7 @@ gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
|
||||
return (PyObject *) str_obj;
|
||||
}
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_lazy_string (void)
|
||||
{
|
||||
if (PyType_Ready (&lazy_string_object_type) < 0)
|
||||
@ -296,6 +296,8 @@ gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr,
|
||||
encoding->reset (lazy->encoding ? xstrdup (lazy->encoding) : NULL);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_lazy_string);
|
||||
|
||||
|
||||
|
||||
static PyMethodDef lazy_string_object_methods[] = {
|
||||
|
@ -285,7 +285,7 @@ ltpy_dealloc (PyObject *self)
|
||||
/* Initialize LineTable, LineTableEntry and LineTableIterator
|
||||
objects. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_linetable (void)
|
||||
{
|
||||
if (PyType_Ready (&linetable_object_type) < 0)
|
||||
@ -446,6 +446,8 @@ ltpy_iter_is_valid (PyObject *self, PyObject *args)
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_linetable);
|
||||
|
||||
|
||||
|
||||
static PyMethodDef linetable_object_methods[] = {
|
||||
|
@ -99,7 +99,7 @@ get_buffer (PyObject *self, Py_buffer *buf, int flags)
|
||||
|
||||
/* General Python initialization callback. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_membuf (void)
|
||||
{
|
||||
membuf_object_type.tp_new = PyType_GenericNew;
|
||||
@ -110,6 +110,10 @@ gdbpy_initialize_membuf (void)
|
||||
(PyObject *) &membuf_object_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_membuf);
|
||||
|
||||
|
||||
|
||||
static PyBufferProcs buffer_procs =
|
||||
{
|
||||
get_buffer
|
||||
|
@ -595,7 +595,7 @@ micmdpy_dealloc (PyObject *obj)
|
||||
|
||||
/* Python initialization for the MI commands components. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_micommands ()
|
||||
{
|
||||
micmdpy_object_type.tp_new = PyType_GenericNew;
|
||||
@ -614,7 +614,9 @@ gdbpy_initialize_micommands ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
/* Cleanup just before GDB shuts down the Python interpreter. */
|
||||
|
||||
static void
|
||||
gdbpy_finalize_micommands ()
|
||||
{
|
||||
/* mi_command_py objects hold references to micmdpy_object objects. They must
|
||||
@ -737,3 +739,5 @@ _initialize_py_micmd ()
|
||||
show_pymicmd_debug,
|
||||
&setdebuglist, &showdebuglist);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_micommands, gdbpy_finalize_micommands);
|
||||
|
@ -704,7 +704,7 @@ objfile_to_objfile_object (struct objfile *objfile)
|
||||
return gdbpy_ref<>::new_reference (result);
|
||||
}
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_objfile (void)
|
||||
{
|
||||
if (PyType_Ready (&objfile_object_type) < 0)
|
||||
@ -714,6 +714,8 @@ gdbpy_initialize_objfile (void)
|
||||
(PyObject *) &objfile_object_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_objfile);
|
||||
|
||||
|
||||
|
||||
static PyMethodDef objfile_object_methods[] =
|
||||
|
@ -906,7 +906,7 @@ parmpy_dealloc (PyObject *obj)
|
||||
}
|
||||
|
||||
/* Initialize the 'parameters' module. */
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_parameters (void)
|
||||
{
|
||||
int i;
|
||||
@ -934,6 +934,8 @@ gdbpy_initialize_parameters (void)
|
||||
(PyObject *) &parmpy_object_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_parameters);
|
||||
|
||||
|
||||
|
||||
PyTypeObject parmpy_object_type =
|
||||
|
@ -529,7 +529,7 @@ gdbpy_is_progspace (PyObject *obj)
|
||||
return PyObject_TypeCheck (obj, &pspace_object_type);
|
||||
}
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_pspace (void)
|
||||
{
|
||||
if (PyType_Ready (&pspace_object_type) < 0)
|
||||
@ -539,6 +539,8 @@ gdbpy_initialize_pspace (void)
|
||||
(PyObject *) &pspace_object_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_pspace);
|
||||
|
||||
|
||||
|
||||
static gdb_PyGetSetDef pspace_getset[] =
|
||||
|
@ -816,7 +816,7 @@ static PyMappingMethods btpy_list_mapping_methods =
|
||||
|
||||
/* Sets up the btrace record API. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_btrace (void)
|
||||
{
|
||||
btpy_list_type.tp_new = PyType_GenericNew;
|
||||
@ -837,3 +837,5 @@ gdbpy_initialize_btrace (void)
|
||||
|
||||
return PyType_Ready (&btpy_list_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_btrace);
|
||||
|
@ -544,7 +544,7 @@ static gdb_PyGetSetDef recpy_gap_getset[] = {
|
||||
|
||||
/* Sets up the record API in the gdb module. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_record (void)
|
||||
{
|
||||
recpy_record_type.tp_new = PyType_GenericNew;
|
||||
@ -648,3 +648,5 @@ gdbpy_stop_recording (PyObject *self, PyObject *args)
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_record);
|
||||
|
@ -427,7 +427,7 @@ gdbpy_parse_register_id (struct gdbarch *gdbarch, PyObject *pyo_reg_id,
|
||||
|
||||
/* Initializes the new Python classes from this file in the gdb module. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_registers ()
|
||||
{
|
||||
register_descriptor_object_type.tp_new = PyType_GenericNew;
|
||||
@ -462,6 +462,10 @@ gdbpy_initialize_registers ()
|
||||
(PyObject *) ®ister_descriptor_iterator_object_type));
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_registers);
|
||||
|
||||
|
||||
|
||||
static PyMethodDef register_descriptor_iterator_object_methods [] = {
|
||||
{ "find", (PyCFunction) register_descriptor_iter_find,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
|
@ -618,7 +618,7 @@ gdbpy_lookup_static_symbols (PyObject *self, PyObject *args, PyObject *kw)
|
||||
return return_list.release ();
|
||||
}
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_symbols (void)
|
||||
{
|
||||
if (PyType_Ready (&symbol_object_type) < 0)
|
||||
@ -687,6 +687,8 @@ gdbpy_initialize_symbols (void)
|
||||
(PyObject *) &symbol_object_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_symbols);
|
||||
|
||||
|
||||
|
||||
static gdb_PyGetSetDef symbol_object_getset[] = {
|
||||
|
@ -509,7 +509,7 @@ symtab_object_to_symtab (PyObject *obj)
|
||||
return ((symtab_object *) obj)->symtab;
|
||||
}
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_symtabs (void)
|
||||
{
|
||||
symtab_object_type.tp_new = PyType_GenericNew;
|
||||
@ -528,6 +528,8 @@ gdbpy_initialize_symtabs (void)
|
||||
(PyObject *) &sal_object_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_symtabs);
|
||||
|
||||
|
||||
|
||||
static gdb_PyGetSetDef symtab_object_getset[] = {
|
||||
|
@ -601,7 +601,7 @@ PyTypeObject gdbpy_tui_window_object_type =
|
||||
|
||||
/* Initialize this module. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_tui ()
|
||||
{
|
||||
#ifdef TUI
|
||||
@ -615,10 +615,12 @@ gdbpy_initialize_tui ()
|
||||
|
||||
/* Finalize this module. */
|
||||
|
||||
void
|
||||
static void
|
||||
gdbpy_finalize_tui ()
|
||||
{
|
||||
#ifdef TUI
|
||||
gdbpy_tui_window_maker::invalidate_all ();
|
||||
#endif /* TUI */
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_tui, gdbpy_finalize_tui);
|
||||
|
@ -1445,7 +1445,7 @@ gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw)
|
||||
return type_to_type_object (type);
|
||||
}
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_types (void)
|
||||
{
|
||||
if (PyType_Ready (&type_object_type) < 0)
|
||||
@ -1473,6 +1473,8 @@ gdbpy_initialize_types (void)
|
||||
(PyObject *) &field_object_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_types);
|
||||
|
||||
|
||||
|
||||
static gdb_PyGetSetDef type_object_getset[] =
|
||||
|
@ -969,23 +969,9 @@ pyuw_on_new_gdbarch (struct gdbarch *newarch)
|
||||
}
|
||||
}
|
||||
|
||||
void _initialize_py_unwind ();
|
||||
void
|
||||
_initialize_py_unwind ()
|
||||
{
|
||||
add_setshow_boolean_cmd
|
||||
("py-unwind", class_maintenance, &pyuw_debug,
|
||||
_("Set Python unwinder debugging."),
|
||||
_("Show Python unwinder debugging."),
|
||||
_("When on, Python unwinder debugging is enabled."),
|
||||
NULL,
|
||||
show_pyuw_debug,
|
||||
&setdebuglist, &showdebuglist);
|
||||
}
|
||||
|
||||
/* Initialize unwind machinery. */
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_unwind (void)
|
||||
{
|
||||
gdb::observers::architecture_changed.attach (pyuw_on_new_gdbarch,
|
||||
@ -1004,6 +990,24 @@ gdbpy_initialize_unwind (void)
|
||||
(PyObject *) &unwind_info_object_type);
|
||||
}
|
||||
|
||||
void _initialize_py_unwind ();
|
||||
void
|
||||
_initialize_py_unwind ()
|
||||
{
|
||||
add_setshow_boolean_cmd
|
||||
("py-unwind", class_maintenance, &pyuw_debug,
|
||||
_("Set Python unwinder debugging."),
|
||||
_("Show Python unwinder debugging."),
|
||||
_("When on, Python unwinder debugging is enabled."),
|
||||
NULL,
|
||||
show_pyuw_debug,
|
||||
&setdebuglist, &showdebuglist);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_unwind);
|
||||
|
||||
|
||||
|
||||
static PyMethodDef pending_frame_object_methods[] =
|
||||
{
|
||||
{ "read_register", (PyCFunction) pending_framepy_read_register,
|
||||
|
@ -2056,7 +2056,7 @@ gdbpy_is_value_object (PyObject *obj)
|
||||
return PyObject_TypeCheck (obj, &value_object_type);
|
||||
}
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_values (void)
|
||||
{
|
||||
if (PyType_Ready (&value_object_type) < 0)
|
||||
@ -2066,6 +2066,8 @@ gdbpy_initialize_values (void)
|
||||
(PyObject *) &value_object_type);
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_values);
|
||||
|
||||
|
||||
|
||||
static gdb_PyGetSetDef value_object_getset[] = {
|
||||
|
@ -599,7 +599,7 @@ python_xmethod_worker::python_xmethod_worker (PyObject *py_worker,
|
||||
Py_INCREF (this_type);
|
||||
}
|
||||
|
||||
int
|
||||
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
|
||||
gdbpy_initialize_xmethods (void)
|
||||
{
|
||||
py_match_method_name = PyUnicode_FromString (match_method_name);
|
||||
@ -613,3 +613,5 @@ gdbpy_initialize_xmethods (void)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
GDBPY_INITIALIZE_FILE (gdbpy_initialize_xmethods);
|
||||
|
@ -488,77 +488,120 @@ struct gdbarch *arch_object_to_gdbarch (PyObject *obj);
|
||||
|
||||
extern struct program_space *progspace_object_to_program_space (PyObject *obj);
|
||||
|
||||
void gdbpy_initialize_gdb_readline (void);
|
||||
int gdbpy_initialize_auto_load (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_values (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_frames (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_instruction (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_btrace (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_record (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_symtabs (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_commands (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_symbols (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_symtabs (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_blocks (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_types (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_functions (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_pspace (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_objfile (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_breakpoints (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_breakpoint_locations ()
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_finishbreakpoints (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_lazy_string (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_linetable (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_parameters (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_thread (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_inferior (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_eventregistry (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_event (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_arch (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_registers ()
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_xmethods (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_unwind (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_tui ()
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
void gdbpy_finalize_tui ();
|
||||
int gdbpy_initialize_membuf ()
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_connection ()
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_micommands (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
void gdbpy_finalize_micommands ();
|
||||
int gdbpy_initialize_disasm ()
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
/* A class for managing the initialization, and finalization functions
|
||||
from all Python files (e.g. gdb/python/py-*.c).
|
||||
|
||||
Within any Python file, create an instance of this class, passing in
|
||||
the initialization function, and, optionally, the finalization
|
||||
function.
|
||||
|
||||
These functions are added to a single global list of functions, which
|
||||
can then be called from do_start_initialization and finalize_python
|
||||
(see python.c) to initialize all the Python files within GDB. */
|
||||
|
||||
class gdbpy_initialize_file
|
||||
{
|
||||
/* The type of a function that can be called just after GDB has setup the
|
||||
Python interpreter. This function will setup any additional Python
|
||||
state required by a particular subsystem. Return 0 if the setup was
|
||||
successful, or return -1 if setup failed, in which case a Python
|
||||
exception should have been raised. */
|
||||
|
||||
using gdbpy_initialize_file_ftype = int (*) (void);
|
||||
|
||||
/* The type of a function that can be called just before GDB shuts down
|
||||
the Python interpreter. This function can cleanup an Python state
|
||||
that is cached within GDB, for example, if GDB is holding any
|
||||
references to Python objects, these should be released before the
|
||||
Python interpreter is shut down.
|
||||
|
||||
There is no error return in this case. This function is only called
|
||||
when GDB is already shutting down. The function should make a best
|
||||
effort to clean up, and then return. */
|
||||
|
||||
using gdbpy_finalize_file_ftype = void (*) (void);
|
||||
|
||||
/* The type for an initialization and finalization function pair. */
|
||||
|
||||
using callback_pair_t = std::pair<gdbpy_initialize_file_ftype,
|
||||
gdbpy_finalize_file_ftype>;
|
||||
|
||||
/* Return the vector of callbacks. The vector is defined as a static
|
||||
variable within this function so that it will be initialized the first
|
||||
time this function is called. This is important, as this function is
|
||||
called as part of the global object initialization process; if the
|
||||
vector was a static variable within this class then we could not
|
||||
guarantee that it had been initialized before it was used. */
|
||||
|
||||
static std::vector<callback_pair_t> &
|
||||
callbacks ()
|
||||
{
|
||||
static std::vector<callback_pair_t> list;
|
||||
return list;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/* Register the initialization (INIT) and finalization (FINI) functions
|
||||
for a Python file. See the comments on the function types above for
|
||||
when these functions will be called.
|
||||
|
||||
Either of these functions can be nullptr, in which case no function
|
||||
will be called.
|
||||
|
||||
The FINI argument is optional, and defaults to nullptr (no function to
|
||||
call). */
|
||||
|
||||
gdbpy_initialize_file (gdbpy_initialize_file_ftype init,
|
||||
gdbpy_finalize_file_ftype fini = nullptr)
|
||||
{
|
||||
callbacks ().emplace_back (init, fini);
|
||||
}
|
||||
|
||||
/* Run all the Python file initialize functions and return true. If any
|
||||
of the initialize functions fails then this function returns false.
|
||||
In the case of failure it is undefined how many of the initialize
|
||||
functions will have been called. */
|
||||
|
||||
static bool
|
||||
initialize_all ()
|
||||
{
|
||||
/* The initialize_all function should only be called once. The
|
||||
following check reverses the global list, which will effect this
|
||||
initialize_all call, as well as the later finalize_all call.
|
||||
|
||||
The environment variable checked here is the same as the one checked
|
||||
in the generated init.c file. */
|
||||
if (getenv ("GDB_REVERSE_INIT_FUNCTIONS") != nullptr)
|
||||
std::reverse (callbacks ().begin (), callbacks ().end ());
|
||||
|
||||
for (const auto &p : gdbpy_initialize_file::callbacks ())
|
||||
{
|
||||
if (p.first != nullptr && p.first () < 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Run all the Python file finalize functions. */
|
||||
|
||||
static void
|
||||
finalize_all ()
|
||||
{
|
||||
for (const auto &p : gdbpy_initialize_file::callbacks ())
|
||||
{
|
||||
if (p.second != nullptr)
|
||||
p.second ();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Macro to simplify registering the initialization and finalization
|
||||
functions for a Python file. */
|
||||
|
||||
#define GDBPY_INITIALIZE_FILE(INIT, ...) \
|
||||
static gdbpy_initialize_file \
|
||||
CONCAT(gdbpy_initialize_file_obj_, __LINE__) (INIT, ##__VA_ARGS__)
|
||||
|
||||
PyMODINIT_FUNC gdbpy_events_mod_func ();
|
||||
|
||||
|
@ -1955,8 +1955,8 @@ finalize_python (void *ignore)
|
||||
(void) PyGILState_Ensure ();
|
||||
gdbpy_enter::finalize ();
|
||||
|
||||
gdbpy_finalize_micommands ();
|
||||
gdbpy_finalize_tui ();
|
||||
/* Call the gdbpy_finalize_* functions from every *.c file. */
|
||||
gdbpy_initialize_file::finalize_all ();
|
||||
|
||||
Py_Finalize ();
|
||||
|
||||
@ -2144,41 +2144,8 @@ init_done:
|
||||
gdbpy_gdberror_exc) < 0)
|
||||
return false;
|
||||
|
||||
gdbpy_initialize_gdb_readline ();
|
||||
|
||||
if (gdbpy_initialize_auto_load () < 0
|
||||
|| gdbpy_initialize_values () < 0
|
||||
|| gdbpy_initialize_disasm () < 0
|
||||
|| gdbpy_initialize_frames () < 0
|
||||
|| gdbpy_initialize_commands () < 0
|
||||
|| gdbpy_initialize_instruction () < 0
|
||||
|| gdbpy_initialize_record () < 0
|
||||
|| gdbpy_initialize_btrace () < 0
|
||||
|| gdbpy_initialize_symbols () < 0
|
||||
|| gdbpy_initialize_symtabs () < 0
|
||||
|| gdbpy_initialize_blocks () < 0
|
||||
|| gdbpy_initialize_functions () < 0
|
||||
|| gdbpy_initialize_parameters () < 0
|
||||
|| gdbpy_initialize_types () < 0
|
||||
|| gdbpy_initialize_pspace () < 0
|
||||
|| gdbpy_initialize_objfile () < 0
|
||||
|| gdbpy_initialize_breakpoints () < 0
|
||||
|| gdbpy_initialize_breakpoint_locations () < 0
|
||||
|| gdbpy_initialize_finishbreakpoints () < 0
|
||||
|| gdbpy_initialize_lazy_string () < 0
|
||||
|| gdbpy_initialize_linetable () < 0
|
||||
|| gdbpy_initialize_thread () < 0
|
||||
|| gdbpy_initialize_inferior () < 0
|
||||
|| gdbpy_initialize_eventregistry () < 0
|
||||
|| gdbpy_initialize_event () < 0
|
||||
|| gdbpy_initialize_arch () < 0
|
||||
|| gdbpy_initialize_registers () < 0
|
||||
|| gdbpy_initialize_xmethods () < 0
|
||||
|| gdbpy_initialize_unwind () < 0
|
||||
|| gdbpy_initialize_membuf () < 0
|
||||
|| gdbpy_initialize_connection () < 0
|
||||
|| gdbpy_initialize_tui () < 0
|
||||
|| gdbpy_initialize_micommands () < 0)
|
||||
/* Call the gdbpy_initialize_* functions from every *.c file. */
|
||||
if (!gdbpy_initialize_file::initialize_all ())
|
||||
return false;
|
||||
|
||||
#define GDB_PY_DEFINE_EVENT_TYPE(name, py_name, doc, base) \
|
||||
|
Loading…
Reference in New Issue
Block a user