| 789 | } |
| 790 | |
| 791 | void |
| 792 | AbstractProcessManager::warnIfOffsetsAreMismatched(remote_addr_t runtime_addr) const |
| 793 | { |
| 794 | Structure<py_runtime_v> py_runtime(shared_from_this(), runtime_addr); |
| 795 | |
| 796 | if (0 != memcmp(py_runtime.getField(&py_runtime_v::o_dbg_off_cookie), "xdebugpy", 8)) { |
| 797 | LOG(WARNING) << "Debug offsets cookie doesn't match!"; |
| 798 | return; |
| 799 | } |
| 800 | |
| 801 | // Note: It's OK for pystack's size to be smaller, but not larger. |
| 802 | #define compare_size(size_offset, pystack_struct) \ |
| 803 | if ((d_py_v->py_runtime.*size_offset).offset \ |
| 804 | && ((uint64_t)offsets().pystack_struct.size > py_runtime.getField(size_offset))) \ |
| 805 | { \ |
| 806 | LOG(INFO) << "Debug offsets mismatch: compiled-in " << sizeof(void*) * 8 << "-bit python3." \ |
| 807 | << d_minor << " " #pystack_struct ".size " << offsets().pystack_struct.size << " > " \ |
| 808 | << py_runtime.getField(size_offset) << " loaded from _Py_DebugOffsets"; \ |
| 809 | } else \ |
| 810 | do { \ |
| 811 | } while (0) |
| 812 | |
| 813 | #define compare_offset(field_offset_offset, pystack_field) \ |
| 814 | if ((d_py_v->py_runtime.*field_offset_offset).offset \ |
| 815 | && (uint64_t)offsets().pystack_field.offset != py_runtime.getField(field_offset_offset)) \ |
| 816 | { \ |
| 817 | LOG(INFO) << "Debug offsets mismatch: compiled-in " << sizeof(void*) * 8 << "-bit python3." \ |
| 818 | << d_minor << " " #pystack_field << " " << offsets().pystack_field.offset \ |
| 819 | << " != " << py_runtime.getField(field_offset_offset) \ |
| 820 | << " loaded from _Py_DebugOffsets"; \ |
| 821 | } else \ |
| 822 | do { \ |
| 823 | } while (0) |
| 824 | |
| 825 | compare_size(&py_runtime_v::o_dbg_off_runtime_state_struct_size, py_runtime); |
| 826 | compare_offset(&py_runtime_v::o_dbg_off_runtime_state_finalizing, py_runtime.o_finalizing); |
| 827 | compare_offset(&py_runtime_v::o_dbg_off_runtime_state_interpreters_head, py_runtime.o_interp_head); |
| 828 | |
| 829 | compare_size(&py_runtime_v::o_dbg_off_interpreter_state_struct_size, py_is); |
| 830 | compare_offset(&py_runtime_v::o_dbg_off_interpreter_state_next, py_is.o_next); |
| 831 | compare_offset(&py_runtime_v::o_dbg_off_interpreter_state_threads_head, py_is.o_tstate_head); |
| 832 | compare_offset(&py_runtime_v::o_dbg_off_interpreter_state_gc, py_is.o_gc); |
| 833 | compare_offset(&py_runtime_v::o_dbg_off_interpreter_state_imports_modules, py_is.o_modules); |
| 834 | compare_offset(&py_runtime_v::o_dbg_off_interpreter_state_sysdict, py_is.o_sysdict); |
| 835 | compare_offset(&py_runtime_v::o_dbg_off_interpreter_state_builtins, py_is.o_builtins); |
| 836 | compare_offset(&py_runtime_v::o_dbg_off_interpreter_state_ceval_gil, py_is.o_gil_runtime_state); |
| 837 | |
| 838 | compare_size(&py_runtime_v::o_dbg_off_thread_state_struct_size, py_thread); |
| 839 | compare_offset(&py_runtime_v::o_dbg_off_thread_state_prev, py_thread.o_prev); |
| 840 | compare_offset(&py_runtime_v::o_dbg_off_thread_state_next, py_thread.o_next); |
| 841 | compare_offset(&py_runtime_v::o_dbg_off_thread_state_interp, py_thread.o_interp); |
| 842 | compare_offset(&py_runtime_v::o_dbg_off_thread_state_current_frame, py_thread.o_frame); |
| 843 | compare_offset(&py_runtime_v::o_dbg_off_thread_state_thread_id, py_thread.o_thread_id); |
| 844 | compare_offset(&py_runtime_v::o_dbg_off_thread_state_native_thread_id, py_thread.o_native_thread_id); |
| 845 | |
| 846 | compare_size(&py_runtime_v::o_dbg_off_interpreter_frame_struct_size, py_frame); |
| 847 | compare_offset(&py_runtime_v::o_dbg_off_interpreter_frame_previous, py_frame.o_back); |
| 848 | compare_offset(&py_runtime_v::o_dbg_off_interpreter_frame_executable, py_frame.o_code); |