Blame SOURCES/00364-thread-exit.patch

d7a225
bpo-44434: Don't call PyThread_exit_thread() explicitly (GH-26758)
d7a225
d7a225
_thread.start_new_thread() no longer calls PyThread_exit_thread()
d7a225
explicitly at the thread exit, the call was redundant.
d7a225
d7a225
On Linux with the glibc, pthread_cancel() loads dynamically the
d7a225
libgcc_s.so.1 library. dlopen() can fail if there is no more
d7a225
available file descriptor to open the file. In this case, the process
d7a225
aborts with the error message:
d7a225
d7a225
"libgcc_s.so.1 must be installed for pthread_cancel to work"
d7a225
d7a225
pthread_cancel() unwinds back to the thread's wrapping function that
d7a225
calls the thread entry point.
d7a225
d7a225
The unwind function is dynamically loaded from the libgcc_s library
d7a225
since it is tightly coupled to the C compiler (GCC). The unwinder
d7a225
depends on DWARF, the compiler generates DWARF, so the unwinder
d7a225
belongs to the compiler.
d7a225
d7a225
Thanks Florian Weimer and Carlos O'Donell for their help on
d7a225
investigating this issue.
d7a225
d7a225
https://github.com/python/cpython/commit/45a78f906d2d5fe5381d78466b11763fc56d57ba
d7a225
d7a225
Resolves: rhbz#1972293
d7a225
d7a225
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
d7a225
index a13b2e0..8cc035b 100644
d7a225
--- a/Modules/_threadmodule.c
d7a225
+++ b/Modules/_threadmodule.c
d7a225
@@ -1027,7 +1027,10 @@ t_bootstrap(void *boot_raw)
d7a225
     nb_threads--;
d7a225
     PyThreadState_Clear(tstate);
d7a225
     PyThreadState_DeleteCurrent();
d7a225
-    PyThread_exit_thread();
d7a225
+
d7a225
+    // bpo-44434: Don't call explicitly PyThread_exit_thread(). On Linux with
d7a225
+    // the glibc, pthread_exit() can abort the whole process if dlopen() fails
d7a225
+    // to open the libgcc_s.so library (ex: EMFILE error).
d7a225
 }
d7a225
 
d7a225
 static PyObject *