Skip to content
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

[BUG] metaclass=EnumMeta causes: PyTuple_GET_SIZE: Assertion PyTuple_Check(op)' failed` #5665

Closed
mgorny opened this issue Aug 29, 2023 · 0 comments · Fixed by #5675
Closed

Comments

@mgorny
Copy link
Contributor

mgorny commented Aug 29, 2023

Describe the bug

The code snippet reproduced below built with Cython 3 (Cython 0.x is fine) produces a Python extension that crashes upon loading if CPython was built with assertions enabled:

$ python -c 'import repro'
python: ./Include/cpython/tupleobject.h:23: PyTuple_GET_SIZE: Assertion `PyTuple_Check(op)' failed.
Aborted (core dumped)
Backtrace
(gdb) bt
#0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
#1  0x00007fa5a2889e2f in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78
#2  0x00007fa5a2839cc2 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x00007fa5a28224ed in __GI_abort () at abort.c:79
#4  0x00007fa5a2822415 in __assert_fail_base (fmt=0x7fa5a299fb98 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", 
    assertion=assertion@entry=0x7fa5a2f04da1 "PyTuple_Check(op)", file=file@entry=0x7fa5a2f1a450 "./Include/cpython/tupleobject.h", 
    line=line@entry=23, function=function@entry=0x7fa5a2f46710 <__PRETTY_FUNCTION__.8> "PyTuple_GET_SIZE") at assert.c:92
#5  0x00007fa5a28325e2 in __assert_fail (assertion=assertion@entry=0x7fa5a2f04da1 "PyTuple_Check(op)", 
    file=file@entry=0x7fa5a2f1a450 "./Include/cpython/tupleobject.h", line=line@entry=23, 
    function=function@entry=0x7fa5a2f46710 <__PRETTY_FUNCTION__.8> "PyTuple_GET_SIZE") at assert.c:101
#6  0x00007fa5a2d5249a in PyTuple_GET_SIZE (op=op@entry={}) at ./Include/cpython/tupleobject.h:23
#7  0x00007fa5a2d52678 in method_vectorcall (method=<optimized out>, args=0x7ffdb3ea2bd8, nargsf=<optimized out>, kwnames={})
    at Objects/classobject.c:64
#8  0x00007fa5a2af9c4b in __Pyx_PyObject_FastCallDict ()
   from /home/mgorny/git/cython-enummeta-repro/repro.cpython-311-x86_64-linux-gnu.so
#9  0x00007fa5a2afa1ea in __Pyx_Py3MetaclassPrepare ()
   from /home/mgorny/git/cython-enummeta-repro/repro.cpython-311-x86_64-linux-gnu.so
#10 0x00007fa5a2af8e57 in __pyx_pymod_exec_repro () from /home/mgorny/git/cython-enummeta-repro/repro.cpython-311-x86_64-linux-gnu.so
#11 0x00007fa5a2d97284 in PyModule_ExecDef (module=module@entry=<module at remote 0x7fa5a2ba0400>, 
    def=def@entry=0x7fa5a2aff280 <__pyx_moduledef>) at Objects/moduleobject.c:419
#12 0x00007fa5a2e554b3 in exec_builtin_or_dynamic (mod=mod@entry=<module at remote 0x7fa5a2ba0400>) at Python/import.c:2334
#13 0x00007fa5a2e55501 in _imp_exec_dynamic_impl (module=<optimized out>, mod=mod@entry=<module at remote 0x7fa5a2ba0400>)
    at Python/import.c:2408
#14 0x00007fa5a2e5550c in _imp_exec_dynamic (module=<optimized out>, mod=mod@entry=<module at remote 0x7fa5a2ba0400>)
    at Python/clinic/import.c.h:474
#15 0x00007fa5a2d952cd in cfunction_vectorcall_O (func=<built-in method exec_dynamic of module object at remote 0x7fa5a2b8a390>, 
    args=<optimized out>, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/methodobject.c:514
#16 0x00007fa5a2d4fa71 in _PyVectorcall_Call (tstate=tstate@entry=0x7fa5a31856f8 <_PyRuntime+166328>, 
    func=0x7fa5a2d95264 <cfunction_vectorcall_O>, 
    callable=callable@entry=<built-in method exec_dynamic of module object at remote 0x7fa5a2b8a390>, 
    tuple=tuple@entry=(<module at remote 0x7fa5a2ba0400>,), kwargs=kwargs@entry={}) at Objects/call.c:245
#17 0x00007fa5a2d4fe22 in _PyObject_Call (tstate=0x7fa5a31856f8 <_PyRuntime+166328>, 
    callable=callable@entry=<built-in method exec_dynamic of module object at remote 0x7fa5a2b8a390>, 
    args=args@entry=(<module at remote 0x7fa5a2ba0400>,), kwargs=kwargs@entry={}) at Objects/call.c:328
#18 0x00007fa5a2d4fe74 in PyObject_Call (
    callable=callable@entry=<built-in method exec_dynamic of module object at remote 0x7fa5a2b8a390>, 
    args=args@entry=(<module at remote 0x7fa5a2ba0400>,), kwargs=kwargs@entry={}) at Objects/call.c:355
#19 0x00007fa5a2e207ef in do_call_core (tstate=tstate@entry=0x7fa5a31856f8 <_PyRuntime+166328>, 
    func=func@entry=<built-in method exec_dynamic of module object at remote 0x7fa5a2b8a390>, 
    callargs=callargs@entry=(<module at remote 0x7fa5a2ba0400>,), kwdict=kwdict@entry={}, use_tracing=0) at Python/ceval.c:7329
#20 0x00007fa5a2e2ce0c in _PyEval_EvalFrameDefault (tstate=0x7fa5a31856f8 <_PyRuntime+166328>, frame=0x7fa5a32f62e0, 
    throwflag=<optimized out>) at Python/ceval.c:5381
#21 0x00007fa5a2e2e00b in _PyEval_EvalFrame (tstate=tstate@entry=0x7fa5a31856f8 <_PyRuntime+166328>, 
    frame=frame@entry=0x7fa5a32f6078, throwflag=throwflag@entry=0) at ./Include/internal/pycore_ceval.h:73
#22 0x00007fa5a2e2e102 in _PyEval_Vector (tstate=0x7fa5a31856f8 <_PyRuntime+166328>, func=0x7fa5a2b4fce0, locals=locals@entry=0x0, 
    args=0x7ffdb3ea3010, argcount=<optimized out>, kwnames=0x0) at Python/ceval.c:6439
#23 0x00007fa5a2d4fef8 in _PyFunction_Vectorcall (func=<optimized out>, stack=<optimized out>, nargsf=<optimized out>, 
    kwnames=<optimized out>) at Objects/call.c:393
#24 0x00007fa5a2d50235 in _PyObject_VectorcallTstate (tstate=tstate@entry=0x7fa5a31856f8 <_PyRuntime+166328>, 
    callable=callable@entry=<function at remote 0x7fa5a2b4fce0>, args=args@entry=0x7ffdb3ea3010, nargsf=nargsf@entry=2, 
    kwnames=kwnames@entry=0x0) at ./Include/internal/pycore_call.h:92
#25 0x00007fa5a2d51241 in object_vacall (tstate=tstate@entry=0x7fa5a31856f8 <_PyRuntime+166328>, base=base@entry=0x0, 
    callable=<function at remote 0x7fa5a2b4fce0>, vargs=vargs@entry=0x7ffdb3ea3090) at Objects/call.c:819
#26 0x00007fa5a2d51374 in PyObject_CallMethodObjArgs (obj=0x0, name=<optimized out>) at Objects/call.c:879
#27 0x00007fa5a2e54ed7 in import_find_and_load (tstate=tstate@entry=0x7fa5a31856f8 <_PyRuntime+166328>, 
    abs_name=abs_name@entry='repro') at Python/import.c:1737
#28 0x00007fa5a2e5717e in PyImport_ImportModuleLevelObject (name=name@entry='repro', globals=<optimized out>, 
    locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x5622088c0470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7fa5a2b88a90>}, fromlist=fromlist@entry=None, 
    level=level@entry=0) at Python/import.c:1836
#29 0x00007fa5a2e1c6bd in import_name (tstate=tstate@entry=0x7fa5a31856f8 <_PyRuntime+166328>, frame=frame@entry=0x7fa5a32f6020, 
    name='repro', fromlist=fromlist@entry=None, level=level@entry=0) at Python/ceval.c:7429
#30 0x00007fa5a2e28487 in _PyEval_EvalFrameDefault (tstate=0x7fa5a31856f8 <_PyRuntime+166328>, frame=0x7fa5a32f6020, 
    throwflag=<optimized out>) at Python/ceval.c:3951
#31 0x00007fa5a2e2e00b in _PyEval_EvalFrame (tstate=tstate@entry=0x7fa5a31856f8 <_PyRuntime+166328>, 
    frame=frame@entry=0x7fa5a32f6020, throwflag=throwflag@entry=0) at ./Include/internal/pycore_ceval.h:73
#32 0x00007fa5a2e2e102 in _PyEval_Vector (tstate=tstate@entry=0x7fa5a31856f8 <_PyRuntime+166328>, func=func@entry=0x7fa5a2bd5f80, 
    locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x5622088c0470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7fa5a2b88a90>}, args=args@entry=0x0, 
    argcount=argcount@entry=0, kwnames=kwnames@entry=0x0) at Python/ceval.c:6439
#33 0x00007fa5a2e2e21d in PyEval_EvalCode (co=co@entry=<code at remote 0x7fa5a2b1f5d0>, 
    globals=globals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x5622088c0470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7fa5a2b88a90>}, 
    locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x5622088c0470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7fa5a2b88a90>}) at Python/ceval.c:1154
#34 0x00007fa5a2e707ba in run_eval_code_obj (tstate=tstate@entry=0x7fa5a31856f8 <_PyRuntime+166328>, co=co@entry=0x7fa5a2b1f5d0, 
    globals=globals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x5622088c0470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7fa5a2b88a90>}, 
    locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x5622088c0470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7fa5a2b88a90>}) at Python/pythonrun.c:1712
#35 0x00007fa5a2e70884 in run_mod (mod=mod@entry=0x56220890cf50, filename=<optimized out>, 
    globals=globals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x5622088c0470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7fa5a2b88a90>}, 
    locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x5622088c0470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7fa5a2b88a90>}, flags=flags@entry=0x7ffdb3ea3580, 
    arena=arena@entry=0x7fa5a2b1b7d0) at Python/pythonrun.c:1733
#36 0x00007fa5a2e73800 in PyRun_StringFlags (str=str@entry=0x7fa5a2bba840 "import repro\n", start=start@entry=257, 
    globals={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x5622088c0470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7fa5a2b88a90>}, 
    locals={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x5622088c0470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7fa5a2b88a90>}, flags=flags@entry=0x7ffdb3ea3580)
    at Python/pythonrun.c:1603
#37 0x00007fa5a2e7385d in PyRun_SimpleStringFlags (command=0x7fa5a2bba840 "import repro\n", flags=flags@entry=0x7ffdb3ea3580)
    at Python/pythonrun.c:487
#38 0x00007fa5a2e90487 in pymain_run_command (command=<optimized out>) at Modules/main.c:255
#39 0x00007fa5a2e90f4c in pymain_run_python (exitcode=exitcode@entry=0x7ffdb3ea3614) at Modules/main.c:592
#40 0x00007fa5a2e9127d in Py_RunMain () at Modules/main.c:680
#41 0x00007fa5a2e912fa in pymain_main (args=args@entry=0x7ffdb3ea3670) at Modules/main.c:710
#42 0x00007fa5a2e913c9 in Py_BytesMain (argc=<optimized out>, argv=<optimized out>) at Modules/main.c:734
#43 0x000056220831b16e in main (argc=<optimized out>, argv=<optimized out>) at ./Programs/python.c:15

Code to reproduce the behaviour:

from enum import IntEnum, EnumMeta


class Test(IntEnum, metaclass=EnumMeta):
    pass

Expected behaviour

No response

OS

Gentoo Linux amd64

Python version

3.11.5

Cython version

df4c9a4

Additional context

Originally reported to pythongssapi/python-gssapi#327.

da-woods added a commit to da-woods/cython that referenced this issue Sep 2, 2023
Fixes cython#5665

I'm slightly surprised this hasn't caused more bugs. We're passing
a dict where we should be passing a tuple of names.

Replacement should hopefully be right, but I don't know how
optimized or otherwise it is.
da-woods added a commit to da-woods/cython that referenced this issue Sep 2, 2023
Fixes cython#5665

I'm slightly surprised this hasn't caused more bugs. We're passing
a dict where we should be passing a tuple of names.

Replacement should hopefully be right, but I don't know how
optimized or otherwise it is.
@scoder scoder added this to the 3.0.3 milestone Sep 12, 2023
scoder pushed a commit that referenced this issue Sep 12, 2023
We're passing a dict where we should be passing a tuple of names.

The replacement should hopefully be right, but I don't know how optimized or otherwise it is. It prevents a crash in the previous code, so we don't lose anything.

Closes #5665
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants