Skip to content

bpo-44897: WIP: Integrate trashcan into _Py_Dealloc #27738

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

Closed
wants to merge 5 commits into from

Conversation

nascheme
Copy link
Member

@nascheme nascheme commented Aug 12, 2021

This is a WIP/proof-of-concept of doing away with Py_TRASHCAN_BEGIN and
Py_TRASHCAN_END and instead integrating the functionality into
_Py_Dealloc. There are a few advantages:

  • all container objects have the risk of overflowing the C stack if a
    long reference chain of them is created and then deallocated. So, to
    be safe, the tp_dealloc methods for those objects should be protected
    from overflowing the stack.

  • the Py_TRASHCAN_BEGIN and Py_TRASHCAN_END macros are hard to
    understand and a bit hard to use correctly. Making the mechanism
    internal avoids confusion. The code can be slightly simplified as
    well.

This proof-of-concept seems to pass tests but it will need some careful
review. The exact rules related to calling GC Track/Untrack are subtle
and this changes things a bit. I.e. tp_dealloc is called with GC
objects already untracked. For 3rd party extensions, they are calling
PyObject_GC_UnTrack() and so I believe they should still work.

The fact that PyObject_CallFinalizerFromDealloc() wants GC objects to
definitely be tracked is a bit of a mystery to me (there is an assert to
check that). I changed the code to track objects if they are not
already tracked but I'm not sure that's correct.

There could be a performance hit, due to the _PyType_IS_GC() test that
was added to the _Py_Dealloc() function. For non-GC objects, that's
going to be a new branch and I'm worried it might hurt a bit. OTOH,
maybe it's just in the noise. Profiling will need to be done.

https://bugs.python.org/issue44897

This is a WIP/proof-of-concept of doing away with Py_TRASHCAN_BEGIN and
Py_TRASHCAN_END and instead integrating the functionality into
_Py_Dealloc.  There are a few advantages:

- all container objects have the risk of overflowing the C stack if a
  long reference chain of them is created and then deallocated.  So, to
  be safe, the tp_dealloc methods for those objects should be protected
  from overflowing the stack.

- the Py_TRASHCAN_BEGIN and Py_TRASHCAN_END macros are hard to
  understand and a bit hard to use correctly.  Making the mechanism
  internal avoids confusion.  The code can be slightly simplified as
  well.

This proof-of-concept seems to pass tests but it will need some careful
review.  The exact rules related to calling GC Track/Untrack are subtle
and this changes things a bit.  I.e. tp_dealloc is called with GC
objects already untracked.  For 3rd party extensions, they are calling
PyObject_GC_UnTrack() and so I believe they should still work.

The fact that PyObject_CallFinalizerFromDealloc() wants GC objects to
definitely be tracked is a bit of a mystery to me (there is an assert to
check that).  I changed the code to track objects if they are not
already tracked but I'm not sure that's correct.

There could be a performance hit, due to the _PyType_IS_GC() test that
was added to the _Py_Dealloc() function.  For non-GC objects, that's
going to be a new branch and I'm worried it might hurt a bit.  OTOH,
maybe it's just in the noise.  Profiling will need to be done.
Since _Py_Dealloc will untrack, don't need to do it in tp_dealloc.  If
an object is resurrected, PyObject_CallFinalizerFromDealloc() will do
the track call.
@nascheme nascheme requested review from tim-one and ctismer August 13, 2021 07:08
I'm not sure _PyType_IS_GC() is safe in case the object returns false
from tp_is_gc().
@github-actions
Copy link

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale Stale PR or inactive for long period of time. label Sep 16, 2021
@rhettinger rhettinger removed their request for review May 3, 2022 06:30
@github-actions github-actions bot removed the stale Stale PR or inactive for long period of time. label Aug 11, 2022
@nascheme
Copy link
Member Author

nascheme commented Apr 5, 2023

FYI, I believe this would have fixed GH-102356 and probably a lot of similar crashing bugs that have not yet been found. I would imagine most "container" (GC tracked) objects can be used to blow up the C stack on dealloc.

@serhiy-storchaka serhiy-storchaka marked this pull request as draft January 17, 2024 20:08
@nascheme
Copy link
Member Author

Since this PR is so out of date, I've created a new one: GH-124716

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.

None yet

4 participants