Skip to content

Commit 2982dab

Browse files
authored
Use Py_Version symbol for detecting the python version (#835)
Use the Py_Version symbol for detecting the python version - instead of relying on scanning the BSS section for the string version.
1 parent c478370 commit 2982dab

1 file changed

Lines changed: 30 additions & 0 deletions

File tree

src/python_process_info.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,36 @@ pub fn get_python_version<P>(python_info: &PythonProcessInfo, process: &P) -> Re
298298
where
299299
P: ProcessMemory,
300300
{
301+
// Try getting the Py_Version symbol (points to 32 bit encoded version)
302+
if let Some(&addr) = python_info.get_symbol("Py_Version") {
303+
let version: u32 = process
304+
.copy_struct(addr as usize)
305+
.context("Failed to copy Py_Version symbol")?;
306+
307+
// decode u32 version via the _Py_PACK_FULL_VERSION logic
308+
let major: u64 = ((version >> 24) & 0xff).into();
309+
let minor: u64 = ((version >> 16) & 0xff).into();
310+
let patch: u64 = ((version >> 8) & 0xff).into();
311+
let release_level = (version >> 4) & 0xf;
312+
let release_serial = (version) & 0xf;
313+
let release_flags = match release_level {
314+
0xA => format!("a{}", release_serial),
315+
0xB => format!("b{}", release_serial),
316+
0xC => format!("rc{}", release_serial),
317+
_ => "".to_owned(),
318+
};
319+
320+
let version = Version {
321+
major,
322+
minor,
323+
patch,
324+
release_flags,
325+
build_metadata: None,
326+
};
327+
info!("Got version {} from Py_Version symbol", version);
328+
return Ok(version);
329+
}
330+
301331
// If possible, grab the sys.version string from the processes memory (mac osx).
302332
if let Some(&addr) = python_info
303333
.get_symbol("Py_GetVersion.version")

0 commit comments

Comments
 (0)