Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Specializing interpreter may crash if the code object of a class's __init__ method is reassigned #122712

Copy link
Copy link
@mpage

Description

@mpage
Issue body actions

Crash report

What happened?

The interpreter will specialize CALL instructions into CALL_ALLOC_AND_ENTER_INIT when it sees that the target of a CALL is a heap type with a simple __init__ method (i.e. no *args, **kwargs, or kwonly args) and the correct number of arguments are provided to the call. The CALL_ALLOC_AND_ENTER_INIT verifies this condition using a weaker check based only on the argument count. It's possible to reassign the code object for a class's __init__ method using a code object that passes the argcount check in CALL_ALLOC_AND_ENTER_INIT, but uses one of the other properties that the specializer guards against (*args in the repro below).

The following repro causes the interpreter to crash (we should construct the *args tuple but do not):

class MyClass:
    def __init__(self):
        pass


def count_args(self, *args):
    print(f"there are {len(args)}")


def instantiate():
    MyClass()


SPECIALIZATION_THRESHOLD = 10


def main():
    # Trigger specialization
    for i in range(SPECIALIZATION_THRESHOLD):
        instantiate()
    # Trigger the bug
    MyClass.__init__.__code__ = count_args.__code__
    instantiate()


if __name__ == "__main__":
    main()

Backtrace:

python: Python/generated_cases.c.h:5011: _PyEval_EvalFrameDefault: Assertion `!PyStackRef_IsNull(GETLOCAL(oparg))' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff7c8b94c in __pthread_kill_implementation () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff7c8b94c in __pthread_kill_implementation () from /lib64/libc.so.6
#1  0x00007ffff7c3e646 in raise () from /lib64/libc.so.6
#2  0x00007ffff7c287f3 in abort () from /lib64/libc.so.6
#3  0x00007ffff7c2871b in __assert_fail_base.cold () from /lib64/libc.so.6
#4  0x00007ffff7c37386 in __assert_fail () from /lib64/libc.so.6
#5  0x000000000065f3d8 in _PyEval_EvalFrameDefault (tstate=tstate@entry=0xa7c008 <_PyRuntime+416008>, frame=0x7ffff7e1d1c0, throwflag=throwflag@entry=0) at Python/generated_cases.c.h:5016
#6  0x00000000006697e2 in _PyEval_EvalFrame (throwflag=0, frame=<optimized out>, tstate=0xa7c008 <_PyRuntime+416008>) at ./Include/internal/pycore_ceval.h:119
#7  _PyEval_Vector (tstate=tstate@entry=0xa7c008 <_PyRuntime+416008>, func=func@entry=0x7ffff7a625d0,
    locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/mpage/local/scratch/repro_init_issue.py') at remote 0x7ffff7ac3120>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7bbcbf0>, '__file__': '/home/mpage/local/scratch/repro_init_issue.py', '__cached__': None, 'MyClass': <type at remote 0xba9bf0>, 'count_args': <function at remote 0x7ffff7a63590>, 'instantiate': <function at remote 0x7ffff7ae8050>, 'SPECIALIZATION_THRESHOLD': 10, 'main': <function at remote 0x7ffff7ae8110>}, args=args@entry=0x0, argcount=argcount@entry=0,
    kwnames=kwnames@entry=0x0) at Python/ceval.c:1821
#8  0x000000000066989c in PyEval_EvalCode (co=co@entry=<code at remote 0x7ffff7b63480>,
    globals=globals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/mpage/local/scratch/repro_init_issue.py') at remote 0x7ffff7ac3120>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7bbcbf0>, '__file__': '/home/mpage/local/scratch/repro_init_issue.py', '__cached__': None, 'MyClass': <type at remote 0xba9bf0>, 'count_args': <function at remote 0x7ffff7a63590>, 'instantiate': <function at remote 0x7ffff7ae8050>, 'SPECIALIZATION_THRESHOLD': 10, 'main': <function at remote 0x7ffff7ae8110>},
    locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/mpage/local/scratch/repro_init_issue.py') at remote 0x7ffff7ac3120>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7bbcbf0>, '__file__': '/home/mpage/local/scratch/repro_init_issue.py', '__cached__': None, 'MyClass': <type at remote 0xba9bf0>, 'count_args': <function at remote 0x7ffff7a63590>, 'instantiate': <function at remote 0x7ffff7ae8050>, 'SPECIALIZATION_THRESHOLD': 10, 'main': <function at remote 0x7ffff7ae8110>}) at Python/ceval.c:618
#9  0x00000000006e51c9 in run_eval_code_obj (tstate=tstate@entry=0xa7c008 <_PyRuntime+416008>, co=co@entry=0x7ffff7b63480,
    globals=globals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/mpage/local/scratch/repro_init_issue.py') at remote 0x7ffff7ac3120>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7bbcbf0>, '__file__': '/home/mpage/local/scratch/repro_init_issue.py', '__cached__': None, 'MyClass': <type at remote 0xba9bf0>, 'count_args': <function at remote 0x7ffff7a63590>, 'instantiate': <function at remote 0x7ffff7ae8050>, 'SPECIALIZATION_THRESHOLD': 10, 'main': <function at remote 0x7ffff7ae8110>},
    locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/mpage/local/scratch/repro_init_issue.py') at remote 0x7ffff7ac3120>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7bbcbf0>, '__file__': '/home/mpage/local/scratch/repro_init_issue.py', '__cached__': None, 'MyClass': <type at remote 0xba9bf0>, 'count_args': <function at remote 0x7ffff7a63590>, 'instantiate': <function at remote 0x7ffff7ae8050>, 'SPECIALIZATION_THRESHOLD': 10, 'main': <function at remote 0x7ffff7ae8110>}) at Python/pythonrun.c:1292
#10 0x00000000006e69aa in run_mod (mod=mod@entry=0xbb8770, filename=filename@entry='/home/mpage/local/scratch/repro_init_issue.py',
    globals=globals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/mpage/local/scratch/repro_init_issue.py') at remote 0x7ffff7ac3120>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7bbcbf0>, '__file__': '/home/mpage/local/scratch/repro_init_issue.py', '__cached__': None, 'MyClass': <type at remote 0xba9bf0>, 'count_args': <function at remote 0x7ffff7a63590>, 'instantiate': <function at remote 0x7ffff7ae8050>, 'SPECIALIZATION_THRESHOLD': 10, 'main': <function at remote 0x7ffff7ae8110>},
    locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/mpage/local/scratch/repro_init_issue.py') at remote 0x7ffff7ac3120>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7bbcbf0>, '__file__': '/home/mpage/local/scratch/repro_init_issue.py', '__cached__': None, 'MyClass': <type at remote 0xba9bf0>, 'count_args': <function at remote 0x7ffff7a63590>, 'instantiate': <function at remote 0x7ffff7ae8050>, 'SPECIALIZATION_THRESHOLD': 10, 'main': <function at remote 0x7ffff7ae8110>}, flags=flags@entry=0x7fffffffd2b8, arena=arena@entry=0x7ffff7ad96c0,
    interactive_src=0x0, generate_new_source=0) at Python/pythonrun.c:1377
#11 0x00000000006e705b in pyrun_file (fp=fp@entry=0xba0550, filename=filename@entry='/home/mpage/local/scratch/repro_init_issue.py', start=start@entry=257,
    globals=globals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/mpage/local/scratch/repro_init_issue.py') at remote 0x7ffff7ac3120>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7bbcbf0>, '__file__': '/home/mpage/local/scratch/repro_init_issue.py', '__cached__': None, 'MyClass': <type at remote 0xba9bf0>, 'count_args': <function at remote 0x7ffff7a63590>, 'instantiate': <function at remote 0x7ffff7ae8050>, 'SPECIALIZATION_THRESHOLD': 10, 'main': <function at remote 0x7ffff7ae8110>},
    locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='/home/mpage/local/scratch/repro_init_issue.py') at remote 0x7ffff7ac3120>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7ffff7bbcbf0>, '__file__': '/home/mpage/local/scratch/repro_init_issue.py', '__cached__': None, 'MyClass': <type at remote 0xba9bf0>, 'count_args': <function at remote 0x7ffff7a63590>, 'instantiate': <function at remote 0x7ffff7ae8050>, 'SPECIALIZATION_THRESHOLD': 10, 'main': <function at remote 0x7ffff7ae8110>}, closeit=closeit@entry=1, flags=0x7fffffffd2b8)
    at Python/pythonrun.c:1210
#12 0x00000000006e8199 in _PyRun_SimpleFileObject (fp=fp@entry=0xba0550, filename=filename@entry='/home/mpage/local/scratch/repro_init_issue.py', closeit=closeit@entry=1, flags=flags@entry=0x7fffffffd2b8)
    at Python/pythonrun.c:459
#13 0x00000000006e8445 in _PyRun_AnyFileObject (fp=fp@entry=0xba0550, filename=filename@entry='/home/mpage/local/scratch/repro_init_issue.py', closeit=closeit@entry=1, flags=flags@entry=0x7fffffffd2b8)
    at Python/pythonrun.c:77
#14 0x0000000000712c8d in pymain_run_file_obj (program_name=program_name@entry='/data/users/mpage/cpython/python', filename=filename@entry='/home/mpage/local/scratch/repro_init_issue.py', skip_source_first_line=0)
    at Modules/main.c:409
#15 0x0000000000714203 in pymain_run_file (config=config@entry=0xa472d8 <_PyRuntime+199640>) at Modules/main.c:428
#16 0x00000000007146bd in pymain_run_python (exitcode=exitcode@entry=0x7fffffffd444) at Modules/main.c:696
#17 0x0000000000714727 in Py_RunMain () at Modules/main.c:775
#18 0x000000000071479e in pymain_main (args=args@entry=0x7fffffffd4a0) at Modules/main.c:805
#19 0x0000000000714859 in Py_BytesMain (argc=<optimized out>, argv=<optimized out>) at Modules/main.c:829
#20 0x000000000041e86f in main (argc=<optimized out>, argv=<optimized out>) at ./Programs/python.c:15

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

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

No response

Linked PRs

Reactions are currently unavailable

Metadata

Metadata

Assignees

Labels

3.13bugs and security fixesbugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    Morty Proxy This is a proxified and sanitized view of the page, visit original site.