[binutils-gdb] Hold the GIL while clearing gdbpy_reggroup_object_map

Tom Tromey via Gdb-cvs <[email protected]>
Newsgroups gmane.comp.gdb.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=bbc133a3083cebcb9d2e010bef47753448d0046f

commit bbc133a3083cebcb9d2e010bef47753448d0046f
Author: Tom Tromey <[email protected]>
Date:   Tue Mar 24 08:59:31 2026 -0600

    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 <[email protected]>

Diff:
---
 gdb/python/py-registers.c    | 23 ++++++++++++++++-------
 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);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.