-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Running atexit
from threads in free-threading build segfaults
#126907
Comments
Please also post the stack trace preferably with a debug build for ease with crashers. |
At a glance, |
Sorry, will do from now on. I get this backtrace for a slightly modified code (because original code wasn't triggering under gdb): #0 atexit_delete_cb (state=state@entry=0x555555cfd8f8 <_PyRuntime+140088>, i=i@entry=0)
at ./Modules/atexitmodule.c:58
#1 0x000055555598d962 in atexit_cleanup (state=0x555555cfd8f8 <_PyRuntime+140088>)
at ./Modules/atexitmodule.c:75
#2 0x000055555598d9b6 in atexit_clear (module=<optimized out>, unused=<optimized out>)
at ./Modules/atexitmodule.c:249
#3 0x0000555555702405 in cfunction_vectorcall_NOARGS (
func=<built-in method _clear of module object at remote 0x200007752c0>, args=<optimized out>,
nargsf=<optimized out>, kwnames=<optimized out>) at Objects/methodobject.c:495
#4 0x000055555567cc55 in _PyObject_VectorcallTstate (tstate=0x555555dc8fe0,
callable=<built-in method _clear of module object at remote 0x200007752c0>, args=0x7ffff7c42b48,
nargsf=9223372036854775808, kwnames=0x0) at ./Include/internal/pycore_call.h:167
#5 0x000055555567cd74 in PyObject_Vectorcall (
callable=callable@entry=<built-in method _clear of module object at remote 0x200007752c0>,
args=args@entry=0x7ffff7c42b48, nargsf=<optimized out>, kwnames=kwnames@entry=0x0)
at Objects/call.c:327
#6 0x00005555558441f7 in _PyEval_EvalFrameDefault (tstate=tstate@entry=0x555555dc8fe0,
frame=<optimized out>, throwflag=throwflag@entry=0) at Python/generated_cases.c.h:955
#7 0x0000555555872978 in _PyEval_EvalFrame (throwflag=0, frame=<optimized out>, tstate=0x555555dc8fe0)
at ./Include/internal/pycore_ceval.h:116
#8 _PyEval_Vector (tstate=<optimized out>, func=0x20000a8b530, locals=locals@entry=0x0,
args=0x7ffff7c42cd8, argcount=1, kwnames=<optimized out>) at Python/ceval.c:1901
#9 0x000055555567c622 in _PyFunction_Vectorcall (func=<optimized out>, stack=<optimized out>,
nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:413
#10 0x00005555556816b4 in _PyObject_VectorcallTstate (kwnames=0x0, nargsf=1, args=0x7ffff7c42cd8,
callable=<function at remote 0x20000a8b530>, tstate=0x555555dc8fe0)
at ./Include/internal/pycore_call.h:167 Code that caused it: from threading import Thread
import atexit
def g():
pass
def f():
for x in range(100):
atexit.register(g)
atexit._clear()
atexit.register(g)
atexit.unregister(g)
atexit._run_exitfuncs()
for x in range(100):
Thread(target=f, args=()).start() Also possible to get this error message:
In that case the backtrace is: #0 0x000055555570fa78 in _PyObject_DebugDumpAddress (p=p@entry=0x20002110f90) at Objects/obmalloc.c:3016
#1 0x000055555570fde6 in _PyMem_DebugCheckAddress (
func=func@entry=0x555555a6c860 <__func__.8> "_PyMem_DebugRawFree", api=<optimized out>,
p=p@entry=0x20002110f90) at Objects/obmalloc.c:2956
#2 0x000055555571390a in _PyMem_DebugRawFree (ctx=ctx@entry=0x555555cdb928 <_PyRuntime+872>,
p=p@entry=0x20002110f90) at Objects/obmalloc.c:2762
#3 0x0000555555713986 in _PyMem_DebugFree (ctx=0x555555cdb928 <_PyRuntime+872>, ptr=0x20002110f90)
at Objects/obmalloc.c:2904
#4 0x000055555572c740 in PyMem_Free (ptr=ptr@entry=0x20002110f90) at Objects/obmalloc.c:1018
#5 0x000055555598d93c in atexit_delete_cb (state=state@entry=0x555555cfd8f8 <_PyRuntime+140088>,
i=i@entry=1) at ./Modules/atexitmodule.c:61
#6 0x000055555598dc94 in atexit_unregister (module=<optimized out>,
func=<function at remote 0x20000a8dbb0>) at ./Modules/atexitmodule.c:291
#7 0x00005555557021ef in cfunction_vectorcall_O (
func=<built-in method unregister of module object at remote 0x200007752c0>, args=<optimized out>,
nargsf=<optimized out>, kwnames=<optimized out>) at Objects/methodobject.c:523
#8 0x000055555567cc55 in _PyObject_VectorcallTstate (tstate=0x555555dc8fe0,
callable=<built-in method unregister of module object at remote 0x200007752c0>, args=0x7ffff642fb48,
nargsf=9223372036854775809, kwnames=0x0) at ./Include/internal/pycore_call.h:167
#9 0x000055555567cd74 in PyObject_Vectorcall (
callable=callable@entry=<built-in method unregister of module object at remote 0x200007752c0>,
args=args@entry=0x7ffff642fb48, nargsf=<optimized out>, kwnames=kwnames@entry=0x0)
at Objects/call.c:327
#10 0x00005555558441f7 in _PyEval_EvalFrameDefault (tstate=tstate@entry=0x555555dc8fe0,
frame=<optimized out>, throwflag=throwflag@entry=0) at Python/generated_cases.c.h:955
#11 0x0000555555872978 in _PyEval_EvalFrame (throwflag=0, frame=<optimized out>, tstate=0x555555dc8fe0)
at ./Include/internal/pycore_ceval.h:116 |
Eh, stack traces are generally not that helpful on the free-threaded build (mimalloc screws up most error messages), especially in a data race. |
Crash report
What happened?
It's possible to segfault or abort a no-gil interpreter running with
PYTHON_GIL=0
by callingatexit
functions from threads:Found using fusil by @vstinner.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
Python 3.14.0a1+ experimental free-threading build (heads/main-dirty:612ac283b81, Nov 16 2024, 01:37:56) [GCC 11.4.0]
Linked PRs
atexit
state on the free-threaded build #126908The text was updated successfully, but these errors were encountered: