Title: JIT: assertion failure in _PyObject_GC_UNTRACK · Issue #137007 · python/cpython · GitHub
Open Graph Title: JIT: assertion failure in _PyObject_GC_UNTRACK · Issue #137007 · python/cpython
X Title: JIT: assertion failure in _PyObject_GC_UNTRACK · Issue #137007 · python/cpython
Description: Crash report What happened? It's possible to non-deterministically abort a special debug JIT build by running the code below, running from a Python executable from a venv where you installed two packages in editable mode. For this specia...
Open Graph Description: Crash report What happened? It's possible to non-deterministically abort a special debug JIT build by running the code below, running from a Python executable from a venv where you installed two pa...
X Description: Crash report What happened? It's possible to non-deterministically abort a special debug JIT build by running the code below, running from a Python executable from a venv where you installed tw...
Opengraph URL: https://github.com/python/cpython/issues/137007
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"JIT: assertion failure in _PyObject_GC_UNTRACK","articleBody":"# Crash report\n\n### What happened?\n\nIt's possible to non-deterministically abort a special debug JIT build by running the code below, running from a Python executable from a venv where you installed **two** packages in editable mode.\n\n\nFor this special build, apply this diff:\n```diff\nindex 454c8dde031..9e21c41421a 100644\n--- a/Include/internal/pycore_backoff.h\n+++ b/Include/internal/pycore_backoff.h\n@@ -99,8 +99,8 @@ backoff_counter_triggers(_Py_BackoffCounter counter)\n // Must be larger than ADAPTIVE_COOLDOWN_VALUE, otherwise when JIT code is\n // invalidated we may construct a new trace before the bytecode has properly\n // re-specialized:\n-#define JUMP_BACKWARD_INITIAL_VALUE 4095\n-#define JUMP_BACKWARD_INITIAL_BACKOFF 12\n+#define JUMP_BACKWARD_INITIAL_VALUE 63\n+#define JUMP_BACKWARD_INITIAL_BACKOFF 6\n static inline _Py_BackoffCounter\n initial_jump_backoff_counter(void)\n {\n@@ -112,8 +112,8 @@ initial_jump_backoff_counter(void)\n * Must be larger than ADAPTIVE_COOLDOWN_VALUE,\n * otherwise when a side exit warms up we may construct\n * a new trace before the Tier 1 code has properly re-specialized. */\n-#define SIDE_EXIT_INITIAL_VALUE 4095\n-#define SIDE_EXIT_INITIAL_BACKOFF 12\n+#define SIDE_EXIT_INITIAL_VALUE 63\n+#define SIDE_EXIT_INITIAL_BACKOFF 6\n\n static inline _Py_BackoffCounter\n initial_temperature_backoff_counter(void)\ndiff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h\nindex 8b7f12bf03d..8cc51959063 100644\n--- a/Include/internal/pycore_optimizer.h\n+++ b/Include/internal/pycore_optimizer.h\n@@ -163,7 +163,7 @@ static inline uint16_t uop_get_error_target(const _PyUOpInstruction *inst)\n // progress (and inserting a new ENTER_EXECUTOR instruction). In practice, this\n // is the \"maximum amount of polymorphism\" that an isolated trace tree can\n // handle before rejoining the rest of the program.\n-#define MAX_CHAIN_DEPTH 4\n+#define MAX_CHAIN_DEPTH 16\n\n /* Symbols */\n /* See explanation in optimizer_symbols.c */\n```\n\nThis MRE must be invoked like this:\n```\n/path/to/venv/with/editable/installs/bin/python mre.py\n```\n\nSorry about another long MRE, this code also seems stubbornly hard to reduce. MRE:\n```python\nfrom random import randint\n\nclass UnstableHash_unstable_hash_object_v4:\n hash_count = 0\n\n def __hash__(self):\n self.hash_count += 1\n new_hash = 5 if self.hash_count \u003c 70 else randint(0, 1024)\n print(new_hash)\n return new_hash\nunstable_hash_object_v4 = UnstableHash_unstable_hash_object_v4()\ntuple_v6 = (90.1433,)\n\ndef uop_harness_f1():\n\n class ShapeA_la_7776:\n payload = 123\n\n class ShapeB_la_7776:\n\n @property\n def payload(self):\n return 'property_payload'\n\n class ShapeC_la_7776:\n\n def payload(self):\n return id(self)\n\n class ShapeD_la_7776:\n __slots__ = ['payload']\n\n def __init__(self):\n self.payload = 'slot_payload'\n shapes_la_7776 = [ShapeA_la_7776(), ShapeB_la_7776(), ShapeC_la_7776(), ShapeD_la_7776()]\n for i in range(500):\n obj = shapes_la_7776[i % len(shapes_la_7776)]\n try:\n payload_val = obj.payload\n if callable(payload_val):\n payload_val()\n payload_val()\n payload_val()\n payload_val()\n except Exception:\n pass\n {unstable_hash_object_v4, unstable_hash_object_v4}\n {unstable_hash_object_v4, unstable_hash_object_v4}\n {unstable_hash_object_v4, unstable_hash_object_v4}\n {unstable_hash_object_v4, unstable_hash_object_v4}\n for i_loop_1589 in {2, 1, 2, 3, 4, 5, 6, 8, 10, 9, 12, 10, 12, 13, 14, 15, 17, 17}:\n x, *y = tuple_v6\n x, *y = tuple_v6\nfor i_f1 in range(300):\n try:\n uop_harness_f1()\n except Exception as e:\n break\n```\n\nBacktrace:\n```\nPython/optimizer.c:269: _PyObject_GC_UNTRACK: Assertion \"_PyObject_GC_IS_TRACKED(((PyObject*)(op)))\" failed: object not tracked by the garbage collector\nEnable tracemalloc to get the memory block allocation traceback\n\nobject address : 0x555555f82230\nobject refcount : 0\nobject type : 0x555555c5e680\nobject type name: uop_executor\nobject repr : \u003crefcnt 0 at 0x555555f82230\u003e\n\nFatal Python error: _PyObject_AssertFailed: _PyObject_AssertFailed\nPython runtime state: initialized\n\nCurrent thread 0x00007ffff7ea8780 [python] (most recent call first):\n File \"/home/danzin/crashers/jit/reduced_crash_retcode_child_15732_2.py\", line 47 in uop_harness_f1\n File \"/home/danzin/crashers/jit/reduced_crash_retcode_child_15732_2.py\", line 56 in \u003cmodule\u003e\n\nProgram received signal SIGABRT, Aborted.\n\n#0 __pthread_kill_implementation (threadid=\u003coptimized out\u003e, signo=6, no_tid=0) at ./nptl/pthread_kill.c:44\n#1 __pthread_kill_internal (threadid=\u003coptimized out\u003e, signo=6) at ./nptl/pthread_kill.c:89\n#2 __GI___pthread_kill (threadid=\u003coptimized out\u003e, signo=signo@entry=6) at ./nptl/pthread_kill.c:100\n#3 0x00007ffff7c4579e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26\n#4 0x00007ffff7c288cd in __GI_abort () at ./stdlib/abort.c:73\n#5 0x00005555558bba92 in fatal_error_exit (status=\u003coptimized out\u003e) at Python/pylifecycle.c:3155\n#6 0x00005555558bd07d in fatal_error (fd=2, header=header@entry=1, prefix=prefix@entry=0x5555559f7e90 \u003c__func__.11\u003e \"_PyObject_AssertFailed\",\n msg=msg@entry=0x555555980fe5 \"_PyObject_AssertFailed\", status=status@entry=-1) at Python/pylifecycle.c:3371\n#7 0x00005555558bd0ef in _Py_FatalErrorFunc (func=func@entry=0x5555559f7e90 \u003c__func__.11\u003e \"_PyObject_AssertFailed\",\n msg=msg@entry=0x555555980fe5 \"_PyObject_AssertFailed\") at Python/pylifecycle.c:3387\n#8 0x00005555556dd237 in _PyObject_AssertFailed (obj=obj@entry=0x555555f82230,\n expr=expr@entry=0x5555559a9f60 \"_PyObject_GC_IS_TRACKED(((PyObject*)(op)))\",\n msg=msg@entry=0x5555559a9f30 \"object not tracked by the garbage collector\", file=file@entry=0x55555598c050 \"Python/optimizer.c\",\n line=line@entry=269, function=function@entry=0x555555a9c010 \u003c__func__.9\u003e \"_PyObject_GC_UNTRACK\") at Objects/object.c:3165\n#9 0x00005555558a2303 in _PyObject_GC_UNTRACK (filename=filename@entry=0x55555598c050 \"Python/optimizer.c\", lineno=lineno@entry=269,\n op=op@entry=0x555555f82230) at ./Include/internal/pycore_gc.h:269\n#10 0x00005555558a3198 in uop_dealloc (op=op@entry=0x555555f82230) at Python/optimizer.c:269\n#11 0x00005555556dc978 in _Py_Dealloc (op=op@entry=0x555555f82230) at Objects/object.c:3206\n#12 0x00005555557b47ab in Py_DECREF_MORTAL (filename=filename@entry=0x5555559aaec8 \"./Include/internal/pycore_stackref.h\", lineno=lineno@entry=701,\n op=0x555555f82230) at ./Include/internal/pycore_object.h:450\n#13 0x00005555557b485b in PyStackRef_CLOSE (ref=..., ref@entry=...) at ./Include/internal/pycore_stackref.h:701\n#14 0x00005555557cfe33 in _PyEval_EvalFrameDefault (tstate=0x555555cca298 \u003c_PyRuntime+331064\u003e, frame=0x7fffffffce30, throwflag=0)\n at Python/generated_cases.c.h:7656\n#15 0x00005555557dd559 in _PyEval_EvalFrame (tstate=tstate@entry=0x555555cca298 \u003c_PyRuntime+331064\u003e, frame=frame@entry=0x7ffff7fac180,\n throwflag=throwflag@entry=0) at ./Include/internal/pycore_ceval.h:119\n#16 0x00005555557dd72a in _PyEval_Vector (tstate=0x555555cca298 \u003c_PyRuntime+331064\u003e, func=0x7ffff74e8650, locals=locals@entry=0x0,\n args=0x7fffffffd008, argcount=\u003coptimized out\u003e, kwnames=0x0) at Python/ceval.c:1977\n#17 0x000055555567dc31 in _PyFunction_Vectorcall (func=\u003coptimized out\u003e, stack=\u003coptimized out\u003e, nargsf=\u003coptimized out\u003e, kwnames=\u003coptimized out\u003e)\n at Objects/call.c:413\n#18 0x000055555567df88 in _PyObject_VectorcallTstate (tstate=0x555555cca298 \u003c_PyRuntime+331064\u003e, callable=callable@entry=0x7ffff74e8650,\n args=args@entry=0x7fffffffd008, nargsf=nargsf@entry=9223372036854775809, kwnames=kwnames@entry=0x0) at ./Include/internal/pycore_call.h:169\n#19 0x000055555567e0b4 in PyObject_CallOneArg (func=func@entry=0x7ffff74e8650, arg=arg@entry=0x7ffff728c8a0) at Objects/call.c:395\n#20 0x000055555570a05e in call_unbound_noarg (unbound=unbound@entry=1, func=func@entry=0x7ffff74e8650, self=self@entry=0x7ffff728c8a0)\n at Objects/typeobject.c:3019\n#21 0x000055555571717f in maybe_call_special_no_args (self=self@entry=0x7ffff728c8a0, attr=\u003coptimized out\u003e,\n attr_is_none=attr_is_none@entry=0x7fffffffd084) at Objects/typeobject.c:3132\n#22 0x000055555571746b in slot_tp_hash (self=0x7ffff728c8a0) at Objects/typeobject.c:10489\n#23 0x00005555556dbf44 in PyObject_Hash (v=0x7ffff728c8a0) at Objects/object.c:1158\n#24 0x00005555556fb0b2 in _PyObject_HashFast (op=op@entry=0x7ffff728c8a0) at ./Include/internal/pycore_object.h:872\n#25 0x00005555556ffaaf in _PySet_AddTakeRef (so=0x7ffff72e5c70, key=0x7ffff728c8a0) at Objects/setobject.c:234\n#26 0x00007ffff706a948 in ?? ()\n#27 0xfffffffffffffffe in ?? ()\n#28 0x0000555555cca298 in _PyRuntime ()\n#29 0x00007fffffffd420 in ?? ()\n#30 0x00007ffff70a9017 in ?? ()\n#31 0x0000555555eb4dc0 in ?? ()\n#32 0x00007ffff70a9000 in ?? ()\n#33 0x0000555555cca298 in _PyRuntime ()\n#34 0x00007ffff7fac0a0 in ?? ()\n#35 0x00007ffff7fac160 in ?? ()\n#36 0x00005555557ca1c0 in _PyEval_EvalFrameDefault (tstate=\u003cerror reading variable: Cannot access memory at address 0xfffffffffffffda0\u003e,\n frame=0xffffffffffffffff, throwflag=\u003cerror reading variable: Cannot access memory at address 0xfffffffffffffd8c\u003e)\n at Python/generated_cases.c.h:5598\nBacktrace stopped: previous frame inner to this frame (corrupt stack?)\n```\n\nHere are the outputs from running with PYTHON_OPT_DEBUG=4 and PYTHON_LLTRACE=4, since they are too long I've attached them as files:\n\n[opt_debug_15732.txt](https://github.com/user-attachments/files/21369964/opt_debug_15732.txt)\n[lltrace_15732.txt](https://github.com/user-attachments/files/21369963/lltrace_15732.txt)\n\nFound using [lafleur](https://github.com/devdanzin/lafleur/).\n\n### CPython versions tested on:\n\nCPython main branch\n\n### Operating systems tested on:\n\nLinux\n\n### Output from running 'python -VV' on the command line:\n\nPython 3.15.0a0 (heads/main-dirty:6bf1c0ab349, Jul 22 2025, 11:26:33) [GCC 14.2.0]\n\n\u003c!-- gh-linked-prs --\u003e\n### Linked PRs\n* gh-137016\n* gh-142541\n\u003c!-- /gh-linked-prs --\u003e\n","author":{"url":"https://github.com/devdanzin","@type":"Person","name":"devdanzin"},"datePublished":"2025-07-22T14:43:20.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":16},"url":"https://github.com/137007/cpython/issues/137007"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:010634d0-f1c9-c18f-dfd2-f79df852aaa7 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | A5E2:2E7C7E:5D2D1A:7F23C2:6A559F16 |
| html-safe-nonce | 73bfa16dc45d590c4bb5be1fa42cecda75d84b78b05cc72f239ce8c1218f2630 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBNUUyOjJFN0M3RTo1RDJEMUE6N0YyM0MyOjZBNTU5RjE2IiwidmlzaXRvcl9pZCI6IjI2NTY2MjkyNTkzOTgxMjczODIiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 661dcbec825e986f95b84bbec8005db2d99e79876826a972e3b07852e9aab7ff |
| hovercard-subject-tag | issue:3252979260 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/python/cpython/137007/issue_layout |
| twitter:image | https://opengraph.githubassets.com/19db183e890a4ec14b20bbfad345d712c96f806a317ae1a0c54ab65eda70c4d3/python/cpython/issues/137007 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/19db183e890a4ec14b20bbfad345d712c96f806a317ae1a0c54ab65eda70c4d3/python/cpython/issues/137007 |
| og:image:alt | Crash report What happened? It's possible to non-deterministically abort a special debug JIT build by running the code below, running from a Python executable from a venv where you installed two pa... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | devdanzin |
| hostname | github.com |
| expected-hostname | github.com |
| None | b5665c84831ed9ac4fb79519c16c9c5580ba8092fb8bb6e3e72972ec7197348e |
| turbo-cache-control | no-preview |
| go-import | github.com/python/cpython git https://github.com/python/cpython.git |
| octolytics-dimension-user_id | 1525981 |
| octolytics-dimension-user_login | python |
| octolytics-dimension-repository_id | 81598961 |
| octolytics-dimension-repository_nwo | python/cpython |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 81598961 |
| octolytics-dimension-repository_network_root_nwo | python/cpython |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | aa21baa44893467b0b640d0300538f84ca8c475b |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width