| 680 | } |
| 681 | |
| 682 | void |
| 683 | AbstractProcessManager::setPythonVersionFromDebugOffsets() |
| 684 | { |
| 685 | remote_addr_t pyruntime_addr = findSymbol("_PyRuntime"); |
| 686 | if (!pyruntime_addr) { |
| 687 | pyruntime_addr = findPyRuntimeFromElfData(); |
| 688 | } |
| 689 | if (!pyruntime_addr) { |
| 690 | pyruntime_addr = findDebugOffsetsFromMaps(); |
| 691 | } |
| 692 | |
| 693 | if (!pyruntime_addr) { |
| 694 | LOG(DEBUG) << "Unable to find _Py_DebugOffsets"; |
| 695 | return; |
| 696 | } |
| 697 | |
| 698 | try { |
| 699 | uint64_t cookie; |
| 700 | copyObjectFromProcess(pyruntime_addr, &cookie); |
| 701 | if (0 != memcmp(&cookie, "xdebugpy", 8)) { |
| 702 | LOG(DEBUG) << "Found a _PyRuntime structure without _Py_DebugOffsets"; |
| 703 | return; |
| 704 | } |
| 705 | |
| 706 | uint64_t version; |
| 707 | copyObjectFromProcess(pyruntime_addr + 8, &version); |
| 708 | |
| 709 | ParsedPyVersion parsed; |
| 710 | if (parsePyVersionHex(version, parsed) && parsed.major == 3 && parsed.minor >= 13) { |
| 711 | LOG(INFO) << std::hex << std::showbase << "_Py_DebugOffsets at " << pyruntime_addr |
| 712 | << " identify the version as " << parsed; |
| 713 | setPythonVersion(std::make_pair(parsed.major, parsed.minor)); |
| 714 | Structure<py_runtime_v> py_runtime(shared_from_this(), pyruntime_addr); |
| 715 | bool is_free_threaded = py_runtime.getField(&py_runtime_v::o_dbg_off_free_threaded); |
| 716 | std::unique_ptr<python_v> offsets = loadDebugOffsets(py_runtime); |
| 717 | if (offsets) { |
| 718 | LOG(INFO) << "_Py_DebugOffsets appear to be valid and will be used"; |
| 719 | warnIfOffsetsAreMismatched(pyruntime_addr); |
| 720 | d_debug_offsets_addr = pyruntime_addr; |
| 721 | d_debug_offsets = std::move(offsets); |
| 722 | d_is_free_threaded = is_free_threaded; |
| 723 | return; |
| 724 | } |
| 725 | } |
| 726 | } catch (const RemoteMemCopyError& ex) { |
| 727 | LOG(DEBUG) << std::hex << std::showbase << "Found apparently invalid _Py_DebugOffsets at " |
| 728 | << pyruntime_addr; |
| 729 | } |
| 730 | |
| 731 | LOG(DEBUG) << "Failed to validate _PyDebugOffsets structure"; |
| 732 | d_major = 0; |
| 733 | d_minor = 0; |
| 734 | d_py_v = nullptr; |
| 735 | d_debug_offsets_addr = 0; |
| 736 | d_debug_offsets.reset(); |
| 737 | } |
| 738 | |
| 739 | std::pair<int, int> |
nothing calls this directly
no test coverage detected