@@ -107,14 +107,36 @@ validate_span(
107107 return 0 ;
108108}
109109
110+ static inline int
111+ validate_alignment (
112+ const char * field_name ,
113+ uint64_t offset ,
114+ size_t alignment )
115+ {
116+ if (alignment > 1 && offset % alignment != 0 ) {
117+ PyErr_Format (
118+ PyExc_RuntimeError ,
119+ "Invalid debug offsets: %s=%llu is not aligned to %zu bytes" ,
120+ field_name ,
121+ (unsigned long long )offset ,
122+ alignment );
123+ return -1 ;
124+ }
125+ return 0 ;
126+ }
127+
110128static inline int
111129validate_field (
112130 const char * field_name ,
113131 uint64_t reported_size ,
114132 uint64_t offset ,
115133 size_t width ,
134+ size_t alignment ,
116135 size_t buffer_size )
117136{
137+ if (validate_alignment (field_name , offset , alignment ) < 0 ) {
138+ return -1 ;
139+ }
118140 if (validate_span (field_name , offset , width , reported_size , "reported size" ) < 0 ) {
119141 return -1 ;
120142 }
@@ -128,6 +150,7 @@ validate_nested_field(
128150 uint64_t base_offset ,
129151 uint64_t nested_offset ,
130152 size_t width ,
153+ size_t alignment ,
131154 size_t buffer_size )
132155{
133156 if (base_offset > UINT64_MAX - nested_offset ) {
@@ -142,6 +165,7 @@ validate_nested_field(
142165 reported_size ,
143166 base_offset + nested_offset ,
144167 width ,
168+ alignment ,
145169 buffer_size );
146170}
147171
@@ -150,8 +174,12 @@ validate_fixed_field(
150174 const char * field_name ,
151175 uint64_t offset ,
152176 size_t width ,
177+ size_t alignment ,
153178 size_t buffer_size )
154179{
180+ if (validate_alignment (field_name , offset , alignment ) < 0 ) {
181+ return -1 ;
182+ }
155183 return validate_span (field_name , offset , width , buffer_size , "local buffer size" );
156184}
157185
@@ -169,37 +197,40 @@ validate_fixed_field(
169197 } \
170198 } while (0)
171199
172- #define PY_REMOTE_DEBUG_VALIDATE_FIELD (section , field , field_size , buffer_size ) \
200+ #define PY_REMOTE_DEBUG_VALIDATE_FIELD (section , field , field_size , field_alignment , buffer_size ) \
173201 do { \
174202 if (validate_field( \
175203 #section "." #field, \
176204 debug_offsets->section.size, \
177205 debug_offsets->section.field, \
178206 field_size, \
207+ field_alignment, \
179208 buffer_size) < 0) { \
180209 return -1; \
181210 } \
182211 } while (0)
183212
184- #define PY_REMOTE_DEBUG_VALIDATE_NESTED_FIELD (section , base , nested_section , field , field_size , buffer_size ) \
213+ #define PY_REMOTE_DEBUG_VALIDATE_NESTED_FIELD (section , base , nested_section , field , field_size , field_alignment , buffer_size ) \
185214 do { \
186215 if (validate_nested_field( \
187216 #section "." #base "." #field, \
188217 debug_offsets->section.size, \
189218 debug_offsets->section.base, \
190219 debug_offsets->nested_section.field, \
191220 field_size, \
221+ field_alignment, \
192222 buffer_size) < 0) { \
193223 return -1; \
194224 } \
195225 } while (0)
196226
197- #define PY_REMOTE_DEBUG_VALIDATE_FIXED_FIELD (section , field , field_size , buffer_size ) \
227+ #define PY_REMOTE_DEBUG_VALIDATE_FIXED_FIELD (section , field , field_size , field_alignment , buffer_size ) \
198228 do { \
199229 if (validate_fixed_field( \
200230 #section "." #field, \
201231 debug_offsets->section.field, \
202232 field_size, \
233+ field_alignment, \
203234 buffer_size) < 0) { \
204235 return -1; \
205236 } \
@@ -216,84 +247,84 @@ validate_fixed_field(
216247 * the unwinder, so no validation is needed for them.
217248 */
218249#define PY_REMOTE_DEBUG_RUNTIME_STATE_FIELDS (APPLY , buffer_size ) \
219- APPLY(runtime_state, interpreters_head, sizeof(uintptr_t), buffer_size)
250+ APPLY(runtime_state, interpreters_head, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size)
220251
221252#define PY_REMOTE_DEBUG_THREAD_STATE_FIELDS (APPLY , buffer_size ) \
222- APPLY(thread_state, native_thread_id, sizeof(unsigned long), buffer_size); \
223- APPLY(thread_state, interp, sizeof(uintptr_t), buffer_size); \
224- APPLY(thread_state, datastack_chunk, sizeof(uintptr_t), buffer_size); \
225- APPLY(thread_state, status, FIELD_SIZE(PyThreadState, _status), buffer_size); \
226- APPLY(thread_state, holds_gil, sizeof(int), buffer_size); \
227- APPLY(thread_state, gil_requested, sizeof(int), buffer_size); \
228- APPLY(thread_state, current_exception, sizeof(uintptr_t), buffer_size); \
229- APPLY(thread_state, thread_id, sizeof(unsigned long), buffer_size); \
230- APPLY(thread_state, next, sizeof(uintptr_t), buffer_size); \
231- APPLY(thread_state, current_frame, sizeof(uintptr_t), buffer_size); \
232- APPLY(thread_state, base_frame, sizeof(uintptr_t), buffer_size); \
233- APPLY(thread_state, last_profiled_frame, sizeof(uintptr_t), buffer_size)
253+ APPLY(thread_state, native_thread_id, sizeof(unsigned long), _Alignof(long), buffer_size); \
254+ APPLY(thread_state, interp, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
255+ APPLY(thread_state, datastack_chunk, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
256+ APPLY(thread_state, status, FIELD_SIZE(PyThreadState, _status), _Alignof(unsigned int), buffer_size); \
257+ APPLY(thread_state, holds_gil, sizeof(int), _Alignof(int), buffer_size); \
258+ APPLY(thread_state, gil_requested, sizeof(int), _Alignof(int), buffer_size); \
259+ APPLY(thread_state, current_exception, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
260+ APPLY(thread_state, thread_id, sizeof(unsigned long), _Alignof(long), buffer_size); \
261+ APPLY(thread_state, next, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
262+ APPLY(thread_state, current_frame, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
263+ APPLY(thread_state, base_frame, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
264+ APPLY(thread_state, last_profiled_frame, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size)
234265
235266#define PY_REMOTE_DEBUG_INTERPRETER_STATE_FIELDS (APPLY , buffer_size ) \
236- APPLY(interpreter_state, id, sizeof(int64_t), buffer_size); \
237- APPLY(interpreter_state, next, sizeof(uintptr_t), buffer_size); \
238- APPLY(interpreter_state, threads_head, sizeof(uintptr_t), buffer_size); \
239- APPLY(interpreter_state, threads_main, sizeof(uintptr_t), buffer_size); \
240- APPLY(interpreter_state, gil_runtime_state_locked, sizeof(int), buffer_size); \
241- APPLY(interpreter_state, gil_runtime_state_holder, sizeof(PyThreadState *), buffer_size); \
242- APPLY(interpreter_state, code_object_generation, sizeof(uint64_t), buffer_size); \
243- APPLY(interpreter_state, tlbc_generation, sizeof(uint32_t), buffer_size)
267+ APPLY(interpreter_state, id, sizeof(int64_t), _Alignof(int64_t), buffer_size); \
268+ APPLY(interpreter_state, next, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
269+ APPLY(interpreter_state, threads_head, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
270+ APPLY(interpreter_state, threads_main, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
271+ APPLY(interpreter_state, gil_runtime_state_locked, sizeof(int), _Alignof(int), buffer_size); \
272+ APPLY(interpreter_state, gil_runtime_state_holder, sizeof(PyThreadState *), _Alignof(PyThreadState *), buffer_size); \
273+ APPLY(interpreter_state, code_object_generation, sizeof(uint64_t), _Alignof(uint64_t), buffer_size); \
274+ APPLY(interpreter_state, tlbc_generation, sizeof(uint32_t), _Alignof(uint32_t), buffer_size)
244275
245276#define PY_REMOTE_DEBUG_INTERPRETER_FRAME_FIELDS (APPLY , buffer_size ) \
246- APPLY(interpreter_frame, previous, sizeof(uintptr_t), buffer_size); \
247- APPLY(interpreter_frame, executable, sizeof(uintptr_t), buffer_size); \
248- APPLY(interpreter_frame, instr_ptr, sizeof(uintptr_t), buffer_size); \
249- APPLY(interpreter_frame, owner, sizeof(char), buffer_size); \
250- APPLY(interpreter_frame, stackpointer, sizeof(uintptr_t), buffer_size); \
251- APPLY(interpreter_frame, tlbc_index, sizeof(int32_t), buffer_size)
277+ APPLY(interpreter_frame, previous, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
278+ APPLY(interpreter_frame, executable, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
279+ APPLY(interpreter_frame, instr_ptr, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
280+ APPLY(interpreter_frame, owner, sizeof(char), _Alignof(char), buffer_size); \
281+ APPLY(interpreter_frame, stackpointer, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
282+ APPLY(interpreter_frame, tlbc_index, sizeof(int32_t), _Alignof(int32_t), buffer_size)
252283
253284#define PY_REMOTE_DEBUG_CODE_OBJECT_FIELDS (APPLY , buffer_size ) \
254- APPLY(code_object, qualname, sizeof(uintptr_t), buffer_size); \
255- APPLY(code_object, filename, sizeof(uintptr_t), buffer_size); \
256- APPLY(code_object, linetable, sizeof(uintptr_t), buffer_size); \
257- APPLY(code_object, firstlineno, sizeof(int), buffer_size); \
258- APPLY(code_object, co_code_adaptive, sizeof(char), buffer_size); \
259- APPLY(code_object, co_tlbc, sizeof(uintptr_t), buffer_size)
285+ APPLY(code_object, qualname, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
286+ APPLY(code_object, filename, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
287+ APPLY(code_object, linetable, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
288+ APPLY(code_object, firstlineno, sizeof(int), _Alignof(int), buffer_size); \
289+ APPLY(code_object, co_code_adaptive, sizeof(char), _Alignof(char), buffer_size); \
290+ APPLY(code_object, co_tlbc, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size)
260291
261292#define PY_REMOTE_DEBUG_SET_OBJECT_FIELDS (APPLY , buffer_size ) \
262- APPLY(set_object, used, sizeof(Py_ssize_t), buffer_size); \
263- APPLY(set_object, mask, sizeof(Py_ssize_t), buffer_size); \
264- APPLY(set_object, table, sizeof(uintptr_t), buffer_size)
293+ APPLY(set_object, used, sizeof(Py_ssize_t), _Alignof(Py_ssize_t), buffer_size); \
294+ APPLY(set_object, mask, sizeof(Py_ssize_t), _Alignof(Py_ssize_t), buffer_size); \
295+ APPLY(set_object, table, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size)
265296
266297#define PY_REMOTE_DEBUG_LONG_OBJECT_FIELDS (APPLY , buffer_size ) \
267- APPLY(long_object, lv_tag, sizeof(uintptr_t), buffer_size); \
268- APPLY(long_object, ob_digit, sizeof(digit), buffer_size)
298+ APPLY(long_object, lv_tag, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
299+ APPLY(long_object, ob_digit, sizeof(digit), _Alignof(digit), buffer_size)
269300
270301#define PY_REMOTE_DEBUG_BYTES_OBJECT_FIELDS (APPLY , buffer_size ) \
271- APPLY(bytes_object, ob_size, sizeof(Py_ssize_t), buffer_size); \
272- APPLY(bytes_object, ob_sval, sizeof(char), buffer_size)
302+ APPLY(bytes_object, ob_size, sizeof(Py_ssize_t), _Alignof(Py_ssize_t), buffer_size); \
303+ APPLY(bytes_object, ob_sval, sizeof(char), _Alignof(char), buffer_size)
273304
274305#define PY_REMOTE_DEBUG_UNICODE_OBJECT_FIELDS (APPLY , buffer_size ) \
275- APPLY(unicode_object, length, sizeof(Py_ssize_t), buffer_size); \
276- APPLY(unicode_object, asciiobject_size, sizeof(char), buffer_size)
306+ APPLY(unicode_object, length, sizeof(Py_ssize_t), _Alignof(Py_ssize_t), buffer_size); \
307+ APPLY(unicode_object, asciiobject_size, sizeof(char), _Alignof(char), buffer_size)
277308
278309#define PY_REMOTE_DEBUG_GEN_OBJECT_FIELDS (APPLY , buffer_size ) \
279- APPLY(gen_object, gi_frame_state, sizeof(int8_t), buffer_size); \
280- APPLY(gen_object, gi_iframe, FIELD_SIZE(PyGenObject, gi_iframe), buffer_size)
310+ APPLY(gen_object, gi_frame_state, sizeof(int8_t), _Alignof(int8_t), buffer_size); \
311+ APPLY(gen_object, gi_iframe, FIELD_SIZE(PyGenObject, gi_iframe), _Alignof(_PyInterpreterFrame), buffer_size)
281312
282313#define PY_REMOTE_DEBUG_TASK_OBJECT_FIELDS (APPLY , buffer_size ) \
283- APPLY(asyncio_task_object, task_name, sizeof(uintptr_t), buffer_size); \
284- APPLY(asyncio_task_object, task_awaited_by, sizeof(uintptr_t), buffer_size); \
285- APPLY(asyncio_task_object, task_is_task, sizeof(char), buffer_size); \
286- APPLY(asyncio_task_object, task_awaited_by_is_set, sizeof(char), buffer_size); \
287- APPLY(asyncio_task_object, task_coro, sizeof(uintptr_t), buffer_size); \
288- APPLY(asyncio_task_object, task_node, SIZEOF_LLIST_NODE, buffer_size)
314+ APPLY(asyncio_task_object, task_name, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
315+ APPLY(asyncio_task_object, task_awaited_by, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
316+ APPLY(asyncio_task_object, task_is_task, sizeof(char), _Alignof(char), buffer_size); \
317+ APPLY(asyncio_task_object, task_awaited_by_is_set, sizeof(char), _Alignof(char), buffer_size); \
318+ APPLY(asyncio_task_object, task_coro, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
319+ APPLY(asyncio_task_object, task_node, SIZEOF_LLIST_NODE, _Alignof(struct llist_node), buffer_size)
289320
290321#define PY_REMOTE_DEBUG_ASYNC_INTERPRETER_STATE_FIELDS (APPLY , buffer_size ) \
291- APPLY(asyncio_interpreter_state, asyncio_tasks_head, SIZEOF_LLIST_NODE, buffer_size)
322+ APPLY(asyncio_interpreter_state, asyncio_tasks_head, SIZEOF_LLIST_NODE, _Alignof(struct llist_node), buffer_size)
292323
293324#define PY_REMOTE_DEBUG_ASYNC_THREAD_STATE_FIELDS (APPLY , buffer_size ) \
294- APPLY(asyncio_thread_state, asyncio_running_loop, sizeof(uintptr_t), buffer_size); \
295- APPLY(asyncio_thread_state, asyncio_running_task, sizeof(uintptr_t), buffer_size); \
296- APPLY(asyncio_thread_state, asyncio_tasks_head, SIZEOF_LLIST_NODE, buffer_size)
325+ APPLY(asyncio_thread_state, asyncio_running_loop, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
326+ APPLY(asyncio_thread_state, asyncio_running_task, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \
327+ APPLY(asyncio_thread_state, asyncio_tasks_head, SIZEOF_LLIST_NODE, _Alignof(struct llist_node), buffer_size)
297328
298329/* Called once after reading _Py_DebugOffsets, before any hot-path use. */
299330static inline int
@@ -321,23 +352,31 @@ _PyRemoteDebug_ValidateDebugOffsetsLayout(struct _Py_DebugOffsets *debug_offsets
321352 err_stackitem ,
322353 exc_value ,
323354 sizeof (uintptr_t ),
355+ _Alignof(uintptr_t ),
324356 sizeof (_PyErr_StackItem ));
325357 PY_REMOTE_DEBUG_VALIDATE_NESTED_FIELD (
326358 thread_state ,
327359 exc_state ,
328360 err_stackitem ,
329361 exc_value ,
330362 sizeof (uintptr_t ),
363+ _Alignof(uintptr_t ),
331364 SIZEOF_THREAD_STATE );
332365
333366 PY_REMOTE_DEBUG_VALIDATE_READ_SECTION (gc , SIZEOF_GC_RUNTIME_STATE );
334- PY_REMOTE_DEBUG_VALIDATE_FIELD (gc , frame , sizeof (uintptr_t ), SIZEOF_GC_RUNTIME_STATE );
367+ PY_REMOTE_DEBUG_VALIDATE_FIELD (
368+ gc ,
369+ frame ,
370+ sizeof (uintptr_t ),
371+ _Alignof(uintptr_t ),
372+ SIZEOF_GC_RUNTIME_STATE );
335373 PY_REMOTE_DEBUG_VALIDATE_NESTED_FIELD (
336374 interpreter_state ,
337375 gc ,
338376 gc ,
339377 frame ,
340378 sizeof (uintptr_t ),
379+ _Alignof(uintptr_t ),
341380 INTERP_STATE_BUFFER_SIZE );
342381
343382 PY_REMOTE_DEBUG_VALIDATE_SECTION (interpreter_frame );
@@ -351,13 +390,19 @@ _PyRemoteDebug_ValidateDebugOffsetsLayout(struct _Py_DebugOffsets *debug_offsets
351390 SIZEOF_CODE_OBJ );
352391
353392 PY_REMOTE_DEBUG_VALIDATE_SECTION (pyobject );
354- PY_REMOTE_DEBUG_VALIDATE_FIELD (pyobject , ob_type , sizeof (uintptr_t ), SIZEOF_PYOBJECT );
393+ PY_REMOTE_DEBUG_VALIDATE_FIELD (
394+ pyobject ,
395+ ob_type ,
396+ sizeof (uintptr_t ),
397+ _Alignof(uintptr_t ),
398+ SIZEOF_PYOBJECT );
355399
356400 PY_REMOTE_DEBUG_VALIDATE_SECTION (type_object );
357401 PY_REMOTE_DEBUG_VALIDATE_FIELD (
358402 type_object ,
359403 tp_flags ,
360404 sizeof (unsigned long ),
405+ _Alignof(unsigned long ),
361406 SIZEOF_TYPE_OBJ );
362407
363408 PY_REMOTE_DEBUG_VALIDATE_SECTION (set_object );
@@ -389,6 +434,7 @@ _PyRemoteDebug_ValidateDebugOffsetsLayout(struct _Py_DebugOffsets *debug_offsets
389434 llist_node ,
390435 next ,
391436 sizeof (uintptr_t ),
437+ _Alignof(uintptr_t ),
392438 SIZEOF_LLIST_NODE );
393439
394440 return 0 ;
0 commit comments