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
Looking at the stack trace, it's pretty clear the crash comes from close_output (definition). What's happening isn't obvious though.
Looking further into it, I think what is happening is the following:
When OutputContainer gets GC'd, the Python reference to self.file is dropped
Dropping that reference reference frees the PyIOFile which in turns call av_freep(&self.iocontext)
Dropping the reference also triggers close_output
close_output checks whether self.file is None. The thing is that, at this point it isNone (as it was cleared by tp_clear) so it calls avio_closep(&self.ptr.pb)
avio_closep(&self.ptr.pb) actually has already been called before -- by av_freep(&self.iocontext), which makes the whole thing crash.
I believe the reason why things are done this way is that self.file is None can also mean "the file was opened with avio_open / with a path", but it conflicts with what tp_clear does.
The proposed fix is to add a new bint _avio_opened attribute which will not be cleared (as opposed to a Python object reference/pointer) so the deallocator can just look at this to make the call of whether it should call avio_closep.
avio_closep(&self.ptr.pb) actually has already been called before -- by av_freep(&self.iocontext), which makes the whole thing crash.
I'm calling AI slop, see #2202. av_freep does not call avio_closep(). Sure, it points to the same memory, but a human expect would make this distinction.
I think this does point to a real issue, so the human directing this is welcome to continue contributing to the project. self.file is None does feel a little fishy here. However, this approach feels dubious and a bit brittle. I'm not elaborating further.
Thanks for reviewing quickly. I plead guilty, I used LLMs for investigating and although the fix was not LLM made, it clearly was mostly guided by it. Sorry for posting that without digging further prior to doing it.
I also do believe that the issue is real as I’ve seen it happen several times, which is why I wanted to try and fix it.
So I’ll have another take at it when I get a chance (in the next few days). I’ll let you know what I find myself :)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is this PR?
This PR is an attempt to fix a crash I have been seeing in some of my code, where the service crashes with the following stack trace.
Looking at the stack trace, it's pretty clear the crash comes from
close_output(definition). What's happening isn't obvious though.Looking further into it, I think what is happening is the following:
OutputContainergets GC'd, the Python reference toself.fileis droppedPyIOFilewhich in turns callav_freep(&self.iocontext)close_outputclose_outputchecks whetherself.file is None. The thing is that, at this point it isNone(as it was cleared bytp_clear) so it callsavio_closep(&self.ptr.pb)avio_closep(&self.ptr.pb)actually has already been called before -- byav_freep(&self.iocontext), which makes the whole thing crash.I believe the reason why things are done this way is that
self.file is Nonecan also mean "the file was opened withavio_open/ with a path", but it conflicts with whattp_cleardoes.The proposed fix is to add a new
bint _avio_openedattribute which will not be cleared (as opposed to a Python object reference/pointer) so the deallocator can just look at this to make the call of whether it should callavio_closep.