From 22b69c8c6af69d1a4192eb67239ef8a1639a575c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=A1l=20Gy=C3=B6rgy?= Date: Mon, 6 Jul 2026 14:20:38 +0200 Subject: [PATCH] feat(ebpf/python): add CPython 3.14 offsets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Python 3.14 processes were not profiled: pyVersions had no {3, 14, *} entry, so GetUserOffsets returned "unsupported version" (patch-guessing only spans a single major.minor). Add the 3.14.0 offsets for amd64 and arm64, generated by python_dwarfdump from a release-config CPython 3.14.0 build (--enable-shared, -gdwarf-4, no --with-pydebug). amd64 and arm64 offsets are identical, matching the existing 3.13 entries. Offsets reflect real 3.14 layout changes verified with pahole, e.g. PyTupleObject gained Py_hash_t ob_hash, moving ob_item from 24 to 32. The offset-driven eBPF unwinder and the existing >= Py313 code path handle 3.14 with no further changes. Also make python_dwarfdump tolerant of forward-declaration DIEs (DW_AT_declaration, no byte_size) that modern GCC emits across compilation units: GetTypeByName2 now skips the incomplete entry and keeps the complete definition instead of panicking. Signed-off-by: Gaál György --- ebpf/dwarfdump/dwarfdump.go | 5 +++- ebpf/python/python_offsets_gen_amd64.go | 34 +++++++++++++++++++++++++ ebpf/python/python_offsets_gen_arm64.go | 34 +++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/ebpf/dwarfdump/dwarfdump.go b/ebpf/dwarfdump/dwarfdump.go index d96247e8dc..1bbebf7acc 100644 --- a/ebpf/dwarfdump/dwarfdump.go +++ b/ebpf/dwarfdump/dwarfdump.go @@ -53,7 +53,10 @@ func (i *Index) GetTypeByName2(name string) *Typ { for _, offset := range typedef.TypeOffsets { typ := i.offset2Type[offset] if typ == nil { - panic(fmt.Sprintf("%s %d not found", name, offset)) + // Forward declaration (DW_AT_declaration, no byte_size): the type is + // defined completely in another compilation unit. Skip the incomplete + // entry and keep looking for the real definition. + continue } res = append(res, typ) if len(res) > 0 { diff --git a/ebpf/python/python_offsets_gen_amd64.go b/ebpf/python/python_offsets_gen_amd64.go index 806ee6681d..c79177241f 100644 --- a/ebpf/python/python_offsets_gen_amd64.go +++ b/ebpf/python/python_offsets_gen_amd64.go @@ -3819,4 +3819,38 @@ var pyVersions = map[Version]*UserOffsets{ PyCompactUnicodeObjectSize: 56, PyCellObject__ob_ref: 16, }, + {3, 14, 0}: { + PyVarObject_ob_size: 16, + PyObject_ob_type: 8, + PyTypeObject_tp_name: 24, + PyThreadState_frame: -1, + PyThreadState_cframe: -1, + PyThreadState_current_frame: 72, + PyCFrame_current_frame: -1, + PyFrameObject_f_back: 16, + PyFrameObject_f_code: -1, + PyFrameObject_f_localsplus: -1, + PyCodeObject_co_filename: 112, + PyCodeObject_co_name: 120, + PyCodeObject_co_varnames: -1, + PyCodeObject_co_localsplusnames: 96, + PyCodeObject__co_cell2arg: -1, + PyCodeObject__co_cellvars: -1, + PyCodeObject__co_nlocals: 80, + PyTupleObject_ob_item: 32, + PyInterpreterFrame_f_code: -1, + PyInterpreterFrame_f_executable: 0, + PyInterpreterFrame_previous: 8, + PyInterpreterFrame_localsplus: 80, + PyInterpreterFrame_owner: 74, + PyRuntimeState_gilstate: 10064, + PyRuntimeState_autoTSSkey: 2336, + Gilstate_runtime_state_autoTSSkey: -1, + PyTssT_is_initialized: 0, + PyTssT_key: 4, + PyTssTSize: 8, + PyASCIIObjectSize: 40, + PyCompactUnicodeObjectSize: 56, + PyCellObject__ob_ref: 16, + }, } diff --git a/ebpf/python/python_offsets_gen_arm64.go b/ebpf/python/python_offsets_gen_arm64.go index 101e9883d3..b3a44988bb 100644 --- a/ebpf/python/python_offsets_gen_arm64.go +++ b/ebpf/python/python_offsets_gen_arm64.go @@ -3819,4 +3819,38 @@ var pyVersions = map[Version]*UserOffsets{ PyCompactUnicodeObjectSize: 56, PyCellObject__ob_ref: 16, }, + {3, 14, 0}: { + PyVarObject_ob_size: 16, + PyObject_ob_type: 8, + PyTypeObject_tp_name: 24, + PyThreadState_frame: -1, + PyThreadState_cframe: -1, + PyThreadState_current_frame: 72, + PyCFrame_current_frame: -1, + PyFrameObject_f_back: 16, + PyFrameObject_f_code: -1, + PyFrameObject_f_localsplus: -1, + PyCodeObject_co_filename: 112, + PyCodeObject_co_name: 120, + PyCodeObject_co_varnames: -1, + PyCodeObject_co_localsplusnames: 96, + PyCodeObject__co_cell2arg: -1, + PyCodeObject__co_cellvars: -1, + PyCodeObject__co_nlocals: 80, + PyTupleObject_ob_item: 32, + PyInterpreterFrame_f_code: -1, + PyInterpreterFrame_f_executable: 0, + PyInterpreterFrame_previous: 8, + PyInterpreterFrame_localsplus: 80, + PyInterpreterFrame_owner: 74, + PyRuntimeState_gilstate: 10064, + PyRuntimeState_autoTSSkey: 2336, + Gilstate_runtime_state_autoTSSkey: -1, + PyTssT_is_initialized: 0, + PyTssT_key: 4, + PyTssTSize: 8, + PyASCIIObjectSize: 40, + PyCompactUnicodeObjectSize: 56, + PyCellObject__ob_ref: 16, + }, }