-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
iostream: Fix unreleased memoryview #2008
Conversation
memoryview should be released explicitly. Otherwise, a bytearray holded by the memoryview is not resizable until GC. See also: https://bugs.python.org/issue29178
I think you don't need the second nested with memoryview(self._read_buffer) as m:
b = m[self._read_buffer_pos:self._read_buffer_pos + loc].tobytes() |
Even I don't keep reference, temporary memoryview may be created and closed lazily in Python 3 |
FYI:
|
The |
@bdarnell You're right. How do you think using temporal bytearray like I described above? When reading MBs of data, avoiding temporal copy is nice. |
CC @pitrou who originally wrote the code here that's using Hmm, if this analysis is accurate, it makes
|
My suggestion was based on this comment in the bug discussion: https://bugs.python.org/issue29178#msg284837 ... on a second reading of that it looks like the |
@methane, is it a theoretical concern or did you actually get an error in the wild (using PyPy perhaps)? CPython is reference-counted so the memoryview is immediately collected after it gets out of scope... |
Tracebacks keep references to local variables. The memoryview there is not bound to a local variable, so it shouldn't be kept alive by the traceback. |
@pitrou When I create this pull request, I think it will be real problem at PyPy. But as I said:
I haven't tried micropython yet. Jython, IronPython and Piston are Python 2.7 yet. On the other hand, |
There's no local variable in that line, but the |
I've tried to reproduce the write error, but I'm unable to. Any error that escapes from On a closer read of the SO question, I think the poster is probably using threads incorrectly in a way that is manifesting in a variety of unexpected errors. So maybe there's nothing to be done here after all. The only python implementations we currently support are cpython and pypy. Pypy doesn't have this error at all, and cpython's refcounting appears to make this naive use of |
OK, let's leave it for now. |
I think I may have stumbled on something related to this:
|
The above is using tornado 4.5.1 |
@s0undt3ch Can you point to the code that's running here? Are you doing anything with threads? Our (my) working theory for this issue is that it has something to do with improper use of threads, but if you've found a way it can happen without threads then we'd be interested in learning more. |
@bdarnell if running a loop in its own thread and using You might ask, why am I running the loop in its own thread, or, why ain't I using If you see any way that I can improve that code and specifically stop running into those exceptions, please let me know since learning is always a pleasant experience to me even when proving me wrong. |
@s0undt3ch The errors in the comments of that gist appear to stem from a confusion of Other than that, the code looks correct in its handling of the IOLoop across threads. I don't quite see why you can't use As for the |
stackimpact/stackimpact-python#1 has identified a non-threading-related scenario in which this error can occur: a signal handler (especially one that calls |
seeing the same
|
@lucasts Are you doing anything with threads or signals? Is the newrelic package? (Monitoring packages are likely candidates for using signals in a way that breaks here, as we saw with stackimpact, but grepping the newrelic code I can find doesn't appear to be doing anything like that) In any case, signal-based monitoring tools are useful enough that we should probably do something to fix this: either introduce the necessary |
Adding |
IOW, I'd really like to see a small reproducer. @lucasts |
See tornadoweb#2008 for reasons why this might be necessary.
Ok, I've got a reproducer: |
D'oh, I was relying on my earlier comment #2008 (comment) Was this exception present in python 2? If so, was relying on destruction order the only way to avoid it? If not, were operations involving memoryviews simply unsafe?
|
Do you mean the
Hmm, I see. Let me try... |
Indeed, it works. I'll open an alternative PR for that. |
See tornadoweb#2008 for reasons why this might be necessary.
See #2008 for reasons why this might be necessary.
Yes, we believe #2173 will fix the problem. |
See tornadoweb#2008 for reasons why this might be necessary.
See tornadoweb#2008 for reasons why this might be necessary.
I'm still seeing a similar error using 4.5.3 in Python 2.7.
|
@jeffreydwalter Interesting. I don't think we've seen that AssertionError fire before. (It makes me think about thread-safety issues - are you possibly accessing the IOStream from multiple threads?) Please open a new issue with more details about what you're doing instead of commenting on this closed one. |
This contains the fix for tornadoweb/tornado#2008, which I recently encountered.
I am seeing the exact same AssertionError as @jeffreydwalter with python 3.6 and tornado 4.5.3. It only happens when I am updating the document (from a callback called from another thread via |
@aayla-secura my issue turned out to be me opening threads inside the on_message() callback. |
@aayla-secura I don't know if it'll help you, but here's the issue that I filed in relation to my problem #2271 |
@jeffreydwalter I don't think that is my problem here, but it was my incorrect using of threads. I'm still not sure why updating the document via
is given in the manual, so that's my bad for not heeding to it. |
I see this issue has been closed. But I am seeing the same error on 4.5.3 with python2. I have a consistent repro. This is the line of code that throws the error: |
Every known occurrence of this has been related to incorrect use of threads. If you're seeing this without threads, please file a new issue with details. |
definitely will do. thanks for a quick response. |
memoryview should be released explicitly. Otherwise, a bytearray
holded by the memoryview is not resizable until GC.
See also: https://bugs.python.org/issue29178