Make 'import gdb.events' work

Pierre-Marie noticed that, while gdb.events is a Python module, it
can't be imported.  This patch changes how this module is created, so
that it can be imported, while also ensuring that the module is always
visible, just as it was in the past.

This new approach required one non-obvious change -- when running
gdb.base/warning.exp, where --data-directory is intentionally not
found, the event registries can now be nullptr.  Consequently, this
patch probably also requires

    https://sourceware.org/pipermail/gdb-patches/2022-June/189796.html

Note that this patch obsoletes

    https://sourceware.org/pipermail/gdb-patches/2022-June/189797.html
This commit is contained in:
Tom Tromey 2022-06-03 07:59:49 -06:00
parent 736918239b
commit 3acd9a692d
6 changed files with 37 additions and 22 deletions

View File

@ -27,6 +27,11 @@ else:
from _gdb import *
# Historically, gdb.events was always available, so ensure it's
# still available without an explicit import.
import _gdbevents as events
sys.modules['gdb.events'] = events
class _GdbFile(object):
# These two are needed in Python 3

View File

@ -118,7 +118,9 @@ gdbpy_initialize_eventregistry (void)
bool
evregpy_no_listeners_p (eventregistry_object *registry)
{
return PyList_Size (registry->callbacks) == 0;
/* REGISTRY can be nullptr if gdb failed to find the data directory
at startup. */
return registry == nullptr || PyList_Size (registry->callbacks) == 0;
}
static PyMethodDef eventregistry_object_methods[] =

View File

@ -23,7 +23,7 @@
static struct PyModuleDef EventModuleDef =
{
PyModuleDef_HEAD_INIT,
"gdb.events",
"_gdbevents",
NULL,
-1,
NULL,
@ -33,7 +33,8 @@ static struct PyModuleDef EventModuleDef =
NULL
};
/* Initialize python events. */
/* Helper function to add a single event registry to the events
module. */
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
add_new_registry (eventregistry_object **registryp, const char *name)
@ -48,24 +49,21 @@ add_new_registry (eventregistry_object **registryp, const char *name)
(PyObject *)(*registryp));
}
int
gdbpy_initialize_py_events (void)
/* Create and populate the _gdbevents module. Note that this is
always created, see the base gdb __init__.py. */
PyMODINIT_FUNC
gdbpy_events_mod_func ()
{
gdb_py_events.module = PyModule_Create (&EventModuleDef);
if (gdb_py_events.module == nullptr)
return nullptr;
if (!gdb_py_events.module)
return -1;
#define GDB_PY_DEFINE_EVENT(name) \
#define GDB_PY_DEFINE_EVENT(name) \
if (add_new_registry (&gdb_py_events.name, #name) < 0) \
return -1;
return nullptr;
#include "py-all-events.def"
#undef GDB_PY_DEFINE_EVENT
if (gdb_pymodule_addobject (gdb_module,
"events",
(PyObject *) gdb_py_events.module) < 0)
return -1;
return 0;
return gdb_py_events.module;
}

View File

@ -521,8 +521,6 @@ int gdbpy_initialize_eventregistry (void)
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
int gdbpy_initialize_event (void)
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
int gdbpy_initialize_py_events (void)
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
int gdbpy_initialize_arch (void)
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
int gdbpy_initialize_registers ()
@ -543,6 +541,8 @@ void gdbpy_finalize_micommands ();
int gdbpy_initialize_disasm ()
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
PyMODINIT_FUNC gdbpy_events_mod_func ();
/* A wrapper for PyErr_Fetch that handles reference counting for the
caller. */
class gdbpy_err_fetch

View File

@ -2005,11 +2005,20 @@ do_start_initialization ()
remain alive for the duration of the program's execution, so
it is not freed after this call. */
Py_SetProgramName (progname_copy);
/* Define _gdb as a built-in module. */
PyImport_AppendInittab ("_gdb", init__gdb_module);
#endif
/* Define all internal modules. These are all imported (and thus
created) during initialization. */
struct _inittab mods[3] =
{
{ "_gdb", init__gdb_module },
{ "_gdbevents", gdbpy_events_mod_func },
{ nullptr, nullptr }
};
if (PyImport_ExtendInittab (mods) < 0)
return false;
Py_Initialize ();
#if PY_VERSION_HEX < 0x03090000
/* PyEval_InitThreads became deprecated in Python 3.9 and will
@ -2077,7 +2086,6 @@ do_start_initialization ()
|| gdbpy_initialize_thread () < 0
|| gdbpy_initialize_inferior () < 0
|| gdbpy_initialize_eventregistry () < 0
|| gdbpy_initialize_py_events () < 0
|| gdbpy_initialize_event () < 0
|| gdbpy_initialize_arch () < 0
|| gdbpy_initialize_registers () < 0

View File

@ -38,6 +38,8 @@ clean_restart ${testfile}
if { [skip_python_tests] } { continue }
gdb_test_no_output "python import gdb.events"
set pyfile [gdb_remote_download host ${srcdir}/${subdir}/py-events.py]
gdb_test_no_output "source ${pyfile}" "load python file"