mirror of https://github.com/python/cpython
Add debug offsets for free threaded builds (#123041)
This commit is contained in:
parent
b15b81ed4f
commit
d7a3df9150
|
@ -44,6 +44,15 @@ struct _gilstate_runtime_state {
|
||||||
|
|
||||||
/* Runtime audit hook state */
|
/* Runtime audit hook state */
|
||||||
|
|
||||||
|
#define _Py_Debug_Cookie "xdebugpy"
|
||||||
|
|
||||||
|
#ifdef Py_GIL_DISABLED
|
||||||
|
# define _Py_Debug_gilruntimestate_enabled offsetof(struct _gil_runtime_state, enabled)
|
||||||
|
# define _Py_Debug_Free_Threaded 1
|
||||||
|
#else
|
||||||
|
# define _Py_Debug_gilruntimestate_enabled 0
|
||||||
|
# define _Py_Debug_Free_Threaded 0
|
||||||
|
#endif
|
||||||
typedef struct _Py_AuditHookEntry {
|
typedef struct _Py_AuditHookEntry {
|
||||||
struct _Py_AuditHookEntry *next;
|
struct _Py_AuditHookEntry *next;
|
||||||
Py_AuditHookFunction hookCFunction;
|
Py_AuditHookFunction hookCFunction;
|
||||||
|
@ -53,6 +62,7 @@ typedef struct _Py_AuditHookEntry {
|
||||||
typedef struct _Py_DebugOffsets {
|
typedef struct _Py_DebugOffsets {
|
||||||
char cookie[8];
|
char cookie[8];
|
||||||
uint64_t version;
|
uint64_t version;
|
||||||
|
uint64_t free_threaded;
|
||||||
// Runtime state offset;
|
// Runtime state offset;
|
||||||
struct _runtime_state {
|
struct _runtime_state {
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
|
@ -71,6 +81,8 @@ typedef struct _Py_DebugOffsets {
|
||||||
uint64_t sysdict;
|
uint64_t sysdict;
|
||||||
uint64_t builtins;
|
uint64_t builtins;
|
||||||
uint64_t ceval_gil;
|
uint64_t ceval_gil;
|
||||||
|
uint64_t gil_runtime_state;
|
||||||
|
uint64_t gil_runtime_state_enabled;
|
||||||
uint64_t gil_runtime_state_locked;
|
uint64_t gil_runtime_state_locked;
|
||||||
uint64_t gil_runtime_state_holder;
|
uint64_t gil_runtime_state_holder;
|
||||||
} interpreter_state;
|
} interpreter_state;
|
||||||
|
@ -122,20 +134,57 @@ typedef struct _Py_DebugOffsets {
|
||||||
struct _type_object {
|
struct _type_object {
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
uint64_t tp_name;
|
uint64_t tp_name;
|
||||||
|
uint64_t tp_repr;
|
||||||
|
uint64_t tp_flags;
|
||||||
} type_object;
|
} type_object;
|
||||||
|
|
||||||
// PyTuple object offset;
|
// PyTuple object offset;
|
||||||
struct _tuple_object {
|
struct _tuple_object {
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
uint64_t ob_item;
|
uint64_t ob_item;
|
||||||
|
uint64_t ob_size;
|
||||||
} tuple_object;
|
} tuple_object;
|
||||||
|
|
||||||
|
// PyList object offset;
|
||||||
|
struct _list_object {
|
||||||
|
uint64_t size;
|
||||||
|
uint64_t ob_item;
|
||||||
|
uint64_t ob_size;
|
||||||
|
} list_object;
|
||||||
|
|
||||||
|
// PyDict object offset;
|
||||||
|
struct _dict_object {
|
||||||
|
uint64_t size;
|
||||||
|
uint64_t ma_keys;
|
||||||
|
uint64_t ma_values;
|
||||||
|
} dict_object;
|
||||||
|
|
||||||
|
// PyFloat object offset;
|
||||||
|
struct _float_object {
|
||||||
|
uint64_t size;
|
||||||
|
uint64_t ob_fval;
|
||||||
|
} float_object;
|
||||||
|
|
||||||
|
// PyLong object offset;
|
||||||
|
struct _long_object {
|
||||||
|
uint64_t size;
|
||||||
|
uint64_t lv_tag;
|
||||||
|
uint64_t ob_digit;
|
||||||
|
} long_object;
|
||||||
|
|
||||||
|
// PyBytes object offset;
|
||||||
|
struct _bytes_object {
|
||||||
|
uint64_t size;
|
||||||
|
uint64_t ob_size;
|
||||||
|
uint64_t ob_sval;
|
||||||
|
} bytes_object;
|
||||||
|
|
||||||
// Unicode object offset;
|
// Unicode object offset;
|
||||||
struct _unicode_object {
|
struct _unicode_object {
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
uint64_t state;
|
uint64_t state;
|
||||||
uint64_t length;
|
uint64_t length;
|
||||||
size_t asciiobject_size;
|
uint64_t asciiobject_size;
|
||||||
} unicode_object;
|
} unicode_object;
|
||||||
|
|
||||||
// GC runtime state offset;
|
// GC runtime state offset;
|
||||||
|
|
|
@ -29,11 +29,12 @@ extern PyTypeObject _PyExc_MemoryError;
|
||||||
/* The static initializers defined here should only be used
|
/* The static initializers defined here should only be used
|
||||||
in the runtime init code (in pystate.c and pylifecycle.c). */
|
in the runtime init code (in pystate.c and pylifecycle.c). */
|
||||||
|
|
||||||
#define _PyRuntimeState_INIT(runtime) \
|
#define _PyRuntimeState_INIT(runtime, debug_cookie) \
|
||||||
{ \
|
{ \
|
||||||
.debug_offsets = { \
|
.debug_offsets = { \
|
||||||
.cookie = "xdebugpy", \
|
.cookie = debug_cookie, \
|
||||||
.version = PY_VERSION_HEX, \
|
.version = PY_VERSION_HEX, \
|
||||||
|
.free_threaded = _Py_Debug_Free_Threaded, \
|
||||||
.runtime_state = { \
|
.runtime_state = { \
|
||||||
.size = sizeof(_PyRuntimeState), \
|
.size = sizeof(_PyRuntimeState), \
|
||||||
.finalizing = offsetof(_PyRuntimeState, _finalizing), \
|
.finalizing = offsetof(_PyRuntimeState, _finalizing), \
|
||||||
|
@ -49,6 +50,8 @@ extern PyTypeObject _PyExc_MemoryError;
|
||||||
.sysdict = offsetof(PyInterpreterState, sysdict), \
|
.sysdict = offsetof(PyInterpreterState, sysdict), \
|
||||||
.builtins = offsetof(PyInterpreterState, builtins), \
|
.builtins = offsetof(PyInterpreterState, builtins), \
|
||||||
.ceval_gil = offsetof(PyInterpreterState, ceval.gil), \
|
.ceval_gil = offsetof(PyInterpreterState, ceval.gil), \
|
||||||
|
.gil_runtime_state = offsetof(PyInterpreterState, _gil), \
|
||||||
|
.gil_runtime_state_enabled = _Py_Debug_gilruntimestate_enabled, \
|
||||||
.gil_runtime_state_locked = offsetof(PyInterpreterState, _gil.locked), \
|
.gil_runtime_state_locked = offsetof(PyInterpreterState, _gil.locked), \
|
||||||
.gil_runtime_state_holder = offsetof(PyInterpreterState, _gil.last_holder), \
|
.gil_runtime_state_holder = offsetof(PyInterpreterState, _gil.last_holder), \
|
||||||
}, \
|
}, \
|
||||||
|
@ -90,10 +93,37 @@ extern PyTypeObject _PyExc_MemoryError;
|
||||||
.type_object = { \
|
.type_object = { \
|
||||||
.size = sizeof(PyTypeObject), \
|
.size = sizeof(PyTypeObject), \
|
||||||
.tp_name = offsetof(PyTypeObject, tp_name), \
|
.tp_name = offsetof(PyTypeObject, tp_name), \
|
||||||
|
.tp_repr = offsetof(PyTypeObject, tp_repr), \
|
||||||
|
.tp_flags = offsetof(PyTypeObject, tp_flags), \
|
||||||
}, \
|
}, \
|
||||||
.tuple_object = { \
|
.tuple_object = { \
|
||||||
.size = sizeof(PyTupleObject), \
|
.size = sizeof(PyTupleObject), \
|
||||||
.ob_item = offsetof(PyTupleObject, ob_item), \
|
.ob_item = offsetof(PyTupleObject, ob_item), \
|
||||||
|
.ob_size = offsetof(PyTupleObject, ob_base.ob_size), \
|
||||||
|
}, \
|
||||||
|
.list_object = { \
|
||||||
|
.size = sizeof(PyListObject), \
|
||||||
|
.ob_item = offsetof(PyListObject, ob_item), \
|
||||||
|
.ob_size = offsetof(PyListObject, ob_base.ob_size), \
|
||||||
|
}, \
|
||||||
|
.dict_object = { \
|
||||||
|
.size = sizeof(PyDictObject), \
|
||||||
|
.ma_keys = offsetof(PyDictObject, ma_keys), \
|
||||||
|
.ma_values = offsetof(PyDictObject, ma_values), \
|
||||||
|
}, \
|
||||||
|
.float_object = { \
|
||||||
|
.size = sizeof(PyFloatObject), \
|
||||||
|
.ob_fval = offsetof(PyFloatObject, ob_fval), \
|
||||||
|
}, \
|
||||||
|
.long_object = { \
|
||||||
|
.size = sizeof(PyLongObject), \
|
||||||
|
.lv_tag = offsetof(_PyLongValue, lv_tag), \
|
||||||
|
.ob_digit = offsetof(_PyLongValue, ob_digit), \
|
||||||
|
}, \
|
||||||
|
.bytes_object = { \
|
||||||
|
.size = sizeof(PyBytesObject), \
|
||||||
|
.ob_size = offsetof(PyBytesObject, ob_base.ob_size), \
|
||||||
|
.ob_sval = offsetof(PyBytesObject, ob_sval), \
|
||||||
}, \
|
}, \
|
||||||
.unicode_object = { \
|
.unicode_object = { \
|
||||||
.size = sizeof(PyUnicodeObject), \
|
.size = sizeof(PyUnicodeObject), \
|
||||||
|
|
|
@ -104,7 +104,7 @@ _PyRuntimeState _PyRuntime
|
||||||
#if defined(__linux__) && (defined(__GNUC__) || defined(__clang__))
|
#if defined(__linux__) && (defined(__GNUC__) || defined(__clang__))
|
||||||
__attribute__ ((section (".PyRuntime")))
|
__attribute__ ((section (".PyRuntime")))
|
||||||
#endif
|
#endif
|
||||||
= _PyRuntimeState_INIT(_PyRuntime);
|
= _PyRuntimeState_INIT(_PyRuntime, _Py_Debug_Cookie);
|
||||||
_Py_COMP_DIAG_POP
|
_Py_COMP_DIAG_POP
|
||||||
|
|
||||||
static int runtime_initialized = 0;
|
static int runtime_initialized = 0;
|
||||||
|
|
|
@ -390,7 +390,7 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
|
||||||
Note that we initialize "initial" relative to _PyRuntime,
|
Note that we initialize "initial" relative to _PyRuntime,
|
||||||
to ensure pre-initialized pointers point to the active
|
to ensure pre-initialized pointers point to the active
|
||||||
runtime state (and not "initial"). */
|
runtime state (and not "initial"). */
|
||||||
static const _PyRuntimeState initial = _PyRuntimeState_INIT(_PyRuntime);
|
static const _PyRuntimeState initial = _PyRuntimeState_INIT(_PyRuntime, "");
|
||||||
_Py_COMP_DIAG_POP
|
_Py_COMP_DIAG_POP
|
||||||
|
|
||||||
#define LOCKS_INIT(runtime) \
|
#define LOCKS_INIT(runtime) \
|
||||||
|
@ -455,6 +455,8 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
|
||||||
// Py_Initialize() must be running again.
|
// Py_Initialize() must be running again.
|
||||||
// Reset to _PyRuntimeState_INIT.
|
// Reset to _PyRuntimeState_INIT.
|
||||||
memcpy(runtime, &initial, sizeof(*runtime));
|
memcpy(runtime, &initial, sizeof(*runtime));
|
||||||
|
// Preserve the cookie from the original runtime.
|
||||||
|
memcpy(runtime->debug_offsets.cookie, _Py_Debug_Cookie, 8);
|
||||||
assert(!runtime->_initialized);
|
assert(!runtime->_initialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue