aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2022-06-03 07:59:49 -0600
committerTom Tromey <tromey@adacore.com>2022-07-05 10:28:39 -0600
commit3acd9a692ddaf8f24d6d34cb5ccb7c26d057e9b3 (patch)
tree19216ecf8b1235823b9251f84710982be599e5f8
parent736918239b16cc2ff57bfc64a982f2f0afc8c0f6 (diff)
downloadgdb-3acd9a692ddaf8f24d6d34cb5ccb7c26d057e9b3.zip
gdb-3acd9a692ddaf8f24d6d34cb5ccb7c26d057e9b3.tar.gz
gdb-3acd9a692ddaf8f24d6d34cb5ccb7c26d057e9b3.tar.bz2
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
-rw-r--r--gdb/python/lib/gdb/__init__.py5
-rw-r--r--gdb/python/py-evtregistry.c4
-rw-r--r--gdb/python/py-evts.c28
-rw-r--r--gdb/python/python-internal.h4
-rw-r--r--gdb/python/python.c16
-rw-r--r--gdb/testsuite/gdb.python/py-events.exp2
6 files changed, 37 insertions, 22 deletions
diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py
index a52f6b4..17ee6a1 100644
--- a/gdb/python/lib/gdb/__init__.py
+++ b/gdb/python/lib/gdb/__init__.py
@@ -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
diff --git a/gdb/python/py-evtregistry.c b/gdb/python/py-evtregistry.c
index ef96c48..f3a7f0c 100644
--- a/gdb/python/py-evtregistry.c
+++ b/gdb/python/py-evtregistry.c
@@ -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[] =
diff --git a/gdb/python/py-evts.c b/gdb/python/py-evts.c
index 23a5d75..ca9326a 100644
--- a/gdb/python/py-evts.c
+++ b/gdb/python/py-evts.c
@@ -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;
}
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 5ff9989..5d296a7 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -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
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 8f526bb..2f1a00e 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -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
diff --git a/gdb/testsuite/gdb.python/py-events.exp b/gdb/testsuite/gdb.python/py-events.exp
index a9ababb..9476273 100644
--- a/gdb/testsuite/gdb.python/py-events.exp
+++ b/gdb/testsuite/gdb.python/py-events.exp
@@ -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"