-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
gh-129289: fix subclass of asyncio.Task not propagating __del__() cau… #129804
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
Conversation
…() causes segfault
| if (PyErr_WarnEx(PyExc_Warning, "subclasses of asyncio.Task must propagate __del__()", 1) < 0) { | ||
| PyErr_Clear(); | ||
| } | ||
| _PyObject_ResurrectStart(self); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you want to do it like this. You probably want PyObject_CallFinalizerFromDealloc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look above, this only happens if PyObject_CallFinalizerFromDealloc executes but the Task.__del__() was not called, so this needs to do this stuff which normally happens in PyObject_CallFinalizerFromDealloc but explicitly. Agree is not cleanest, but did not see better option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah wait, I didn't see that it's already called before, but manually trying to resurrect like this seems error-prone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd lean towards just emitting the warning, and then refactoring as needed to prevent a crash if the finalizer wasn't called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As said, agreed is a bit hacky, though is used in a few other places (codeobject, dictobject, funcobject). Currently the alternative is segfault in this case so your call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, and I'd also expect strings to do this as well--but that's not the point. Those are all core interpreter types, asyncio.Task isn't. I'll let @kumaraditya303 make the call here, but IMO, types should always behave in a sane way when both finalized and non-finalized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the record, a simpler way to prevent the segfault without needing to resurrect and call the finalizer would be to just remove the task from the linked list. This has the drawback of not calling callbacks but is a less messy way to keep going. Would you prefer this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a better fix in works, I'll post in sometime.
Its been a bit and I didn't see anyone pick this up, so at least fix the segfault in this case.