From 0ed6cbeac848c266be839141d9b8c1a04fe1e15a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 16 Jun 2021 16:49:19 +0200 Subject: [PATCH] bpo-44434: Don't call PyThread_exit_thread() explicitly _thread.start_new_thread() no longer calls PyThread_exit_thread() explicitly at the thread exit, the call was redundant. On Linux with the glibc, pthread_cancel() loads dynamically the libgcc_s.so.1 library. dlopen() can fail if there is no more available file descriptor to open the file. In this case, the process aborts with the error message: "libgcc_s.so.1 must be installed for pthread_cancel to work" pthread_cancel() unwinds back to the thread's wrapping function that calls the thread entry point. The unwind function is dynamically loaded from the libgcc_s library since it is tightly coupled to the C compiler (GCC). The unwinder depends on DWARF, the compiler generates DWARF, so the unwinder belongs to the compiler. Thanks Florian Weimer and Carlos O'Donell for their help on investigating this issue. --- .../next/Library/2021-06-16-16-52-14.bpo-44434.SQS4Pg.rst | 4 ++++ Modules/_threadmodule.c | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2021-06-16-16-52-14.bpo-44434.SQS4Pg.rst diff --git a/Misc/NEWS.d/next/Library/2021-06-16-16-52-14.bpo-44434.SQS4Pg.rst b/Misc/NEWS.d/next/Library/2021-06-16-16-52-14.bpo-44434.SQS4Pg.rst new file mode 100644 index 00000000000000..37b5b57ce65693 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-06-16-16-52-14.bpo-44434.SQS4Pg.rst @@ -0,0 +1,4 @@ +_thread.start_new_thread() no longer calls PyThread_exit_thread() explicitly +at the thread exit, the call was redundant. On Linux with the glibc, +pthread_exit() aborts the whole process if dlopen() fails to open +libgcc_s.so file (ex: EMFILE error). Patch by Victor Stinner. diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 3f7f1d23bc90da..cf2443e0fe9a11 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1107,7 +1107,9 @@ thread_run(void *boot_raw) PyThreadState_Clear(tstate); _PyThreadState_DeleteCurrent(tstate); - PyThread_exit_thread(); + // bpo-44434: Don't call explicitly PyThread_exit_thread(). On Linux with + // the glibc, pthread_exit() can abort the whole process if dlopen() fails + // to open the libgcc_s.so library (ex: EMFILE error). } static PyObject *