-
-
Notifications
You must be signed in to change notification settings - Fork 31k
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
Raising an exception raised in a "future" instance will create reference cycles #80111
Comments
Try this in a terminal: """ def a():
1/0
future=executor.submit(a)
future.result()
# An exception is raised here. That is normal
gc.set_debug(gc.DEBUG_SAVEALL)
gc.collect()
gc.garbage
""" You will see (python 3.7) that 23 objects are collected when cleaning the cycle. The problem is the attribute "future._exception". If the exception provided by the "future" is raised somewhere else, we will have reference cycles because we have the same exception/traceback in two different places in the traceback framestack. I commonly do this in my code: """ This approach will create reference cycles. They will eventually cleaned up, but I noticed this issue because the cycle clean up phase was touching big objects with many references but unused for a long time, so they were living in the SWAP. The cycle collection was hugely slow because of this and the interpreter is completely stopped until done. Not sure about what to do about this. I am currently doing something like: """ I am breaking the cycle manually. I do not use "future.set_exception(None) because side effects like notifying waiters. I think this is a bug to be solved. Not sure how to do it cleanly. What do you think? Ideas?. |
The corrected test case in the terminal: (a "del" was missing) """ def a():
1/0
future=executor.submit(a)
future.result()
# An exception is raised here. That is normal
del future # Variable vanish, but data is still there because the cycle
gc.set_debug(gc.DEBUG_SAVEALL)
gc.collect()
gc.garbage
""" |
Even more reproductible case, now 100%: """ def a():
1/0
future=executor.submit(a)
future.result()
# An exception is raised here. That is normal
del future # Variable vanish, but data is still there because the cycle
1/0 # Raises another exception drop references to the future one
gc.set_debug(gc.DEBUG_SAVEALL)
gc.collect()
gc.garbage
""" |
@jcea, I see you have created backports for 3.7 and 3.6 as well. Those release as in their security-fix-only phase of their life cycles. This doesn't seem like a security issue but am I missing something? |
"Those releases are in their" |
I retired the backporting request. Thanks, Ned. |
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:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: