You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PyOS_Readline drops GIL and calls PyOS_StdioReadline, which isn't thread safe #60946
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee='https://github.com/tpn'closed_at=<Date2013-10-10.14:19:38.937>created_at=<Date2012-12-21.10:39:50.350>labels= ['interpreter-core', 'type-bug']
title="PyOS_Readline drops GIL and calls PyOS_StdioReadline, which isn't thread safe"updated_at=<Date2013-10-19.11:34:40.896>user='https://github.com/tpn'
PyOS_StdioReadline features numerous calls that require the GIL to be held. Ideally, the GIL drop-take should be moved closer to the actual underlying read system call.
_PyOS_ReadlineTState=PyThreadState_GET();
/* CCP change, cannot release the GIL here because PyOS_StdioReadline uses * the regular MALLOC *//* Py_BEGIN_ALLOW_THREADS */#ifdefWITH_THREADPyThread_acquire_lock(_PyOS_ReadlineLock, 1);
#endif
/* This is needed to handle the unlikely case that the
* interpreter is in interactive mode *and* stdin/out are not
* a tty. This can happen, for example if python is run like
* this: python -i < test1.py
*/
if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
else
rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
prompt);
/*
Py_END_ALLOW_THREADS
*/
Basically, we just comment out the lock release since we don't need it. The reason we found this was that we were using GIL a custom mallocator which should have been run with the GIL but wasn´t.
I just found the readline/GIL issue while working on bpo-18203. I created bpo-18205 but then I found this issue. I just closed bpo-18205 as a duplicate. Here is a patch for Python 3.4.
The callback PyOS_ReadlineFunctionPointer (used to read a line from the standard input) must return a buffer allocated by PyMem_Malloc(), but PyOS_Readline() releases the GIL before calling PyOS_ReadlineFunctionPointer.
tok_nextc() calls PyOS_Readline() and calls PyMem_FREE() to release its result.
PyOS_ReadlineFunctionPointer should allocate memory using malloc(), not using PyMem_Malloc(). But PyOS_Readline() should copy the line into a buffer allocated by PyMem_Malloc() to keep backward compatibility.
Updated patch for the final API of bpo-3329. Update also the documentation. PyOS_ReadlineFunctionPointer must now use PyMem_RawMalloc() or PyMem_RawRealloc(), instead of PyMem_Malloc() or PyMem_Realloc().
Activity
tpn commentedon Dec 21, 2012
Relevant thread: http://mail.python.org/pipermail/python-dev/2012-December/123225.html
PyOS_StdioReadline features numerous calls that require the GIL to be held. Ideally, the GIL drop-take should be moved closer to the actual underlying read system call.
pitrou commentedon May 4, 2013
So, could you propose a patch?
kristjanvalur commentedon May 6, 2013
My quick and dirty fix is simple:
Basically, we just comment out the lock release since we don't need it. The reason we found this was that we were using GIL a custom mallocator which should have been run with the GIL but wasn´t.
vstinner commentedon Jun 13, 2013
I just found the readline/GIL issue while working on bpo-18203. I created bpo-18205 but then I found this issue. I just closed bpo-18205 as a duplicate. Here is a patch for Python 3.4.
--
Copy of the initial message (msg191089):
The callback PyOS_ReadlineFunctionPointer (used to read a line from the standard input) must return a buffer allocated by PyMem_Malloc(), but PyOS_Readline() releases the GIL before calling PyOS_ReadlineFunctionPointer.
Simplified extract of PyOS_Readline():
tok_nextc() calls PyOS_Readline() and calls PyMem_FREE() to release its result.
PyOS_ReadlineFunctionPointer should allocate memory using malloc(), not using PyMem_Malloc(). But PyOS_Readline() should copy the line into a buffer allocated by PyMem_Malloc() to keep backward compatibility.
See also issue bpo-18203 and bpo-3329.
vstinner commentedon Jun 13, 2013
See the following thread on python-dev, the root problem is that PyMem_Malloc() cannot be called with the GIL held. This is a bug in my opinion, and it should be fixed.
http://mail.python.org/pipermail/python-dev/2013-June/126822.html
vstinner commentedon Jun 15, 2013
Updated patch for the final API of bpo-3329. Update also the documentation. PyOS_ReadlineFunctionPointer must now use PyMem_RawMalloc() or PyMem_RawRealloc(), instead of PyMem_Malloc() or PyMem_Realloc().
python-dev commentedon Oct 10, 2013
New changeset 98dbe677dfe7 by Victor Stinner in branch 'default':
Close bpo-16742: Fix misuse of memory allocations in PyOS_Readline()
http://hg.python.org/cpython/rev/98dbe677dfe7
python-dev commentedon Oct 19, 2013
New changeset 6c9050ad1afc by Victor Stinner in branch 'default':
Issue bpo-16742: My fix on PyOS_StdioReadline() was incomplete, PyMem_FREE() was
http://hg.python.org/cpython/rev/6c9050ad1afc
kristjanvalur commentedon Oct 19, 2013
Perhaps in debug builds the memory apis should verify consistency and matching useage.
vstinner commentedon Oct 19, 2013
Python does check usage of apis in debug mode. Memory allocation failure
are almost never checked. See my pyfailmalloc module for that.