| 903 | } |
| 904 | |
| 905 | std::unique_ptr<python_v> |
| 906 | AbstractProcessManager::loadDebugOffsets(Structure<py_runtime_v>& py_runtime) const |
| 907 | { |
| 908 | if (!versionIsAtLeast(3, 13)) { |
| 909 | return {}; // _Py_DebugOffsets was added in 3.13 |
| 910 | } |
| 911 | |
| 912 | if (0 != memcmp(py_runtime.getField(&py_runtime_v::o_dbg_off_cookie), "xdebugpy", 8)) { |
| 913 | LOG(WARNING) << "Debug offsets cookie doesn't match!"; |
| 914 | return {}; |
| 915 | } |
| 916 | |
| 917 | uint64_t version = py_runtime.getField(&py_runtime_v::o_dbg_off_py_version_hex); |
| 918 | int major = (version >> 24) & 0xff; |
| 919 | int minor = (version >> 16) & 0xff; |
| 920 | |
| 921 | if (major != d_major || minor != d_minor) { |
| 922 | LOG(WARNING) << "Detected version " << d_major << "." << d_minor |
| 923 | << " doesn't match debug offsets version " << major << "." << minor << "!"; |
| 924 | return {}; |
| 925 | } |
| 926 | |
| 927 | python_v debug_offsets{}; |
| 928 | if (!copyDebugOffsets(py_runtime, debug_offsets)) { |
| 929 | return {}; |
| 930 | } |
| 931 | |
| 932 | if (!validateDebugOffsets(py_runtime, debug_offsets)) { |
| 933 | return {}; |
| 934 | } |
| 935 | |
| 936 | auto ret = std::make_unique<python_v>(); |
| 937 | *ret = debug_offsets; |
| 938 | clampSizes(*ret); |
| 939 | return ret; |
| 940 | } |
| 941 | |
| 942 | bool |
| 943 | AbstractProcessManager::copyDebugOffsets(Structure<py_runtime_v>& py_runtime, python_v& debug_offsets) |