Skip to content

Assertion failure in Python/optimizer.c _PyOptimizer_Optimize in JIT #140936

Description

@YuanchengJiang

Crash report

What happened?

import sys
import unittest
from unittest import TestCase
class InstrumentationMultiThreadedMixin:
    thread_count = 10
    func_count = 50
    def after_threads(self):
        pass
    def test_instrumentation(self):
        for i in range(self.func_count):
            x = {}
        threads = []
        for i in range(self.thread_count):
            for t in threads:
                break
            self.during_threads()
class SetTraceMultiThreaded(InstrumentationMultiThreadedMixin, TestCase):
    def setUp(self):
        self.set = 2**31-1
    def after_test(self):
        self.assertTrue(self.called)
    def tearDown(self):
        sys.settrace(1023)
    def trace_func(self, frame, event, arg):
        return self.trace_func
    def during_threads(self):
        if self.set:
            sys.settrace(self.trace_func)
        t.join()
if __name__ == "__main__":
    unittest.main()
...
TypeError: 'int' object is not callable
python: ../Python/optimizer.c:121: _PyOptimizer_Optimize: Assertion `interp->jit' failed.
Aborted (core dumped)

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

Activity

  1. added
    type-crashA hard crash of the interpreter, possibly with a core dump
    on Nov 3, 2025
  2. sergey-miryanov commented on Nov 3, 2025

    @sergey-miryanov
    Contributor

    I think it would be better if you provided the building flags used to create the fuzzed version of python executable.

  3. YuanchengJiang commented on Nov 3, 2025

    @YuanchengJiang
    Author

    building flag: --with-pydebug --enable-experimental-jit=yes --with-address-sanitizer

  4. sergey-miryanov commented on Nov 3, 2025

    @sergey-miryanov
    Contributor

    Simplified MRE:

    import sys
    import unittest
    from unittest import TestCase
    
    
    class InstrumentationMultiThreadedMixin(TestCase):
    
        def setUp(self):
            sys.settrace(lambda *args:None)
    
        def tearDown(self):
            sys.settrace(1023)
    
        def test_instrumentation(self):
            assert False
    
    if __name__ == "__main__":
        unittest.main()

    Stacktrace to failed assert:

    >	python315_d.dll!_PyOptimizer_Optimize(_PyInterpreterFrame * frame, _Py_CODEUNIT * start, _PyExecutorObject * * executor_ptr, int chain_depth) Line 121	C
     	python315_d.dll!_PyEval_EvalFrameDefault(_ts * tstate, _PyInterpreterFrame * frame, int throwflag) Line 7656	C
     	python315_d.dll!gen_send_ex2(_PyGenObject * gen, _object * arg, _object * * presult, int exc, int closing) Line 259	C
     	python315_d.dll!gen_send_ex(_PyGenObject * gen, _object * arg, int exc, int closing) Line 301	C
     	python315_d.dll!gen_close(_object * self, _object * args) Line 427	C
     	python315_d.dll!_PyGen_Finalize(_object * self) Line 129	C
     	python315_d.dll!PyObject_CallFinalizer(_object * self) Line 586	C
     	python315_d.dll!PyObject_CallFinalizerFromDealloc(_object * self) Line 605	C
     	python315_d.dll!gen_dealloc(_object * self) Line 169	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF(const char * filename, int lineno, _object * op) Line 403	C
     	python315_d.dll!clear_inline_values(_dictvalues * values) Line 7233	C
     	python315_d.dll!PyObject_ClearManagedDict(_object * obj) Line 7452	C
     	python315_d.dll!subtype_dealloc(_object * self) Line 2824	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF_MORTAL(const char * filename, int lineno, _object * op) Line 450	C
     	python315_d.dll!frame_dealloc(_object * op) Line 1953	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF(const char * filename, int lineno, _object * op) Line 403	C
     	python315_d.dll!tb_dealloc(_object * op) Line 246	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF(const char * filename, int lineno, _object * op) Line 403	C
     	python315_d.dll!tb_dealloc(_object * op) Line 245	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF(const char * filename, int lineno, _object * op) Line 403	C
     	python315_d.dll!tb_dealloc(_object * op) Line 245	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF(const char * filename, int lineno, _object * op) Line 403	C
     	python315_d.dll!tb_dealloc(_object * op) Line 245	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF(const char * filename, int lineno, _object * op) Line 403	C
     	python315_d.dll!tb_dealloc(_object * op) Line 245	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF(const char * filename, int lineno, _object * op) Line 403	C
     	python315_d.dll!tb_dealloc(_object * op) Line 245	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF(const char * filename, int lineno, _object * op) Line 403	C
     	python315_d.dll!tb_dealloc(_object * op) Line 245	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF(const char * filename, int lineno, _object * op) Line 403	C
     	python315_d.dll!tb_dealloc(_object * op) Line 245	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF(const char * filename, int lineno, _object * op) Line 403	C
     	python315_d.dll!tb_dealloc(_object * op) Line 245	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF(const char * filename, int lineno, _object * op) Line 403	C
     	python315_d.dll!tb_dealloc(_object * op) Line 245	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF(const char * filename, int lineno, _object * op) Line 403	C
     	python315_d.dll!tb_dealloc(_object * op) Line 245	C
     	python315_d.dll!_Py_Dealloc(_object * op) Line 3205	C
     	python315_d.dll!Py_DECREF(const char * filename, int lineno, _object * op) Line 403	C
     	python315_d.dll!insertdict(_is * interp, PyDictObject * mp, _object * key, __int64 hash, _object * value) Line 1928	C
     	python315_d.dll!setitem_take2_lock_held(PyDictObject * mp, _object * key, _object * value) Line 2677	C
     	python315_d.dll!_PyDict_SetItem_Take2(PyDictObject * mp, _object * key, _object * value) Line 2684	C
     	python315_d.dll!PyDict_SetItem(_object * op, _object * key, _object * value) Line 2706	C
     	python315_d.dll!PyDict_SetItemString(_object * v, const char * key, _object * item) Line 5059	C
     	python315_d.dll!_PySys_ClearAttrString(_is * interp, const char * name, int verbose) Line 222	C
     	python315_d.dll!finalize_modules_delete_special(_ts * tstate, int verbose) Line 1530	C
     	python315_d.dll!finalize_modules(_ts * tstate) Line 1746	C
     	python315_d.dll!_Py_Finalize(pyruntimestate * runtime) Line 2259	C
     	python315_d.dll!Py_FinalizeEx() Line 2380	C
     	python315_d.dll!Py_RunMain() Line 774	C
     	python315_d.dll!pymain_main(_PyArgv * args) Line 803	C
     	python315_d.dll!Py_Main(int argc, wchar_t * * argv) Line 815	C
     	python_d.exe!wmain(int argc, wchar_t * * argv) Line 10	C

    cc @Fidget-Spinner

  5. added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    and removed
    pendingThe issue will be closed if no feedback is provided
    on Nov 3, 2025
  6. Fidget-Spinner commented on Nov 3, 2025

    @Fidget-Spinner
    Member

    I can reproduce this using my new JIT frontend as well. Probably a bug in the specialization/JIT detection.

  7. added
    3.14bugs and security fixes
    3.15pre-release feature fixes, bugs and security fixes
    on Nov 3, 2025
  8. efimov-mikhail commented on Nov 3, 2025

    @efimov-mikhail
    Member

    FYI, I've made some repro without using stdlib:

    import sys
    
    def simple_for():
        for x in (1, 2): 
            x
    
    def gen():
        try:
            yield
        except:
            simple_for()
    
    sys.settrace(lambda *args: None)
    simple_for()
    g = gen()
    next(g)
  9. efimov-mikhail commented on Nov 3, 2025

    @efimov-mikhail
    Member

    It seems that I've found a simple solution.

  10. added a commit that references this issue on Nov 12, 2025
  11. added a commit that references this issue on Nov 13, 2025
  12. added a commit that references this issue on Nov 13, 2025
  13. added a commit that references this issue on Dec 6, 2025
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

    3.14bugs and security fixes3.15pre-release feature fixes, bugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)topic-JITtype-crashA hard crash of the interpreter, possibly with a core dump

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions