Skip to content
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

gh-94673: Always Finalize Static Builtin Types #95153

Conversation

ericsnowcurrently
Copy link
Member

@ericsnowcurrently ericsnowcurrently commented Jul 22, 2022

Static builtin types are finalized by calling _PyStaticType_Dealloc(). Currently we skip finalizing such a type if it still has subtypes (i.e. its tp_subclasses hasn't been cleared yet). The problem is that static builtin types hold several heap objects, which leak if we skip the type's finalization. This PR addresses that.

For context, there's an old comment that says the following:

// If a type still has subtypes, it cannot be deallocated.
// A subtype can inherit attributes and methods of its parent type,
// and a type must no longer be used once it's deallocated.

However, it isn't clear that is actually still true. Clearing tp_dict should mean it isn't a problem.

Furthermore, the only subtypes that might still be around come from extension modules that didn't clean them up when unloaded (i.e. extensions that do not implement multi-phase initialization, AKA PEP 489). Those objects are already leaking, so this PR doesn't change anything in that regard. Instead, this change means more objects gets cleaned up that before.

@ericsnowcurrently
Copy link
Member Author

@vstinner, you introduced the original skipping logic that I'm basically removing. Are there any problems with the approach I'm taking?

@ericsnowcurrently
Copy link
Member Author

This was split out of #94995.

@ericsnowcurrently ericsnowcurrently added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Jul 22, 2022
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @ericsnowcurrently for commit 74d5af3 🤖

If you want to schedule another build, you need to add the ":hammer: test-with-buildbots" label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Jul 22, 2022
@kumaraditya303
Copy link
Contributor

kumaraditya303 commented Jul 23, 2022

you introduced the original skipping logic that I'm basically removing. Are there any problems with the approach I'm taking?

Hmm, this would affected extension modules which store PyTypeObject in static global if the interpreter is initialized multiple times and the extension does not initializes it's static type via PyType_Ready when it is (re)imported. Such extensions modules are already unsafe in multiple initialization scenario so there should be no impact.

Copy link
Contributor

@kumaraditya303 kumaraditya303 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
@ericsnowcurrently ericsnowcurrently merged commit 2d26449 into python:main Jul 25, 2022
@ericsnowcurrently ericsnowcurrently deleted the always-finalize-static-builtin-standalone branch July 25, 2022 20:23
@vstinner
Copy link
Member

vstinner commented Aug 3, 2022

However, it isn't clear that is actually still true. Clearing tp_dict should mean it isn't a problem.

I skipped type deallocation if they have sub-types to prevent crashes. I don't recall the details.

I got issues with subclasses: https://bugs.python.org/issue46417#msg411122 I fixed this issue with: 8ee07dd

It's a complicated issue: https://bugs.python.org/issue46417#msg411304

See also #84258

@vstinner
Copy link
Member

vstinner commented Aug 3, 2022

Are there any problems with the approach I'm taking?

If Python is initialized multiple times (Py_Initialize + Py_Finalize called multiple times), a sub-type may try to get data from its parent static type which has been cleared. If the static type is not properly initialized, Python can crash. If the heap type is used during the finalization after the static type has been cleared, Python can crash.

Again, I don't recall the details. I don't know the crashes that I got.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants