Skip to content

Segfault in Python 3.13 #868

Closed
Closed

Description

@westernmagic

Description

The following minimal reproducible example segfaults on Python 3.13 (3.13.4, 3.13.5, 3.13.7; macOS and Linux):

#!/usr/bin/env PYTHONMALLOC=debug python
import msgspec

class Foo:
    pass

class Bar(msgspec.Struct, Foo):
    pass

bar = Bar()

gdb backtrace:

#0  Py_DECREF (filename=filename@entry=0x7d4ab8 "../Objects/dictobject.c", lineno=lineno@entry=7151, op=<unknown at remote 0xcdcdcdcdcdcdcdcd>) at ../Include/object.h:930
#1  0x00000000004fe9c4 [PAC] in set_dict_inline_values (obj=obj@entry=<Bar() at remote 0xffffb6c126e0>, new_dict=new_dict@entry=0x0) at ../Objects/dictobject.c:7151
#2  0x0000000000505128 [PAC] in _PyObject_SetManagedDict (obj=obj@entry=<Bar() at remote 0xffffb6c126e0>, new_dict=new_dict@entry=0x0) at ../Objects/dictobject.c:7180
#3  0x00000000005051b8 [PAC] in PyObject_ClearManagedDict (obj=obj@entry=<Bar() at remote 0xffffb6c126e0>) at ../Objects/dictobject.c:7222
#4  0x0000000000554bf8 [PAC] in subtype_dealloc (self=<Bar() at remote 0xffffb6c126e0>) at ../Objects/typeobject.c:2359
#5  0x0000000000519894 [PAC] in _Py_Dealloc (op=op@entry=<Bar() at remote 0xffffb6c126e0>) at ../Objects/object.c:2939
#6  0x00000000004fe2a8 [PAC] in Py_DECREF (filename=filename@entry=0x7b0778 "../Include/object.h", lineno=lineno@entry=1047, op=<Bar() at remote 0xffffb6c126e0>) at ../Include/object.h:939
#7  0x00000000004fe2d0 [PAC] in Py_XDECREF (op=<optimized out>) at ../Include/object.h:1047
#8  0x00000000004fe3b4 [PAC] in dictkeys_decref (interp=interp@entry=0xbf2198 <_PyRuntime+104400>, dk=dk@entry=0xffffb69132e0, use_qsbr=use_qsbr@entry=false) at ../Objects/dictobject.c:496
#9  0x0000000000509664 [PAC] in dict_dealloc (
    self={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <unknown at remote 0xffffb6dfa010>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0xffffb6e5e990>, 'msgspec': <module at remote 0xffffb6d50890>, 'Foo': <type at remote 0xa7b6f20>, 'Bar': <msgspec._core.StructMeta at remote 0xa7b7670>, 'bar': <Bar() at remote 0xffffb6c126e0>}) at ../Objects/dictobject.c:3222
#10 0x0000000000519894 [PAC] in _Py_Dealloc (
    op=op@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <unknown at remote 0xffffb6dfa010>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0xffffb6e5e990>, 'msgspec': <module at remote 0xffffb6d50890>, 'Foo': <type at remote 0xa7b6f20>, 'Bar': <msgspec._core.StructMeta at remote 0xa7b7670>, 'bar': <Bar() at remote 0xffffb6c126e0>})
    at ../Objects/object.c:2939
#11 0x00000000005154d8 [PAC] in Py_DECREF (filename=filename@entry=0x7b0778 "../Include/object.h", lineno=lineno@entry=1047,
    op={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <unknown at remote 0xffffb6dfa010>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0xffffb6e5e990>, 'msgspec': <module at remote 0xffffb6d50890>, 'Foo': <type at remote 0xa7b6f20>, 'Bar': <msgspec._core.StructMeta at remote 0xa7b7670>, 'bar': <Bar() at remote 0xffffb6c126e0>}) at ../Include/object.h:939
#12 0x0000000000515570 [PAC] in Py_XDECREF (op=<optimized out>) at ../Include/object.h:1047
#13 0x0000000000516080 [PAC] in module_dealloc (m=0xffffb6cd0e90) at ../Objects/moduleobject.c:777
#14 0x0000000000519894 [PAC] in _Py_Dealloc (op=op@entry=<module at remote 0xffffb6cd0e90>) at ../Objects/object.c:2939
#15 0x00000000004fe2a8 [PAC] in Py_DECREF (filename=filename@entry=0x7b0778 "../Include/object.h", lineno=lineno@entry=1047, op=<module at remote 0xffffb6cd0e90>) at ../Include/object.h:939
#16 0x00000000004fe2d0 [PAC] in Py_XDECREF (op=<optimized out>) at ../Include/object.h:1047
#17 0x00000000005061ec [PAC] in insertdict (interp=0xbf2198 <_PyRuntime+104400>, mp=mp@entry=0xffffb6e59fd0, key=key@entry='__main__', hash=hash@entry=-6614366599102201275, value=value@entry=None)
    at ../Objects/dictobject.c:1885
#18 0x0000000000506440 [PAC] in setitem_take2_lock_held (mp=mp@entry=0xffffb6e59fd0, key=key@entry='__main__', value=value@entry=None) at ../Objects/dictobject.c:2549
#19 0x0000000000506ab0 [PAC] in _PyDict_SetItem_Take2 (mp=mp@entry=0xffffb6e59fd0, key=key@entry='__main__', value=value@entry=None) at ../Objects/dictobject.c:2557
#20 0x0000000000506b18 [PAC] in PyDict_SetItem (
    op={'sys': None, 'builtins': None, '_frozen_importlib': None, '_imp': None, '_thread': None, '_warnings': None, '_weakref': None, '_io': None, 'marshal': None, 'posix': None, '_frozen_importlib_external': None, 'time': None, 'zipimport': None, 'faulthandler': None, '_codecs': None, 'codecs': None, 'encodings.aliases': None, 'encodings': None, 'encodings.utf_8': None, '_signal': None, '_abc': None, 'abc': None, 'io': None, '__main__': None, '_stat': <module at remote 0xffffb6ce20f0>, 'stat': <module at remote 0xffffb6cd3b30>, '_collections_abc': <module at remote 0xffffb6cd3050>, 'errno': <module at remote 0xffffb6d282f0>, 'genericpath': <module at remote 0xffffb6d284d0>, 'posixpath': <module at remote 0xffffb6cd31d0>, 'os.path': <module at remote 0xffffb6cd31d0>, 'os': <module at remote 0xffffb6cd2870>, '_sitebuiltins': <module at remote 0xffffb6cd2b70>, 'encodings.utf_8_sig': <module at remote 0xffffb6d29af0>, '_distutils_hack': <module at remote 0xffffb6d2a8d0>, 'sitecustomize': <module at remote 0xffffb6d2b8f...(truncated), key='__main__',
    value=None) at ../Include/object.h:1064
#21 0x0000000000507584 [PAC] in dict_ass_sub (mp=<optimized out>, v=<optimized out>, w=<optimized out>) at ../Objects/dictobject.c:3383
#22 0x000000000049eefc [PAC] in PyObject_SetItem (
    o=o@entry={'sys': None, 'builtins': None, '_frozen_importlib': None, '_imp': None, '_thread': None, '_warnings': None, '_weakref': None, '_io': None, 'marshal': None, 'posix': None, '_frozen_importlib_external': None, 'time': None, 'zipimport': None, 'faulthandler': None, '_codecs': None, 'codecs': None, 'encodings.aliases': None, 'encodings': None, 'encodings.utf_8': None, '_signal': None, '_abc': None, 'abc': None, 'io': None, '__main__': None, '_stat': <module at remote 0xffffb6ce20f0>, 'stat': <module at remote 0xffffb6cd3b30>, '_collections_abc': <module at remote 0xffffb6cd3050>, 'errno': <module at remote 0xffffb6d282f0>, 'genericpath': <module at remote 0xffffb6d284d0>, 'posixpath': <module at remote 0xffffb6cd31d0>, 'os.path': <module at remote 0xffffb6cd31d0>, 'os': <module at remote 0xffffb6cd2870>, '_sitebuiltins': <module at remote 0xffffb6cd2b70>, 'encodings.utf_8_sig': <module at remote 0xffffb6d29af0>, '_distutils_hack': <module at remote 0xffffb6d2a8d0>, 'sitecustomize': <module at remote 0xffffb6d2b8f...(truncated),
    key=<optimized out>, value=None) at ../Objects/abstract.c:232
