Skip to content

segfault in gc with 3.14.0b1, trio and pytest #133932

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

Open
jakkdl opened this issue May 12, 2025 · 2 comments
Open

segfault in gc with 3.14.0b1, trio and pytest #133932

jakkdl opened this issue May 12, 2025 · 2 comments
Assignees
Labels
3.14 bugs and security fixes 3.15 new features, bugs and security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-crash A hard crash of the interpreter, possibly with a core dump

Comments

@jakkdl
Copy link

jakkdl commented May 12, 2025

Crash report

What happened?

I'm encountering a segfault during garbage collection since 3.14.0b1 (I have not been able to reproduce it on 3.14.0a6), and while I've so far been able to minify the repro somewhat it still requires both pytest and trio

import trio
from contextlib import suppress
import gc

def test_error_in_run_loop() -> None:
    # Blow stuff up real good to check we at least get a TrioInternalError
    async def main() -> None:
        task = trio.lowlevel.current_task()
        task._schedule_points = "hello!"  # type: ignore
        await trio.lowlevel.checkpoint()
    with suppress(trio.TrioInternalError):
        trio.run(main)
    gc.collect()
    gc.collect()  # removing this line makes the segfault disappear
$ tox -e repro_crash
===================================== test session starts =====================================
platform linux -- Python 3.14.0b1, pytest-8.3.5, pluggy-1.5.0
cachedir: .tox/crash/.pytest_cache
rootdir: /home/h/Git/trio/unbreak_314
configfile: pyproject.toml
collected 1 item                                                                              

Fatal Python error: Segmentation fault

Current thread 0x00007fc3244b0bc0 [pytest] (most recent call first):
  Garbage-collecting
  File "./foo.py", line 14 in test_error_in_run_loop
  File ".../site-packages/_pytest/python.py", line 159 in pytest_pyfunc_call
  File ".../site-packages/pluggy/_callers.py", line 103 in _multicall
  File ".../site-packages/pluggy/_manager.py", line 120 in _hookexec
  File ".../site-packages/pluggy/_hooks.py", line 513 in __call__
  File ".../site-packages/_pytest/python.py", line 1627 in runtest
  File ".../site-packages/_pytest/runner.py", line 174 in pytest_runtest_call
  File ".../site-packages/pluggy/_callers.py", line 103 in _multicall
  File ".../site-packages/pluggy/_manager.py", line 120 in _hookexec
  File ".../site-packages/pluggy/_hooks.py", line 513 in __call__
  File ".../site-packages/_pytest/runner.py", line 242 in <lambda>
  File ".../site-packages/_pytest/runner.py", line 341 in from_call
  File ".../site-packages/_pytest/runner.py", line 241 in call_and_report
  File ".../site-packages/_pytest/runner.py", line 132 in runtestprotocol
  File ".../site-packages/_pytest/runner.py", line 113 in pytest_runtest_protocol
  File ".../site-packages/pluggy/_callers.py", line 103 in _multicall
  File ".../site-packages/pluggy/_manager.py", line 120 in _hookexec
  File ".../site-packages/pluggy/_hooks.py", line 513 in __call__
  File ".../site-packages/_pytest/main.py", line 362 in pytest_runtestloop
  File ".../site-packages/pluggy/_callers.py", line 103 in _multicall
  File ".../site-packages/pluggy/_manager.py", line 120 in _hookexec
  File ".../site-packages/pluggy/_hooks.py", line 513 in __call__
  File ".../site-packages/_pytest/main.py", line 337 in _main
  File ".../site-packages/_pytest/main.py", line 283 in wrap_session
  File ".../site-packages/_pytest/main.py", line 330 in pytest_cmdline_main
  File ".../site-packages/pluggy/_callers.py", line 103 in _multicall
  File ".../site-packages/pluggy/_manager.py", line 120 in _hookexec
  File ".../site-packages/pluggy/_hooks.py", line 513 in __call__
  File ".../site-packages/_pytest/config/__init__.py", line 175 in main
  File ".../site-packages/_pytest/config/__init__.py", line 201 in console_main
  File "./.tox/crash/bin/pytest", line 10 in <module>

Current thread's C stack trace (most recent call first):
  Binary file "/usr/lib/libpython3.14.so.1.0", at _Py_DumpStack+0x4d [0x7fc324096a8d]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x2a778c [0x7fc3240a778c]
  Binary file "/usr/lib/libc.so.6", at +0x3dcd0 [0x7fc323c4bcd0]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x23a40a [0x7fc32403a40a]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0xd8d80 [0x7fc323ed8d80]
  Binary file "/usr/lib/libpython3.14.so.1.0", at _Py_Dealloc+0x75 [0x7fc323f21745]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x1436c1 [0x7fc323f436c1]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x143e65 [0x7fc323f43e65]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x2379db [0x7fc3240379db]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x237e6c [0x7fc324037e6c]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x2a4df8 [0x7fc3240a4df8]
  Binary file "/usr/lib/libpython3.14.so.1.0", at PyObject_Vectorcall+0x5d [0x7fc323ebbc4d]
  Binary file "/usr/lib/libpython3.14.so.1.0", at _PyEval_EvalFrameDefault+0x13ba [0x7fc323fef17a]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x201237 [0x7fc324001237]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0xbb926 [0x7fc323ebb926]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0xbbbc0 [0x7fc323ebbbc0]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x1437c9 [0x7fc323f437c9]
  Binary file "/usr/lib/libpython3.14.so.1.0", at _PyObject_MakeTpCall+0x9f [0x7fc323ebb52f]
  Binary file "/usr/lib/libpython3.14.so.1.0", at _PyEval_EvalFrameDefault+0x4bbf [0x7fc323ff297f]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x201237 [0x7fc324001237]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0xbb926 [0x7fc323ebb926]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0xbbbc0 [0x7fc323ebbbc0]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x1437c9 [0x7fc323f437c9]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0xbb231 [0x7fc323ebb231]
  Binary file "/usr/lib/libpython3.14.so.1.0", at _PyEval_EvalFrameDefault+0x1cae [0x7fc323fefa6e]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x201237 [0x7fc324001237]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0xbb926 [0x7fc323ebb926]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0xbbbc0 [0x7fc323ebbbc0]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x1437c9 [0x7fc323f437c9]
  Binary file "/usr/lib/libpython3.14.so.1.0", at _PyObject_MakeTpCall+0x9f [0x7fc323ebb52f]
  Binary file "/usr/lib/libpython3.14.so.1.0", at _PyEval_EvalFrameDefault+0x4bbf [0x7fc323ff297f]
  Binary file "/usr/lib/libpython3.14.so.1.0", at +0x201237 [0x7fc324001237]
  <truncated rest of calls>
foo.py crash: exit -11 (1.06 seconds) .> pytest foo.py pid=781607
  crash: FAIL code -11 (2.11 seconds)
  evaluation failed :( (2.22 seconds)

I also reproduced it in a clean 3.14.0b1 venv with trio==0.30.0; pytest==8.3.5 without relying on tox, but idr how to get it to print the stack trace that way.

It's not 100% reliable, so I suspect there's some thread race condition going on.

CPython versions tested on:

3.14

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

Python 3.14.0b1 (main, May 9 2025, 13:04:07) [GCC 14.2.1 20250207]

Linked PRs

@jakkdl jakkdl added the type-crash A hard crash of the interpreter, possibly with a core dump label May 12, 2025
@devdanzin
Copy link
Contributor

Here's the backtrace I get on 3.14 latest git:

Program received signal SIGSEGV, Segmentation fault.
PyStackRef_IsHeapSafe (ref=...) at ./Include/internal/pycore_stackref.h:609
609         return (ref.bits & Py_TAG_BITS) == 0 || ref.bits == PyStackRef_NULL_BITS ||  _Py_IsImmortal(BITS_TO_PTR_MASKED(ref));

#0  PyStackRef_IsHeapSafe (ref=...) at ./Include/internal/pycore_stackref.h:609
#1  PyStackRef_MakeHeapSafe (ref=...) at ./Include/internal/pycore_stackref.h:615
#2  _PyFrame_Copy (dest=0x7ffff5fc0868, src=0x7ffff5fc0718) at ./Include/internal/pycore_interpframe.h:98
#3  take_ownership (frame=0x7ffff5fc0718, f=0x7ffff5fc0820) at Python/frame.c:54
#4  _PyFrame_ClearExceptCode (frame=frame@entry=0x7ffff5fc0718) at Python/frame.c:120
#5  0x000055555566b9d5 in gen_clear_frame (gen=0x7ffff5fc06d0) at Objects/genobject.c:153
#6  gen_clear_frame (gen=0x7ffff5fc06d0) at Objects/genobject.c:145
#7  gen_dealloc (self=0x7ffff5fc06d0) at Objects/genobject.c:182
#8  0x00005555556bd3ae in _Py_Dealloc (op=0x7ffff5fc06d0) at Objects/object.c:3107
#9  0x00005555556eeabe in Py_DECREF (op=<optimized out>) at ./Include/refcount.h:433
#10 clear_slots (self=0x7ffff5fbf800, type=0x555556268f50) at Objects/typeobject.c:2465
#11 subtype_clear (self=0x7ffff5fbf800) at Objects/typeobject.c:2483
#12 0x00005555557eac73 in delete_garbage (old=0x555555b01c60 <_PyRuntime+98048>, collectable=0x7fffffffd9d0,
    gcstate=<optimized out>, tstate=0x555555b36da0 <_PyRuntime+315456>) at Python/gc.c:1141
