Skip to content

pyunwind: measure code-object offsets for CPython 3.13 and 3.14 (#83) - #132

Merged
dpsoft merged 1 commit into
mainfrom
feat/python-offsets-313-314
Sep 4, 2026
Merged

pyunwind: measure code-object offsets for CPython 3.13 and 3.14 (#83)#132
dpsoft merged 1 commit into
mainfrom
feat/python-offsets-313-314

Conversation

@dpsoft

@dpsoft dpsoft commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Only 3.12 had measured code-object offsets, so 3.13 and 3.14 silently rendered python:0x… — and Fedora's system interpreter is 3.14, so the default Python on a common distribution got no names at all from the change that added them.

Measured with offsetof against each version's own headers (obtained with uv python install, no system packages needed).

The values agree, and that is a hazard

All three carry the same offsets — co_filename=112, co_name=120, co_qualname=128, co_firstlineno=68.

A bug returning 3.12's table for every version would therefore be invisible in the numbers. So each was measured separately against its own headers, and the live test now runs per version rather than against whichever interpreter it found first — a single-version test would pass just as happily on the broken table.

Verified against real interpreters

interpreter result
3.12.14 (uv, the venv) Widget.method_here at target.py:4
3.13.15 (uv) same
3.14.7 (uv) same
3.14.3 (Fedora system) same — a different build from the 3.14.7 the offsets came from

That last row is the one that matters: it shows the layout is a property of the CPython version rather than of the particular build the headers came from.

Still declines what it has not measured

An unsupported version gets no code offsets rather than a neighbour's table. Reading co_qualname at the wrong offset yields a pointer to something that is not a string, and the frame would be named from whatever it found — asserted, so a future version added to the frame table without measuring its code layout cannot quietly inherit one.

Only 3.12 had them, so 3.13 and 3.14 silently rendered python:0x… -- and
Fedora's system interpreter is 3.14, which means the default Python on a
common distribution got no names at all from the change that added them.

Measured with offsetof against each version's own headers. All three carry the
same values (co_filename=112, co_name=120, co_qualname=128,
co_firstlineno=68), and that agreement is a hazard as much as a convenience: a
bug returning 3.12's table for every version would be invisible in the numbers.
So each was measured separately, and each is verified end to end against a LIVE
interpreter of that version -- the live test now runs per version rather than
against whichever one it found first, because a single-version test would pass
just as happily on the broken table.

Validated on four interpreters, including Fedora's system 3.14.3, which is a
different build from the 3.14.7 the offsets were taken from: all resolve
Widget.method_here at target.py:4.

An unsupported version still declines rather than borrowing a neighbour's
table. Reading co_qualname at the wrong offset yields a pointer to something
that is not a string, and the frame would be named from whatever it found;
asserted, so a future version added to the frame table without measuring its
code layout cannot quietly inherit one.
@dpsoft
dpsoft merged commit b70c985 into main Sep 4, 2026
10 checks passed
@dpsoft
dpsoft deleted the feat/python-offsets-313-314 branch September 4, 2026 23:00
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.

1 participant