MCPcopy Create free account
hub / github.com/bloomberg/pystack / validateDebugOffsets

Method validateDebugOffsets

src/pystack/_pystack/process.cpp:1061–1181  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1059}
1060
1061bool
1062AbstractProcessManager::validateDebugOffsets(
1063 const Structure<py_runtime_v>& py_runtime,
1064 python_v& debug_offsets) const
1065{
1066 // Simple sanity checks on the decoded offsets:
1067 // - No structure is larger than 1 MB
1068 // - Every field falls within its structure's size
1069#define check_size(pystack_struct, size_offset) \
1070 do { \
1071 if (debug_offsets.pystack_struct.size > 1024 * 1024) { \
1072 LOG(WARNING) << "Ignoring debug offsets because " #pystack_struct ".size (" \
1073 << debug_offsets.pystack_struct.size << ") reported at byte offset " \
1074 << (d_py_v->py_runtime.*size_offset).offset \
1075 << " in detected _Py_DebugOffsets structure at " << std::hex << std::showbase \
1076 << py_runtime.getFieldRemoteAddress(&py_runtime_v::o_dbg_off_cookie) \
1077 << " is implausibly large"; \
1078 return {}; \
1079 } \
1080 } while (0)
1081
1082#define check_field_bounds(structure, field) \
1083 do { \
1084 if (debug_offsets.structure.size < 0 \
1085 || (size_t)debug_offsets.structure.size < debug_offsets.structure.field.offset \
1086 || debug_offsets.structure.size - debug_offsets.structure.field.offset \
1087 < sizeof(decltype(debug_offsets.structure.field)::Type)) \
1088 { \
1089 LOG(WARNING) << "Ignoring debug offsets because " #structure ".size (" \
1090 << debug_offsets.structure.size << ") - " #structure "." #field ".offset (" \
1091 << debug_offsets.structure.field.offset << ") < the field's size (" \
1092 << sizeof(decltype(debug_offsets.structure.field)::Type) << ")"; \
1093 return {}; \
1094 } \
1095 } while (0)
1096
1097 check_size(py_runtime, &py_runtime_v::o_dbg_off_runtime_state_struct_size);
1098 check_field_bounds(py_runtime, o_finalizing);
1099 check_field_bounds(py_runtime, o_interp_head);
1100
1101 check_size(py_is, &py_runtime_v::o_dbg_off_interpreter_state_struct_size);
1102 check_field_bounds(py_is, o_next);
1103 check_field_bounds(py_is, o_tstate_head);
1104 check_field_bounds(py_is, o_gc);
1105 check_field_bounds(py_is, o_modules);
1106 check_field_bounds(py_is, o_sysdict);
1107 check_field_bounds(py_is, o_builtins);
1108 check_field_bounds(py_is, o_gil_runtime_state);
1109
1110 check_size(py_thread, &py_runtime_v::o_dbg_off_thread_state_struct_size);
1111 check_field_bounds(py_thread, o_prev);
1112 check_field_bounds(py_thread, o_next);
1113 check_field_bounds(py_thread, o_interp);
1114 check_field_bounds(py_thread, o_frame);
1115 check_field_bounds(py_thread, o_thread_id);
1116 check_field_bounds(py_thread, o_native_thread_id);
1117
1118 check_size(py_frame, &py_runtime_v::o_dbg_off_interpreter_frame_struct_size);

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected