diff options
| author | Tom Tromey <tromey@adacore.com> | 2026-03-24 08:59:31 -0600 |
|---|---|---|
| committer | Tom Tromey <tromey@adacore.com> | 2026-03-25 11:12:14 -0600 |
| commit | bbc133a3083cebcb9d2e010bef47753448d0046f (patch) | |
| tree | 26a101298156a96b7f4af076fd15bdf7d617fdfa /gdb/python | |
| parent | 1a10ac99959e8d28694cb47d0632552e6feb03b2 (diff) | |
| download | binutils-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.c | 23 | ||||
| -rw-r--r-- | gdb/python/python-internal.h | 4 |
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); |
