| 737 | } |
| 738 | |
| 739 | std::pair<int, int> |
| 740 | AbstractProcessManager::findPythonVersion() const |
| 741 | { |
| 742 | if (d_py_v) { |
| 743 | // Already set or previously found (probably via _Py_DebugOffsets) |
| 744 | return std::make_pair(d_major, d_minor); |
| 745 | } |
| 746 | |
| 747 | auto version_symbol = findSymbol("Py_Version"); |
| 748 | if (!version_symbol) { |
| 749 | LOG(DEBUG) << "Failed to determine Python version from symbols"; |
| 750 | return {-1, -1}; |
| 751 | } |
| 752 | unsigned long version; |
| 753 | try { |
| 754 | copyObjectFromProcess(version_symbol, &version); |
| 755 | } catch (RemoteMemCopyError& ex) { |
| 756 | LOG(DEBUG) << "Failed to determine Python version from symbols"; |
| 757 | return {-1, -1}; |
| 758 | } |
| 759 | int major = (version >> 24) & 0xFF; |
| 760 | int minor = (version >> 16) & 0xFF; |
| 761 | int level = (version >> 4) & 0x0F; |
| 762 | |
| 763 | if (major == 0 && minor == 0) { |
| 764 | LOG(DEBUG) << "Failed to determine Python version from symbols: empty data copied"; |
| 765 | return {-1, -1}; |
| 766 | } |
| 767 | |
| 768 | if (major != 2 && major != 3) { |
| 769 | LOG(DEBUG) << "Failed to determine Python version from symbols: invalid major version"; |
| 770 | return {-1, -1}; |
| 771 | } |
| 772 | |
| 773 | if (level != 0xA && level != 0xB && level != 0xC && level != 0xF) { |
| 774 | LOG(DEBUG) << "Failed to determine Python version from symbols: invalid release level"; |
| 775 | return {-1, -1}; |
| 776 | } |
| 777 | |
| 778 | LOG(DEBUG) << "Python version determined from symbols: " << major << "." << minor; |
| 779 | return {major, minor}; |
| 780 | } |
| 781 | |
| 782 | void |
| 783 | AbstractProcessManager::setPythonVersion(const std::pair<int, int>& version) |