Skip to content

Commit 1f61158

Browse files
authored
Merge branch 'master' into set_gha_workflow_permissions
2 parents b350b5c + f84084a commit 1f61158

1 file changed

Lines changed: 72 additions & 64 deletions

File tree

src/python_process_info.rs

Lines changed: 72 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,52 @@ where
373373
{
374374
// get the address of the main PyInterpreterState object from loaded symbols if we can
375375
// (this tends to be faster than scanning through the bss section)
376+
match get_interpreter_address_from_symbols(python_info, process, version) {
377+
Ok(addr) => {
378+
// Check that the symbol address is valid before returning
379+
match check_interpreter_addresses(&[addr], &*python_info.maps, process, version) {
380+
Ok(addr) => return Ok(addr),
381+
Err(_) => {
382+
warn!("Interpreter address from symbol is invalid {:016x}", addr);
383+
}
384+
};
385+
}
386+
Err(err) => {
387+
info!("Failed to get interpreter address from symbols {:?}, scanning BSS section from main binary", err)
388+
}
389+
}
390+
391+
// try scanning the BSS section of the binary for things that might be the interpreterstate
392+
let err = if let Some(ref pb) = python_info.python_binary {
393+
match get_interpreter_address_from_binary(pb, &*python_info.maps, process, version) {
394+
Ok(addr) => return Ok(addr),
395+
err => Some(err),
396+
}
397+
} else {
398+
None
399+
};
400+
401+
// Before giving up, try again if there is a libpython.so
402+
if let Some(ref lpb) = python_info.libpython_binary {
403+
info!("Failed to get interpreter from binary BSS, scanning libpython BSS");
404+
match get_interpreter_address_from_binary(lpb, &*python_info.maps, process, version) {
405+
Ok(addr) => Ok(addr),
406+
lib_err => err.unwrap_or(lib_err),
407+
}
408+
} else {
409+
err.expect("Both python and libpython are invalid.")
410+
}
411+
}
412+
413+
// Gets the address of the main PyInterpreterState object from loaded symbols
414+
fn get_interpreter_address_from_symbols<P>(
415+
python_info: &PythonProcessInfo,
416+
process: &P,
417+
version: &Version,
418+
) -> Result<usize, Error>
419+
where
420+
P: ProcessMemory,
421+
{
376422
match version {
377423
Version {
378424
major: 3,
@@ -381,37 +427,34 @@ where
381427
} => {
382428
if let Some(&pyruntime_addr) = python_info.get_symbol("_PyRuntime") {
383429
// figure out the interpreters_head location using the debug_offsets
384-
let addr = match version {
430+
match version {
385431
Version {
386432
major: 3,
387433
minor: 14,
388434
..
389435
} => {
390436
let debug_offsets: v3_14_0::_Py_DebugOffsets =
391437
process.copy_struct(pyruntime_addr as usize)?;
392-
process.copy_struct(
393-
pyruntime_addr as usize
394-
+ debug_offsets.runtime_state.interpreters_head as usize,
395-
)?
438+
return process
439+
.copy_struct(
440+
pyruntime_addr as usize
441+
+ debug_offsets.runtime_state.interpreters_head as usize,
442+
)
443+
.context(
444+
"Failed to copy py_debug_offsets.runtime_state.interpreters_head",
445+
);
396446
}
397447
_ => {
398448
let debug_offsets: v3_13_0::_Py_DebugOffsets =
399449
process.copy_struct(pyruntime_addr as usize)?;
400-
process.copy_struct(
401-
pyruntime_addr as usize
402-
+ debug_offsets.runtime_state.interpreters_head as usize,
403-
)?
404-
}
405-
};
406-
407-
// Make sure the interpreter addr is valid before returning
408-
match check_interpreter_addresses(&[addr], &*python_info.maps, process, version) {
409-
Ok(addr) => return Ok(addr),
410-
Err(_) => {
411-
warn!(
412-
"Interpreter address from _PyRuntime symbol is invalid {:016x}",
413-
addr
414-
);
450+
return process
451+
.copy_struct(
452+
pyruntime_addr as usize
453+
+ debug_offsets.runtime_state.interpreters_head as usize,
454+
)
455+
.context(
456+
"Failed to copy py_debug_offsets.runtime_state.interpreters_head",
457+
);
415458
}
416459
};
417460
}
@@ -422,57 +465,22 @@ where
422465
..
423466
} => {
424467
if let Some(&addr) = python_info.get_symbol("_PyRuntime") {
425-
let addr = process
426-
.copy_struct(addr as usize + pyruntime::get_interp_head_offset(version))?;
427-
428-
// Make sure the interpreter addr is valid before returning
429-
match check_interpreter_addresses(&[addr], &*python_info.maps, process, version) {
430-
Ok(addr) => return Ok(addr),
431-
Err(_) => {
432-
warn!(
433-
"Interpreter address from _PyRuntime symbol is invalid {:016x}",
434-
addr
435-
);
436-
}
437-
};
468+
return process
469+
.copy_struct(addr as usize + pyruntime::get_interp_head_offset(version))
470+
.context("Failed to copy interpreters_head");
438471
}
439472
}
440473
_ => {
441474
if let Some(&addr) = python_info.get_symbol("interp_head") {
442-
let addr = process.copy_struct(addr as usize)?;
443-
match check_interpreter_addresses(&[addr], &*python_info.maps, process, version) {
444-
Ok(addr) => return Ok(addr),
445-
Err(_) => {
446-
warn!(
447-
"Interpreter address from interp_head symbol is invalid {:016x}",
448-
addr
449-
);
450-
}
451-
};
475+
return process
476+
.copy_struct(addr as usize)
477+
.context("Failed to copy interp_head");
452478
}
453479
}
454480
};
455-
info!("Failed to find runtime address from symbols, scanning BSS section from main binary");
456-
457-
// try scanning the BSS section of the binary for things that might be the interpreterstate
458-
let err = if let Some(ref pb) = python_info.python_binary {
459-
match get_interpreter_address_from_binary(pb, &*python_info.maps, process, version) {
460-
Ok(addr) => return Ok(addr),
461-
err => Some(err),
462-
}
463-
} else {
464-
None
465-
};
466-
// Before giving up, try again if there is a libpython.so
467-
if let Some(ref lpb) = python_info.libpython_binary {
468-
info!("Failed to get interpreter from binary BSS, scanning libpython BSS");
469-
match get_interpreter_address_from_binary(lpb, &*python_info.maps, process, version) {
470-
Ok(addr) => Ok(addr),
471-
lib_err => err.unwrap_or(lib_err),
472-
}
473-
} else {
474-
err.expect("Both python and libpython are invalid.")
475-
}
481+
return Err(format_err!(
482+
"Failed to find _PyRuntime address from symbols"
483+
));
476484
}
477485

478486
fn get_interpreter_address_from_binary<P>(

0 commit comments

Comments
 (0)