Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use /proc/pid/exe for the Python binary in Linux #364

Merged
merged 4 commits into from
Mar 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/binary_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@ impl BinaryInfo {
}

/// Uses goblin to parse a binary file, returns information on symbols/bss/adjusted offset etc
pub fn parse_binary(_pid: remoteprocess::Pid, filename: &str, addr: u64, size: u64) -> Result<BinaryInfo, Error> {
pub fn parse_binary(_pid: remoteprocess::Pid, filename: &str, addr: u64, size: u64, _is_bin: bool) -> Result<BinaryInfo, Error> {
// on linux the process could be running in docker, access the filename through procfs
// if filename is the binary executable (not libpython) - take it from /proc/pid/exe, which works
// across namespaces just like /proc/pid/root, and also if the file was deleted.
#[cfg(target_os="linux")]
let filename = &format!("/proc/{}/root{}", _pid, filename);
let filename = &if _is_bin {
format!("/proc/{}/exe", _pid)
} else {
format!("/proc/{}/root{}", _pid, filename)
};

let offset = addr;

Expand Down
6 changes: 3 additions & 3 deletions src/python_spy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ impl PythonProcessInfo {

// TODO: consistent types? u64 -> usize? for map.start etc
#[allow(unused_mut)]
let python_binary = parse_binary(process.pid, &filename, map.start() as u64, map.size() as u64)
let python_binary = parse_binary(process.pid, &filename, map.start() as u64, map.size() as u64, true)
.and_then(|mut pb| {
// windows symbols are stored in separate files (.pdb), load
#[cfg(windows)]
Expand Down Expand Up @@ -792,7 +792,7 @@ impl PythonProcessInfo {
if let Some(filename) = &libpython.filename() {
info!("Found libpython binary @ {}", filename);
#[allow(unused_mut)]
let mut parsed = parse_binary(process.pid, filename, libpython.start() as u64, libpython.size() as u64)?;
let mut parsed = parse_binary(process.pid, filename, libpython.start() as u64, libpython.size() as u64, false)?;
#[cfg(windows)]
parsed.symbols.extend(get_windows_python_symbols(process.pid, filename, libpython.start() as u64)?);
libpython_binary = Some(parsed);
Expand Down Expand Up @@ -822,7 +822,7 @@ impl PythonProcessInfo {
if let Some(libpython) = python_dyld_data {
info!("Found libpython binary from dyld @ {}", libpython.filename);

let mut binary = parse_binary(process.pid, &libpython.filename, libpython.segment.vmaddr, libpython.segment.vmsize)?;
let mut binary = parse_binary(process.pid, &libpython.filename, libpython.segment.vmaddr, libpython.segment.vmsize, false)?;

// TODO: bss addr offsets returned from parsing binary are wrong
// (assumes data section isn't split from text section like done here).
Expand Down