Closed
Description
On Linux, when I stress test test_threading.test_4_daemon_threads(), it does crash randomly:
./python -m test test_threading -m test_4_daemon_threads -j50 -F --fail-env-changed
gdb traceback:
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00000000006e02f4 in PyInterpreterState_ThreadHead (interp=0xdddddddddddddddd) at Python/pystate.c:1961
warning: Source file is more recent than executable.
1961 return interp->threads.head;
[Current thread is 1 (Thread 0x7fcbb8ff96c0 (LWP 510515))]
Missing separate debuginfos, use: dnf debuginfo-install bzip2-libs-1.0.8-13.fc38.x86_64 glibc-2.37-5.fc38.x86_64 libffi-3.4.4-2.fc38.x86_64 libgcc-13.2.1-1.fc38.x86_64 openssl-libs-3.0.9-2.fc38.x86_64 xz-libs-5.4.1-1.fc38.x86_64 zlib-1.2.13-3.fc38.x86_64
(gdb) where
#0 0x00000000006e02f4 in PyInterpreterState_ThreadHead (interp=0xdddddddddddddddd) at Python/pystate.c:1961
#1 0x0000000000703090 in _Py_DumpTracebackThreads (fd=2, interp=0xdddddddddddddddd, current_tstate=0x24a34e0) at Python/traceback.c:1331
#2 0x000000000071bcef in faulthandler_dump_traceback (fd=2, all_threads=1, interp=0xa53688 <_PyRuntime+92712>) at ./Modules/faulthandler.c:195
#3 0x000000000071bfed in faulthandler_fatal_error (signum=11) at ./Modules/faulthandler.c:313
#4 <signal handler called>
#5 0x000000000069f808 in take_gil (tstate=0x24a34e0) at Python/ceval_gil.c:360
#6 0x00000000006a03ab in PyEval_RestoreThread (tstate=0x24a34e0) at Python/ceval_gil.c:714
#7 0x000000000074dd93 in portable_lseek (self=0x7fcc186c3590, posobj=0x0, whence=1, suppress_pipe_error=false) at ./Modules/_io/fileio.c:934
#8 0x000000000074de88 in _io_FileIO_tell_impl (self=0x7fcc186c3590) at ./Modules/_io/fileio.c:997
#9 0x000000000074ea4c in _io_FileIO_tell (self=0x7fcc186c3590, _unused_ignored=0x0) at ./Modules/_io/clinic/fileio.c.h:460
(...)
gdb debug:
(gdb) frame 5
#5 0x000000000069f808 in take_gil (tstate=0x24a34e0) at Python/ceval_gil.c:360
360 struct _gil_runtime_state *gil = ceval->gil;
(gdb) l
355 }
356
357 assert(_PyThreadState_CheckConsistency(tstate));
358 PyInterpreterState *interp = tstate->interp;
359 struct _ceval_state *ceval = &interp->ceval;
360 struct _gil_runtime_state *gil = ceval->gil;
361
362 /* Check that _PyEval_InitThreads() was called to create the lock */
363 assert(gil_created(gil));
364
(gdb) p /x ceval
$1 = 0xdddddddddddddddd
(gdb) p /x tstate->interp
$2 = 0xdddddddddddddddd
(gdb) p /x tstate
$5 = 0x24a34e0
(gdb) p /x _PyRuntime._finalizing._value
$3 = 0xab8fa8
(gdb) p /x _PyRuntime._finalizing_id
$4 = 0x7fcc49fce740
I don't understand why the test didn't exit: _PyThreadState_MustExit() should return, no?
I don't understand why assert(_PyThreadState_CheckConsistency(tstate));
didn't fail.
Maybe Py_Finalize() was called between the pre-check:
if (_PyThreadState_MustExit(tstate)) {
/* bpo-39877: If Py_Finalize() has been called and tstate is not the
thread which called Py_Finalize(), exit immediately the thread.
This code path can be reached by a daemon thread after Py_Finalize()
completes. In this case, tstate is a dangling pointer: points to
PyThreadState freed memory. */
PyThread_exit_thread();
}
assert(_PyThreadState_CheckConsistency(tstate));
and the code:
PyInterpreterState *interp = tstate->interp;
struct _ceval_state *ceval = &interp->ceval;
struct _gil_runtime_state *gil = ceval->gil;
Linked PRs
Metadata
Metadata
Assignees
Projects
Status
Done