#23 0x000000000067d540 [PAC] in finalize_remove_modules (
    modules=modules@entry={'sys': None, 'builtins': None, '_frozen_importlib': None, '_imp': None, '_thread': None, '_warnings': None, '_weakref': None, '_io': None, 'marshal': None, 'posix': None, '_frozen_importlib_external': None, 'time': None, 'zipimport': None, 'faulthandler': None, '_codecs': None, 'codecs': None, 'encodings.aliases': None, 'encodings': None, 'encodings.utf_8': None, '_signal': None, '_abc': None, 'abc': None, 'io': None, '__main__': None, '_stat': <module at remote 0xffffb6ce20f0>, 'stat': <module at remote 0xffffb6cd3b30>, '_collections_abc': <module at remote 0xffffb6cd3050>, 'errno': <module at remote 0xffffb6d282f0>, 'genericpath': <module at remote 0xffffb6d284d0>, 'posixpath': <module at remote 0xffffb6cd31d0>, 'os.path': <module at remote 0xffffb6cd31d0>, 'os': <module at remote 0xffffb6cd2870>, '_sitebuiltins': <module at remote 0xffffb6cd2b70>, 'encodings.utf_8_sig': <module at remote 0xffffb6d29af0>, '_distutils_hack': <module at remote 0xffffb6d2a8d0>, 'sitecustomize': <module at remote 0xffffb6d2b8f...(truncated), verbose=verbose@entry=0) at ../Python/pylifecycle.c:1598
#24 0x000000000067db54 [PAC] in finalize_modules (tstate=tstate@entry=0xc219f8 <_PyRuntime+299056>) at ../Python/pylifecycle.c:1747
#25 0x00000000006844ac [PAC] in _Py_Finalize (runtime=runtime@entry=0xbd89c8 <_PyRuntime>) at ../Python/pylifecycle.c:2134
#26 0x000000000068457c [PAC] in Py_FinalizeEx () at ../Python/pylifecycle.c:2261
#27 0x00000000006b6910 [PAC] in Py_RunMain () at ../Modules/main.c:778
#28 0x00000000006b6978 [PAC] in pymain_main (args=args@entry=0xffffc10dc0f0) at ../Modules/main.c:806
#29 0x00000000006b6a0c [PAC] in Py_BytesMain (argc=<optimized out>, argv=<optimized out>) at ../Modules/main.c:830
#30 0x000000000042157c [PAC] in main (argc=<optimized out>, argv=<optimized out>) at ../Programs/python.c:1

The above has been distilled from a larger Python program, which segfaults in production (ie. without PYTHONMALLOC=debug set) with the same trace (ie. during deallocation of bar)

Activity

  1. ofek commented on Sep 19, 2025

    @ofek
    Member

    @jcrist Have you been able to take a look at this?

  2. maximzubkov commented on Oct 9, 2025

    @maximzubkov

    @jcrist 🙏

  3. provinzkraut commented on Oct 26, 2025

    @provinzkraut
    Member

    I can no longer reproduce this using 3.13.7 on Linux. @westernmagic @ofek is this still relevant?

  4. ofek commented on Oct 28, 2025

    @ofek
    Member

    Nope, thanks!

  5. ofek commented on Oct 28, 2025

    @ofek
    Member

    I don't think it's related but heads up #910

  6. westernmagic commented on Oct 29, 2025

    @westernmagic
    Author

    Hmm, the minimal reproducible example works on 3.13.7 and 3.13.9, but my production workload still crashes. Will investigate further to see if I can distill another example that crashes on those versions.

  7. ofek commented on Oct 30, 2025

    @ofek
    Member

    Were you able to find another example to reproduce or offer any details about your current production issues?

  8. shadchin commented on Nov 25, 2025

    @shadchin
    Contributor

    On my mac:

    (venv_313) shadchin@i113735019 ~ % python
    Python 3.13.9 (main, Oct 14 2025, 13:52:31) [Clang 17.0.0 (clang-1700.0.13.3)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from msgspec import defstruct
    >>> Test = defstruct("Test", [], dict=True)
    >>> hasattr(Test(), "__dict__")
    zsh: bus error  python
    

    Also I have segfault on Linux with Python 3.13 (with PYTHONMALLOC=debug)

  9. shadchin commented on Nov 27, 2025

    @shadchin
    Contributor
  10. westernmagic commented on Jan 13, 2026

    @westernmagic
    Author

    Sorry for not getting back; I was not able to find a different example that produced the error. However, I can confirm that @shadchin 's patch fixes the error!

  11. Siyet commented on Apr 8, 2026

    @Siyet
    Contributor

    Ported to the community fork msgspec-arise: issue #21, PR #28

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions