Skip to content

Resolve the free-threaded c_stack_refs offset at runtime - #528

Closed
ddorian wants to merge 1 commit into
python-greenlet:masterfrom
ddorian:issue515-c-stack-refs-offset
Closed

Resolve the free-threaded c_stack_refs offset at runtime#528
ddorian wants to merge 1 commit into
python-greenlet:masterfrom
ddorian:issue515-c-stack-refs-offset

Conversation

@ddorian

@ddorian ddorian commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Fixes #527

CPython 3.14.4 appended datastack_cached_chunk to PyThreadState, moving
_PyThreadStateImpl.c_stack_refs from offset 912 to 920 within the 3.14
series. One cp314t wheel serves every 3.14.x, so a wheel built for 3.14.4
or later read 8 bytes past the field on 3.14.0 through 3.14.3 and landed
on gc.alloc_count. 3.5.3 only copied that word around; 3.5.4 walks it as
a list, so it segfaults on the first switch.

Locate the field at import instead of trusting offsetof(). Reading back a
data descriptor puts us inside _PyObject_GenericGetAttrWithDict, which
has the real layout and holds a _PyCStackRef to that descriptor while it
calls __get__; the word of the thread state pointing at that node is
c_stack_refs. The search is bounded by two of our own stack markers and
matched against the descriptor. If it comes up empty on an interpreter we
were not built for, import fails instead of the first switch.

Tested on 3.14.6t, 3.15.0b2t, 3.14.6 and 3.13.14, plus wheels built for
3.14.6 run on 3.14.3 and the reverse.

Fixes python-greenlet#527
@jamadden

Copy link
Copy Markdown
Contributor

I very much appreciate the effort, but I'm disinclined to merge this. I don't like all the assumptions and mucking around used to try to figure out the offset. I think the solution is much simpler: If you're using a binary wheel and it's crashing, either upgrade your Python interpreter, or build greenlet from source.

3.14.4 was released back in April and we're up to 3.14.7 now, so there are more releases that are compatible with the built wheels released yesterday than there are incompatible and over time that number will only continue to go up. So I don't see much value in catering to a shrinking userbase with a significant chunk of complex code when the solutions of either upgrading your interpreter or building from source are so easy.

@ddorian

ddorian commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

Makes sense, I agree.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

free-threaded c_stack_refs offset between different python versions using the same wheel

2 participants