gh-122306: Fix circular reference issue between MemoryView and PickleBuffer during garbage collection#123400
Conversation
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
8b19468 to
f63d798
Compare
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
1 similar comment
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
encukou
left a comment
There was a problem hiding this comment.
I also don't know a good way to fix this, but a leak with an unraisable error message is better than a crash.
I plan to merge in about a week if there are no objections.
|
This change needs a test. I am not sure that this is a right solution, but the test will help us to decide. |
It's really hard to trigger the crash using just def test_circular_reference_gc(self):
mv = memoryview(b"foobar")
error = None
unraisable_exception = None
def custom_unraisablehook(unraisable):
nonlocal unraisable_exception
unraisable_exception = unraisable
def func():
try:
pb = pickle.PickleBuffer(mv)
raise CustomError
except CustomError as e:
# Ensure `error` references the exception
error = e
func()
del mv
prev_unraisablehook = sys.unraisablehook
sys.unraisablehook = custom_unraisablehook
support.gc_collect()
self.assertEqual(unraisable_exception.exc_type, BufferError)
self.assertIsInstance(unraisable_exception.exc_value, BufferError)
self.assertEqual(str(unraisable_exception.exc_value), 'memoryview has 1 exported buffer')
sys.unraisablehook = prev_unraisablehook |
Co-authored-by: Victor Stinner <[email protected]>
f1c9f77 to
7fe3839
Compare
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
#123898 uses a different solution. Trying to break a reference loop is a normal situation, it should not produce error reports (the user cannot do anything about this in any case), so |
Issues
Main Causes
gc.collect()3Next
I have no idea if this is a good way to fix this.But thank for any dev who reviewed this PR.