Skip to content

Conversation

@StanFromIreland
Copy link
Member

@StanFromIreland StanFromIreland commented Oct 31, 2025

Comment on lines 2255 to 2257
if (_Py_IsMainInterpreter(tstate->interp)) {
Py_CLEAR(tstate->interp->audit_hooks);
}
Copy link
Member

Choose a reason for hiding this comment

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

Two things:

  1. This looks like valid per-interpreter state; why is it done only for the main interpreter?
  2. Clearing interpreter fields should generally happen in PyInterpreterState_Clear, not _Py_Finalize.

Copy link
Member

Choose a reason for hiding this comment

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

Also, why are we clearing it after running a GC collection?

Copy link
Member Author

Choose a reason for hiding this comment

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

Clearing interpreter fields should generally happen in PyInterpreterState_Clear, not _Py_Finalize.

It is too late then, once the module is destroyed it leaks.

Copy link
Member

Choose a reason for hiding this comment

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

I don't follow. A module object should clear all references it owns before it's destroyed. Even if it isn't, Py_CLEAR on its own shouldn't fix that.

Can you walk me through the leak to help me understand what's going on?

Copy link
Member Author

@StanFromIreland StanFromIreland Nov 1, 2025

Choose a reason for hiding this comment

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

In the original repro, interp->audit_hooks holds references to the hook, hook, which seems to prevent time.struct_time's deallocation by the GC when the module is destroyed.

StanFromIreland

This comment was marked as off-topic.

@StanFromIreland

This comment was marked as off-topic.

Copy link
Member

@ZeroIntensity ZeroIntensity left a comment

Choose a reason for hiding this comment

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

This doesn't seem like the right fix. See this comment on a similar issue; rearranging Py_CLEAR calls will probably lead to other issues.

As far as I can tell, the leak here comes from the fact that the audit hook isn't in the last generation when calling _PyGC_CollectNoFail for the last time. That can be solved by adding an extra garbage collection in PyInterpreterState_Clear, but that doesn't address the case for when a finalizer installs new audit hooks after we've already cleared them.

@bedevere-app
Copy link

bedevere-app bot commented Nov 1, 2025

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@StanFromIreland
Copy link
Member Author

I see, as such I will close.

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.

3 participants