#13 gc_collect_region (tstate=tstate@entry=0x555555b36da0 <_PyRuntime+315456>, from=<optimized out>,
    to=0x555555b01c60 <_PyRuntime+98048>, stats=stats@entry=0x7fffffffdad0) at Python/gc.c:1759
#14 0x00005555557ebc6c in gc_collect_full (stats=0x7fffffffdad0, tstate=0x555555b36da0 <_PyRuntime+315456>) at Python/gc.c:1679
#15 _PyGC_Collect (tstate=0x555555b36da0 <_PyRuntime+315456>, generation=generation@entry=2,
    reason=reason@entry=_Py_GC_REASON_MANUAL) at Python/gc.c:2041
#16 0x00005555557ed5ae in PyGC_Collect () at Python/gc.c:2070
#17 0x0000555555827526 in _Py_Finalize (runtime=0x555555ae9d60 <_PyRuntime>) at Python/pylifecycle.c:2121
#18 0x000055555582791d in _Py_Finalize (runtime=0x555555ae9d60 <_PyRuntime>) at Python/pylifecycle.c:2252
#19 0x000055555585f8ff in Py_RunMain () at Modules/main.c:769
#20 pymain_main (args=0x7fffffffdc40) at Modules/main.c:797
#21 Py_BytesMain (argc=<optimized out>, argv=<optimized out>) at Modules/main.c:821
#22 0x00007ffff7cc7d90 in __libc_start_call_main (main=main@entry=0x5555555d9cc0 <main>, argc=argc@entry=4,
    argv=argv@entry=0x7fffffffddc8) at ../sysdeps/nptl/libc_start_call_main.h:58
#23 0x00007ffff7cc7e40 in __libc_start_main_impl (main=0x5555555d9cc0 <main>, argc=4, argv=0x7fffffffddc8, init=<optimized out>,
    fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffddb8) at ../csu/libc-start.c:392
#24 0x00005555555ec365 in _start ()

@mpage
Copy link
Contributor

mpage commented May 12, 2025

This bisects to ccf1b0b cc @markshannon

@ZeroIntensity ZeroIntensity added 3.14 bugs and security fixes 3.15 new features, bugs and security fixes labels May 13, 2025
@picnixz picnixz added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label May 15, 2025
@markshannon markshannon self-assigned this May 19, 2025
miss-islington pushed a commit to miss-islington/cpython that referenced this issue May 22, 2025
(cherry picked from commit 29f6dc6)

Co-authored-by: Mark Shannon <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.14 bugs and security fixes 3.15 new features, bugs and security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-crash A hard crash of the interpreter, possibly with a core dump
Projects
None yet
Development

No branches or pull requests

6 participants