-
Notifications
You must be signed in to change notification settings - Fork 332
Greening existing locks doesn't always work right #864
Copy link
Copy link
Closed
Description
Following abbe7a5 (though I feel bad -- the problem seems most likely to be in code I wrote in an earlier version of #754), monkey-patching sometimes leaves lock references as empty dicts (??)
Given a simple repro script like
import unittest.mock
import eventlet
import sys
print(f'{sys.version.split()[0]=}, {eventlet.__version__=}')
print(f'{unittest.mock.NonCallableMock._lock=}')
eventlet.monkey_patch(thread=True)
print(f'{unittest.mock.NonCallableMock._lock=}')(Note that unittest.mock.NonCallableMock._lock only exists for python>=3.10.9,!=3.11.0; see python/cpython#98624 for some background.)
I get output like
sys.version.split()[0]='3.10.12', eventlet.__version__='0.34.2'
unittest.mock.NonCallableMock._lock=<unlocked _thread.RLock object owner=0 count=0 at 0x7fac882f5b00>
unittest.mock.NonCallableMock._lock={}
Segmentation fault (core dumped)
The segfault seems like a give-away that something is amiss; trying again with -X dev and gdb attached, it either continues to segfault during garbage collection:
sys.version.split()[0]='3.10.12', eventlet.__version__='0.34.2'
unittest.mock.NonCallableMock._lock=<unlocked _thread.RLock object owner=0 count=0 at 0x7ffff6c416d0>
unittest.mock.NonCallableMock._lock={}
Program received signal SIGSEGV, Segmentation fault.
0x000055555567d7eb in gc_list_remove (node=0x7ffff6c416c0) at ../Modules/gcmodule.c:273
273 ../Modules/gcmodule.c: No such file or directory.
(gdb) #0 0x000055555567d7eb in gc_list_remove (node=0x7ffff6c416c0) at ../Modules/gcmodule.c:273
#1 PyObject_GC_Del (op=0x7ffff6c416d0) at ../Modules/gcmodule.c:2369
#2 0x0000555555736bb8 in _PyDict_ClearFreeList (interp=0x555555b3e260) at ../Objects/dictobject.c:269
#3 0x000055555567e328 in clear_freelists (interp=0x555555b3e260) at ../Modules/gcmodule.c:1045
#4 gc_collect_main (tstate=0x555555b5a130, generation=2, n_collected=0x7fffffffe148, n_uncollectable=0x7fffffffe140, nofail=0) at ../Modules/gcmodule.c:1326
#5 0x0000555555785470 in gc_collect_with_callback (tstate=0x555555b5a130, generation=2) at ../Modules/gcmodule.c:1413
#6 0x00005555557b6aae in PyGC_Collect () at ../Modules/gcmodule.c:2099
#7 0x00005555557b44c0 in Py_FinalizeEx () at ../Python/pylifecycle.c:1781
#8 0x00005555557a5913 in Py_RunMain () at ../Modules/main.c:668
#9 0x000055555577c02d in Py_BytesMain (argc=<optimized out>, argv=<optimized out>) at ../Modules/main.c:720
(More stack frames follow...)
Or bombs our trying to get the repr for the last print:
sys.version.split()[0]='3.10.12', eventlet.__version__='0.34.2'
unittest.mock.NonCallableMock._lock=<unlocked _thread.RLock object owner=0 count=0 at 0x7ffff6c416d0>
Program received signal SIGSEGV, Segmentation fault.
type_getattro (type=<optimized out>, name=<optimized out>) at ../Objects/typeobject.c:3936
3936 ../Objects/typeobject.c: No such file or directory.
(gdb) #0 type_getattro (type=<optimized out>, name=<optimized out>) at ../Objects/typeobject.c:3936
#1 0x00005555556aae5a in PyObject_GetAttr (v=<type at remote 0x555555d8b950>, name='_lock') at ../Objects/object.c:932
#2 0x000055555569c971 in _PyEval_EvalFrameDefault (tstate=<optimized out>, f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3592
#3 0x00005555556939c6 in _PyEval_EvalFrame (throwflag=0, f=Frame 0x555555bbe060, for file /home/tburke/repro.py, line 8, in <module> (), tstate=0x555555b5a130)
at ../Include/internal/pycore_ceval.h:46
#4 _PyEval_Vector (tstate=0x555555b5a130, con=<optimized out>, locals=<optimized out>, args=<optimized out>, argcount=<optimized out>, kwnames=<optimized out>) at ../Python/ceval.c:5067
#5 0x0000555555789256 in PyEval_EvalCode (co=<code at remote 0x7ffff7798ee0>,
globals={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/tburke/repro.py') at remote 0x7ffff777e710>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7914290>, '__file__': '/home/tburke/repro.py', '__cached__': None, 'unittest': <module at remote 0x7ffff765f710>, 'eventlet': <module at remote 0x7ffff765f3b0>, 'sys': <module at remote 0x7ffff78f35f0>}, locals=<optimized out>) at ../Python/ceval.c:1134
#6 0x00005555557b4108 in run_eval_code_obj (tstate=0x555555b5a130, co=0x7ffff7798ee0,
globals={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/tburke/repro.py') at remote 0x7ffff777e710>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7914290>, '__file__': '/home/tburke/repro.py', '__cached__': None, 'unittest': <module at remote 0x7ffff765f710>, 'eventlet': <module at remote 0x7ffff765f3b0>, 'sys': <module at remote 0x7ffff78f35f0>},
locals={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/tburke/repro.py') at remote 0x7ffff777e710>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7914290>, '__file__': '/home/tburke/repro.py', '__cached__': None, 'unittest': <module at remote 0x7ffff765f710>, 'eventlet': <module at remote 0x7ffff765f3b0>, 'sys': <module at remote 0x7ffff78f35f0>}) at ../Python/pythonrun.c:1291
#7 0x00005555557ad9cb in run_mod (mod=<optimized out>, filename=<optimized out>,
globals={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/tburke/repro.py') at remote 0x7ffff777e710>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7914290>, '__file__': '/home/tburke/repro.py', '__cached__': None, 'unittest': <module at remote 0x7ffff765f710>, 'eventlet': <module at remote 0x7ffff765f3b0>, 'sys': <module at remote 0x7ffff78f35f0>},
locals={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/tburke/repro.py') at remote 0x7ffff777e710>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7914290>, '__file__': '/home/tburke/repro.py', '__cached__': None, 'unittest': <module at remote 0x7ffff765f710>, 'eventlet': <module at remote 0x7ffff765f3b0>, 'sys': <module at remote 0x7ffff78f35f0>}, flags=<optimized out>, arena=<optimized out>) at ../Python/pythonrun.c:1312
#8 0x00005555557b3e55 in pyrun_file (fp=fp@entry=0x555555b69280, filename=filename@entry='/home/tburke/repro.py', start=start@entry=257,
globals=globals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/tburke/repro.py') at remote 0x7ffff777e710>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7914290>, '__file__': '/home/tburke/repro.py', '__cached__': None, 'unittest': <module at remote 0x7ffff765f710>, 'eventlet': <module at remote 0x7ffff765f3b0>, 'sys': <module at remote 0x7ffff78f35f0>},
locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/tburke/repro.py') at remote 0x7ffff777e710>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7914290>, '__file__': '/home/tburke/repro.py', '__cached__': None, 'unittest': <module at remote 0x7ffff765f710>, 'eventlet': <module at remote 0x7ffff765f3b0>, 'sys': <module at remote 0x7ffff78f35f0>}, closeit=closeit@entry=1, flags=0x7fffffffe218)
at ../Python/pythonrun.c:1208
#9 0x00005555557b3338 in _PyRun_SimpleFileObject (fp=0x555555b69280, filename='/home/tburke/repro.py', closeit=1, flags=0x7fffffffe218) at ../Python/pythonrun.c:456
(More stack frames follow...)
FWIW, I see similar trouble with python 3.12.1.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels