Skip to content

Commit 0e1b1ee

Browse files
committed
Remove hardcoded offsets for Python 3.14 and 3.15
These offsets are no longer used for anything in the overwhelming majority of cases. The only way that they could be used is if a process running a modern version of Python managed to trash memory in a way that corrupted the `_Py_DebugOffsets` structure in memory. And unfortunately, even in that case, we would go on to behave incorrectly: the Python 3.14 debug offsets were wrong. Since these aren't being used and haven't been being well maintained, and since they're impossible to properly test, and since they're impossible to make work for multiple different interpreter flavors (GIL vs free-threading, JIT vs no-JIT, etc) and they could even change between two patch versions of the interpreter for the same flavor, let's just remove them and turn it into a hard failure if someone manages to trash memory so badly that the `_Py_DebugOffsets` structure can't be used. Signed-off-by: Matt Wozniski <mwozniski@bloomberg.net>
1 parent d58e67f commit 0e1b1ee

10 files changed

Lines changed: 136 additions & 509 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ classifiers = [
2222
"Programming Language :: Python :: 3.12",
2323
"Programming Language :: Python :: 3.13",
2424
"Programming Language :: Python :: 3.14",
25+
"Programming Language :: Python :: 3.15",
2526
"Programming Language :: Python :: Implementation :: CPython",
2627
"Topic :: Software Development :: Debuggers",
2728
]

src/pystack/_pystack/cpython/code.h

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -197,82 +197,4 @@ typedef struct
197197
} PyCodeObject;
198198
} // namespace Python3_13
199199

200-
namespace Python3_14 {
201-
typedef uint16_t _Py_CODEUNIT;
202-
203-
typedef struct
204-
{
205-
PyObject_VAR_HEAD PyObject* co_consts;
206-
PyObject* co_names;
207-
PyObject* co_exceptiontable;
208-
int co_flags;
209-
int co_argcount;
210-
int co_posonlyargcount;
211-
int co_kwonlyargcount;
212-
int co_stacksize;
213-
int co_firstlineno;
214-
int co_nlocalsplus;
215-
int co_framesize;
216-
int co_nlocals;
217-
int co_ncellvars;
218-
int co_nfreevars;
219-
uint32_t co_version;
220-
PyObject* co_localsplusnames;
221-
PyObject* co_localspluskinds;
222-
PyObject* co_filename;
223-
PyObject* co_name;
224-
PyObject* co_qualname;
225-
PyObject* co_linetable;
226-
PyObject* co_weakreflist;
227-
void* co_executors;
228-
void* _co_cached;
229-
uintptr_t _co_instrumentation_version;
230-
void* _co_monitoring;
231-
Py_ssize_t _co_unique_id;
232-
int _co_firsttraceable;
233-
void* co_extra;
234-
/* deal with co_tlbc somehow */
235-
char co_code_adaptive[1];
236-
} PyCodeObject;
237-
} // namespace Python3_14
238-
239-
namespace Python3_15 {
240-
typedef uint16_t _Py_CODEUNIT;
241-
242-
typedef struct
243-
{
244-
PyObject_VAR_HEAD PyObject* co_consts;
245-
PyObject* co_names;
246-
PyObject* co_exceptiontable;
247-
int co_flags;
248-
int co_argcount;
249-
int co_posonlyargcount;
250-
int co_kwonlyargcount;
251-
int co_stacksize;
252-
int co_firstlineno;
253-
int co_nlocalsplus;
254-
int co_framesize;
255-
int co_nlocals;
256-
int co_ncellvars;
257-
int co_nfreevars;
258-
uint32_t co_version;
259-
PyObject* co_localsplusnames;
260-
PyObject* co_localspluskinds;
261-
PyObject* co_filename;
262-
PyObject* co_name;
263-
PyObject* co_qualname;
264-
PyObject* co_linetable;
265-
PyObject* co_weakreflist;
266-
void* co_executors;
267-
void* _co_cached;
268-
uintptr_t _co_instrumentation_version;
269-
void* _co_monitoring;
270-
Py_ssize_t _co_unique_id;
271-
int _co_firsttraceable;
272-
void* co_extra;
273-
/* deal with co_tlbc somehow */
274-
char co_code_adaptive[1];
275-
} PyCodeObject;
276-
} // namespace Python3_15
277-
278200
} // namespace pystack

src/pystack/_pystack/cpython/frame.h

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -147,24 +147,6 @@ typedef union _PyStackRef {
147147
uintptr_t bits;
148148
} _PyStackRef;
149149

150-
typedef struct _interpreter_frame
151-
{
152-
_PyStackRef f_executable;
153-
void* previous;
154-
void* f_funcobj;
155-
PyObject* f_globals;
156-
PyObject* f_builtins;
157-
PyObject* f_locals;
158-
PyObject* frame_obj;
159-
_Py_CODEUNIT* instr_ptr;
160-
_PyStackRef stackpointer;
161-
/* int32_t tlbc_index; */
162-
uint16_t return_offset;
163-
char owner;
164-
uint8_t visited;
165-
void* localsplus[1];
166-
} PyFrameObject;
167-
168150
} // namespace Python3_14
169151

170152
} // namespace pystack

src/pystack/_pystack/cpython/gc.h

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -83,48 +83,4 @@ struct _gc_runtime_state
8383

8484
} // namespace Python3_8
8585

86-
namespace Python3_14 {
87-
88-
struct _gc_runtime_state
89-
{
90-
PyObject* trash_delete_later;
91-
int trash_delete_nesting;
92-
int enabled;
93-
int debug;
94-
struct Python3_8::gc_generation young;
95-
struct Python3_8::gc_generation old[2];
96-
struct Python3_8::gc_generation permanent_generation;
97-
struct gc_generation_stats generation_stats[NUM_GENERATIONS];
98-
int collecting;
99-
PyObject* garbage;
100-
PyObject* callbacks;
101-
Py_ssize_t heap_size;
102-
Py_ssize_t work_to_do;
103-
int visited_space;
104-
int phase;
105-
};
106-
107-
} // namespace Python3_14
108-
109-
namespace Python3_15 {
110-
111-
struct _gc_runtime_state
112-
{
113-
int enabled;
114-
int debug;
115-
struct Python3_8::gc_generation young;
116-
struct Python3_8::gc_generation old[2];
117-
struct Python3_8::gc_generation permanent_generation;
118-
struct gc_generation_stats generation_stats[NUM_GENERATIONS];
119-
int collecting;
120-
struct _PyInterpreterFrame* frame;
121-
PyObject* garbage;
122-
PyObject* callbacks;
123-
Py_ssize_t heap_size;
124-
Py_ssize_t long_lived_total;
125-
Py_ssize_t long_lived_pending;
126-
};
127-
128-
} // namespace Python3_15
129-
13086
} // namespace pystack

src/pystack/_pystack/cpython/interpreter.h

Lines changed: 0 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -339,157 +339,4 @@ typedef struct _is
339339
} PyInterpreterState;
340340
} // namespace Python3_13
341341

