Data race creating Tcl interpreters concurrently via `_tkinter.create` under free-threading
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Python
- Estrellas
- 77.2k
- Forks
- 35.9k
- Métricas de merge de PR
- Métricas de PR pendientes
Descripción
Bug report
Bug description:
_tkinter declares Py_MOD_GIL_NOT_USED, so under --disable-gil the GIL no longer serializes calls into it. _tkinter.create() creates a new Tcl interpreter with Tcl_CreateInterp():
reached from _tkinter_create_impl:
_tkinter does not serialize interpreter creation, so two threads calling _tkinter.create() run Tcl_CreateInterp() concurrently. That triggers Tcl's first-time global initialization, where Tcl_MutexLock lazily initializes a static mutex. That init is not concurrency-safe, so one thread's pthread_mutex_init (write) races with another thread's pthread_mutex_lock (atomic read) on the same Tcl global.
Reproducer:
import _tkinter
from threading import Thread
def worker():
for _ in range(20000):
try:
_tkinter.create(None, '', 'Tk', False, 1, False, False, None)
except Exception:
pass
ts = [Thread(target=worker) for _ in range(12)]
for t in ts: t.start()
for t in ts: t.join()
TSAN Report (Tested on Linux, Tcl 8.6.14, with useTk=False):
==================
WARNING: ThreadSanitizer: data race (pid=650542)
Atomic read of size 1 at 0x72a0000145d0 by thread T2:
#0 pthread_mutex_lock <null>
#1 TclCreateExecEnv /usr/src/tcl8.6-8.6.14+dfsg-1build1/generic/tclExecute.c:936:5
#2 cfunction_vectorcall_FASTCALL /cpython/Objects/methodobject.c:449:24
#3 _PyObject_VectorcallTstate /cpython/./Include/internal/pycore_call.h:144:11
#4 PyObject_Vectorcall /cpython/Objects/call.c:327:12
#5 _Py_VectorCallInstrumentation_StackRefSteal /cpython/Python/ceval.c:768:11
#6 _PyEval_EvalFrameDefault /cpython/Python/generated_cases.c.h:1906:35
Previous write of size 1 at 0x72a0000145d0 by thread T1 (mutexes: write M0):
#0 pthread_mutex_init <null>
#1 Tcl_MutexLock /usr/src/tcl8.6-8.6.14+dfsg-1build1/unix/tclUnixThrd.c:430:6
#2 cfunction_vectorcall_FASTCALL /cpython/Objects/methodobject.c:449:24
#3 _PyObject_VectorcallTstate /cpython/./Include/internal/pycore_call.h:144:11
#4 PyObject_Vectorcall /cpython/Objects/call.c:327:12
#5 _Py_VectorCallInstrumentation_StackRefSteal /cpython/Python/ceval.c:768:11
#6 _PyEval_EvalFrameDefault /cpython/Python/generated_cases.c.h:1906:35
Location is heap block of size 16384 at 0x72a000014000 allocated by thread T1:
#0 malloc <null>
#1 GetBlocks /usr/src/tcl8.6-8.6.14+dfsg-1build1/generic/tclThreadAlloc.c:1044:17
#2 cfunction_vectorcall_FASTCALL /cpython/Objects/methodobject.c:449:24
#3 _PyObject_VectorcallTstate /cpython/./Include/internal/pycore_call.h:144:11
#4 PyObject_Vectorcall /cpython/Objects/call.c:327:12
#5 _Py_VectorCallInstrumentation_StackRefSteal /cpython/Python/ceval.c:768:11
#6 _PyEval_EvalFrameDefault /cpython/Python/generated_cases.c.h:1906:35
Mutex M0 (0x7fffb1dff7a0) created at:
#0 pthread_mutex_lock <null>
#1 Tcl_MutexLock /usr/src/tcl8.6-8.6.14+dfsg-1build1/unix/tclUnixThrd.c:423:2
#2 _PyImport_RunModInitFunc /cpython/./Python/importdl.c:436:19
#3 import_run_extension /cpython/Python/import.c:2167:14
#4 _imp_create_dynamic_impl /cpython/Python/import.c:5565:11
#5 _imp_create_dynamic /cpython/Python/clinic/import.c.h:489:20
#6 cfunction_vectorcall_FASTCALL /cpython/Objects/methodobject.c:449:24
#7 _PyVectorcall_Call /cpython/Objects/call.c:273:16
#8 _PyObject_Call /cpython/Objects/call.c:348:16
#9 PyObject_Call /cpython/Objects/call.c:373:12
#10 _PyEval_EvalFrameDefault /cpython/Python/generated_cases.c.h:2831:38
SUMMARY: ThreadSanitizer: data race (/cpython/cpython-tsan/bin/python3.16t+0xfad6e) in pthread_mutex_lock
==================
On macOS with Tcl/Tk 9.0 the same reproducer surfaces the _tkinter module-global data races (PyOS_InputHook, tcl_lock). With useTk=True it crashes inside Tk's own display initialization.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
- gh-156342
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Empieza en Modules/_tkinter.c, en Tcl_CreateInterp y _tkinter_create_impl, y luego reproduce las llamadas concurrentes con una compilación de CPython free-threaded usando ThreadSanitizer. Compara la condición de carrera de Tcl en Linux con las condiciones de carrera de ámbito global del módulo en macOS descritas en el informe. Se considera terminado cuando la creación del intérprete ya no informa de las condiciones de carrera identificadas ni se bloquea con el reproductor indicado; gh-156342 ya está enlazado como contexto.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- c, python
- Área
- desktop, operating-systems
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 35/100