aboutsummaryrefslogtreecommitdiff
path: root/gdb/python
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2026-03-24 08:59:31 -0600
committerTom Tromey <tromey@adacore.com>2026-03-25 11:12:14 -0600
commitbbc133a3083cebcb9d2e010bef47753448d0046f (patch)
tree26a101298156a96b7f4af076fd15bdf7d617fdfa /gdb/python
parent1a10ac99959e8d28694cb47d0632552e6feb03b2 (diff)
downloadbinutils-bbc133a3083cebcb9d2e010bef47753448d0046f.tar.gz
binutils-bbc133a3083cebcb9d2e010bef47753448d0046f.tar.bz2
binutils-bbc133a3083cebcb9d2e010bef47753448d0046f.zip
Hold the GIL while clearing gdbpy_reggroup_object_map
Tom de Vries pointed out that a certain Python test left a core file. Looking into this, I think the problem is that the GIL is not held when gdbpy_reggroup_object_map is destroyed. This patch changes the code to explicitly clear the global while holding the GIL. This fixed the crash for me. This also adds a comment to gdbpy_initialize_file to explicitly mention that the GIL is held while the finalizers are run. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34013 Reviewed-By: Tom de Vries <tdevries@suse.de>
Diffstat (limited to 'gdb/python')
-rw-r--r--gdb/python/py-registers.c23
-rw-r--r--gdb/python/python-internal.h4
2 files changed, 19 insertions, 8 deletions
diff --git a/gdb/python/py-registers.c b/gdb/python/py-registers.c
index 44bc53e6a9d..c6e0748e935 100644
--- a/gdb/python/py-registers.c
+++ b/gdb/python/py-registers.c
@@ -80,6 +80,13 @@ struct reggroup_object : public PyObject
extern PyTypeObject reggroup_object_type;
+/* Map from GDB's internal reggroup objects to the Python
+ representation. GDB's reggroups are global, and are never deleted,
+ so using a map like this is safe. Note it is explicitly cleaned at
+ Python shutdown, see gdbpy_finalize_registers. */
+static gdb::unordered_map<const struct reggroup *,gdbpy_ref<>>
+ gdbpy_reggroup_object_map;
+
/* Return a gdb.RegisterGroup object wrapping REGGROUP. The register
group objects are cached, and the same Python object will always be
returned for the same REGGROUP pointer. */
@@ -87,12 +94,6 @@ extern PyTypeObject reggroup_object_type;
static gdbpy_ref<>
gdbpy_get_reggroup (const reggroup *reggroup)
{
- /* Map from GDB's internal reggroup objects to the Python representation.
- GDB's reggroups are global, and are never deleted, so using a map like
- this is safe. */
- static gdb::unordered_map<const struct reggroup *,gdbpy_ref<>>
- gdbpy_reggroup_object_map;
-
/* If there is not already a suitable Python object in the map then
create a new one, and add it to the map. */
if (gdbpy_reggroup_object_map[reggroup] == nullptr)
@@ -433,7 +434,15 @@ gdbpy_initialize_registers ()
return 0;
}
-GDBPY_INITIALIZE_FILE (gdbpy_initialize_registers);
+static void
+gdbpy_finalize_registers ()
+{
+ /* Have to hold the GIL while clearing the global map; this is
+ guaranteed for finalizers. */
+ gdbpy_reggroup_object_map.clear ();
+}
+
+GDBPY_INITIALIZE_FILE (gdbpy_initialize_registers, gdbpy_finalize_registers);
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index bdc960ed208..b24b9314994 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -616,7 +616,9 @@ class gdbpy_initialize_file
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. */
+ effort to clean up, and then return.
+
+ The GIL will be held while calling the finalizers. */
using gdbpy_finalize_file_ftype = void (*) (void);