342-
namespace Python3_14 {
343-
344-
struct _pythreadstate;
345-
346-
typedef struct
347-
{
348-
Python3_13::PyMutex mutex;
349-
unsigned long long thread;
350-
size_t level;
351-
} _PyRecursiveMutex;
352-
353-
struct _import_state
354-
{
355-
PyObject* modules;
356-
PyObject* modules_by_index;
357-
PyObject* importlib;
358-
int override_frozen_modules;
359-
int override_multi_interp_extensions_check;
360-
PyObject* import_func;
361-
_PyRecursiveMutex lock;
362-
/* diagnostic info in PyImport_ImportModuleLevelObject() */
363-
struct
364-
{
365-
int import_level;
366-
int64_t accumulated;
367-
int header;
368-
} find_and_load;
369-
};
370-
371-
struct _gil_runtime_state
372-
{
373-
unsigned long interval;
374-
struct _pythreadstate* last_holder;
375-
int locked;
376-
unsigned long switch_number;
377-
pthread_cond_t cond;
378-
pthread_cond_t mutex;
379-
#ifdef FORCE_SWITCHING
380-
pthread_cond_t switch_cond;
381-
pthread_cond_t switch_mutex;
382-
#endif
383-
};
384-
385-
typedef struct _is
386-
{
387-
struct _ceval_state ceval;
388-
void* _malloced;
389-
struct _is* next;
390-
int64_t id;
391-
Py_ssize_t id_refcount;
392-
int requires_idref;
393-
long _whence;
394-
int _initialized;
395-
int _ready;
396-
int finalizing;
397-
uintptr_t last_restart_version;
398-
struct pythreads
399-
{
400-
uint64_t next_unique_id;
401-
struct _pythreadstate* head;
402-
struct _pythreadstate* preallocated;
403-
struct _pythreadstate* main;
404-
Py_ssize_t count;
405-
size_t stacksize;
406-
} threads;
407-
void* runtime;
408-
struct _pythreadstate* _finalizing;
409-
unsigned long _finalizing_id;
410-
struct _gc_runtime_state gc;
411-
PyObject* sysdict;
412-
PyObject* builtins;
413-
struct _import_state imports;
414-
struct _gil_runtime_state _gil;
415-
} PyInterpreterState;
416-
417-
} // namespace Python3_14
418-
419-
namespace Python3_15 {
420-
421-
struct _pythreadstate;
422-
423-
typedef struct
424-
{
425-
Python3_13::PyMutex mutex;
426-
unsigned long long thread;
427-
size_t level;
428-
} _PyRecursiveMutex;
429-
430-
struct _import_state
431-
{
432-
PyObject* modules;
433-
PyObject* modules_by_index;
434-
PyObject* importlib;
435-
int override_frozen_modules;
436-
int override_multi_interp_extensions_check;
437-
PyObject* import_func;
438-
_PyRecursiveMutex lock;
439-
/* diagnostic info in PyImport_ImportModuleLevelObject() */
440-
struct
441-
{
442-
int import_level;
443-
int64_t accumulated;
444-
int header;
445-
} find_and_load;
446-
};
447-
448-
struct _gil_runtime_state
449-
{
450-
unsigned long interval;
451-
struct _pythreadstate* last_holder;
452-
int locked;
453-
unsigned long switch_number;
454-
pthread_cond_t cond;
455-
pthread_cond_t mutex;
456-
#ifdef FORCE_SWITCHING
457-
pthread_cond_t switch_cond;
458-
pthread_cond_t switch_mutex;
459-
#endif
460-
};
461-
462-
typedef struct _is
463-
{
464-
struct _ceval_state ceval;
465-
struct _is* next;
466-
int64_t id;
467-
Py_ssize_t id_refcount;
468-
int requires_idref;
469-
long _whence;
470-
int _initialized;
471-
int _ready;
472-
int finalizing;
473-
uintptr_t last_restart_version;
474-
struct pythreads
475-
{
476-
uint64_t next_unique_id;
477-
struct _pythreadstate* head;
478-
struct _pythreadstate* preallocated;
479-
struct _pythreadstate* main;
480-
Py_ssize_t count;
481-
size_t stacksize;
482-
} threads;
483-
void* runtime;
484-
struct _pythreadstate* _finalizing;
485-
unsigned long _finalizing_id;
486-
struct _gc_runtime_state gc;
487-
PyObject* sysdict;
488-
PyObject* builtins;
489-
struct _import_state imports;
490-
struct _gil_runtime_state _gil;
491-
} PyInterpreterState;
492-
493-
} // namespace Python3_15
494-
495342
} // namespace pystack

src/pystack/_pystack/cpython/runtime.h

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -619,21 +619,6 @@ typedef struct _Py_DebugOffsets
619619
typedef struct pyruntimestate
620620
{
621621
_Py_DebugOffsets debug_offsets;
622-
int _initialized;
623-
int preinitializing;
624-
int preinitialized;
625-
int core_initialized;
626-
int initialized;
627-
struct _pythreadstate* finalizing;
628-
unsigned long _finalizing_id;
629-
630-
struct pyinterpreters
631-
{
632-
Python3_13::PyMutex mutex;
633-
PyInterpreterState* head;
634-
PyInterpreterState* main;
635-
int64_t next_id;
636-
} interpreters;
637622
} PyRuntimeState;
638623

639624
} // namespace Python3_14
@@ -859,21 +844,6 @@ typedef struct _Py_DebugOffsets
859844
typedef struct pyruntimestate
860845
{
861846
_Py_DebugOffsets debug_offsets;
862-
int _initialized;
863-
int preinitializing;
864-
int preinitialized;
865-
int core_initialized;
866-
int initialized;
867-
struct _pythreadstate* finalizing;
868-
unsigned long _finalizing_id;
869-
870-
struct pyinterpreters
871-
{
872-
Python3_13::PyMutex mutex;
873-
PyInterpreterState* head;
874-
PyInterpreterState* main;
875-
int64_t next_id;
876-
} interpreters;
877847
} PyRuntimeState;
878848

879849
} // namespace Python3_15

src/pystack/_pystack/cpython/string.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -122,23 +122,9 @@ struct _PyUnicode_State
122122

123123
} // namespace Python3_14t
124124

125-
namespace Python3_15t {
126-
127-
struct _PyUnicode_State
128-
{
129-
unsigned char interned;
130-
unsigned int kind : 3;
131-
unsigned int compact : 1;
132-
unsigned int ascii : 1;
133-
unsigned int statically_allocated : 1;
134-
};
135-
136-
} // namespace Python3_15t
137-
138125
union AnyPyUnicodeState {
139126
Python3::_PyUnicode_State python3;
140127
Python3_14t::_PyUnicode_State python3_14t;
141-
Python3_15t::_PyUnicode_State python3_15t;
142128
};
143129

144130
} // namespace pystack

0 commit comments

Comments
 (0)