Commit 5562097
committed
gh-149146: Add dealloc-depth counter fallback to trashcan trigger
Under memory pressure (for example RLIMIT_AS), Python's trashcan trigger
in _Py_Dealloc never fires. The trigger relies on
_Py_RecursionLimit_GetMargin, which compares the machine stack pointer
against c_stack_soft_limit. When RLIMIT_AS prevents the kernel from
growing the C stack, the kernel SIGSEGVs while the stack pointer is
still megabytes above the soft limit (see sibling issue gh-150722 for
an LLDB trace showing SP ~7.2 MB above c_stack_hard_limit at the
SIGSEGV), so the trashcan never deposits and the recursive tuple_dealloc
chain runs out the stack.
Add a per-thread c_dealloc_depth counter as a fallback trigger,
mirroring the historical _PyTrash_UNWIND_LEVEL=50 protection that was
removed when the trashcan was consolidated into _Py_Dealloc.
_Py_RecursionLimit_GetMargin remains the primary signal; the counter
only kicks in when the stack-pointer signal cannot fire.
_PyTrash_thread_destroy_chain itself bumps c_dealloc_depth for the
duration of the drain so any _Py_Dealloc invoked while draining cannot
recursively re-enter destroy_chain (which would rebuild the same
unbounded recursion the trashcan exists to prevent). This mirrors the
historical delete_nesting bookkeeping.
The counter is per-tstate (no atomics needed in the free-threaded
build) and is only touched for GC types, so non-GC types pay zero
overhead.
Add a regression test in test_gc that builds a 100,000-deep
(b, None) tuple chain and asserts that ``del b`` cleans it up
without a C-stack overflow.1 parent 11f032f commit 5562097
5 files changed
Lines changed: 61 additions & 2 deletions
File tree
- Include/cpython
- Lib/test
- Misc/NEWS.d/next/Core_and_Builtins
- Objects
- Python
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
177 | 177 | | |
178 | 178 | | |
179 | 179 | | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
180 | 188 | | |
181 | 189 | | |
182 | 190 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
468 | 468 | | |
469 | 469 | | |
470 | 470 | | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
471 | 484 | | |
472 | 485 | | |
473 | 486 | | |
| |||
Lines changed: 6 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3201 | 3201 | | |
3202 | 3202 | | |
3203 | 3203 | | |
| 3204 | + | |
| 3205 | + | |
| 3206 | + | |
| 3207 | + | |
| 3208 | + | |
3204 | 3209 | | |
3205 | 3210 | | |
3206 | 3211 | | |
| |||
3226 | 3231 | | |
3227 | 3232 | | |
3228 | 3233 | | |
| 3234 | + | |
3229 | 3235 | | |
3230 | 3236 | | |
3231 | 3237 | | |
| |||
3286 | 3292 | | |
3287 | 3293 | | |
3288 | 3294 | | |
| 3295 | + | |
| 3296 | + | |
| 3297 | + | |
| 3298 | + | |
| 3299 | + | |
| 3300 | + | |
| 3301 | + | |
| 3302 | + | |
| 3303 | + | |
| 3304 | + | |
| 3305 | + | |
| 3306 | + | |
| 3307 | + | |
3289 | 3308 | | |
3290 | 3309 | | |
3291 | 3310 | | |
| |||
3294 | 3313 | | |
3295 | 3314 | | |
3296 | 3315 | | |
3297 | | - | |
| 3316 | + | |
| 3317 | + | |
3298 | 3318 | | |
3299 | 3319 | | |
3300 | 3320 | | |
| 3321 | + | |
| 3322 | + | |
| 3323 | + | |
3301 | 3324 | | |
3302 | 3325 | | |
3303 | 3326 | | |
| |||
3340 | 3363 | | |
3341 | 3364 | | |
3342 | 3365 | | |
3343 | | - | |
| 3366 | + | |
| 3367 | + | |
| 3368 | + | |
| 3369 | + | |
| 3370 | + | |
| 3371 | + | |
| 3372 | + | |
| 3373 | + | |
| 3374 | + | |
3344 | 3375 | | |
3345 | 3376 | | |
3346 | 3377 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1628 | 1628 | | |
1629 | 1629 | | |
1630 | 1630 | | |
| 1631 | + | |
1631 | 1632 | | |
1632 | 1633 | | |
1633 | 1634 | | |
| |||
0 commit comments