pub struct Process {
pub pid: i32,
/* private fields */
}
Expand description
Represents a process in /proc/<pid>
.
Note The Process
struct holds an open file descriptor to its /proc/<pid>
directory.
This makes it possible to construct a Process
object and then later call the various methods
on it without a risk of inadvertently getting information from the wrong process (due to PID
reuse).
However the downside is that holding a lot of Process
objects might cause the process to run
out of file descriptors.
For use cases that don’t involve holding a lot of Process
objects, no special handler is
needed. But if you do hold a lot of these objects (for example if you’re writing a ps
or top
-like program), you’ll likely want to gather all of the necessary info from Process
object into a new struct and then drop the Process
object
Fields§
§pid: i32
Implementations§
source§impl Process
impl Process
sourcepub fn cgroups(&self) -> ProcResult<ProcessCGroups>
pub fn cgroups(&self) -> ProcResult<ProcessCGroups>
Describes control groups to which the process with the corresponding PID belongs.
The displayed information differs for cgroupsversion 1 and version 2 hierarchies.
source§impl Process
impl Process
sourcepub fn namespaces(&self) -> ProcResult<Namespaces>
pub fn namespaces(&self) -> ProcResult<Namespaces>
Describes namespaces to which the process with the corresponding PID belongs. Doc reference: https://man7.org/linux/man-pages/man7/namespaces.7.html The namespace type is the key for the HashMap, i.e ‘net’, ‘user’, etc.
source§impl Process
impl Process
sourcepub fn pagemap(&self) -> ProcResult<PageMap>
pub fn pagemap(&self) -> ProcResult<PageMap>
Returns a struct that can be used to access information in the /proc/pid/pagemap
file.
source§impl Process
impl Process
Methods for constructing a new Process
object.
sourcepub fn new(pid: i32) -> ProcResult<Process>
pub fn new(pid: i32) -> ProcResult<Process>
Returns a Process
based on a specified PID.
This can fail if the process doesn’t exist, or if you don’t have permission to access it.
sourcepub fn new_with_root(root: PathBuf) -> ProcResult<Process>
pub fn new_with_root(root: PathBuf) -> ProcResult<Process>
Returns a Process
based on a specified /proc/<pid>
path.
sourcepub fn myself() -> ProcResult<Process>
pub fn myself() -> ProcResult<Process>
Returns a Process
for the currently running process.
This is done by using the /proc/self
symlink
source§impl Process
impl Process
sourcepub fn cmdline(&self) -> ProcResult<Vec<String>>
pub fn cmdline(&self) -> ProcResult<Vec<String>>
Returns the complete command line for the process, unless the process is a zombie.
sourcepub fn pid(&self) -> i32
pub fn pid(&self) -> i32
Returns the process ID for this process, if the process was created from an ID. Otherwise use stat().pid.
sourcepub fn is_alive(&self) -> bool
pub fn is_alive(&self) -> bool
Is this process still alive?
Processes in the Zombie or Dead state are not considered alive.
sourcepub fn uid(&self) -> ProcResult<u32>
pub fn uid(&self) -> ProcResult<u32>
What user owns this process?
sourcepub fn cwd(&self) -> ProcResult<PathBuf>
pub fn cwd(&self) -> ProcResult<PathBuf>
Retrieves current working directory of the process by dereferencing /proc/<pid>/cwd
symbolic link.
This method has the following caveats:
-
if the pathname has been unlinked, the symbolic link will contain the string “ (deleted)“ appended to the original pathname
-
in a multithreaded process, the contents of this symbolic link are not available if the main thread has already terminated (typically by calling
pthread_exit(3)
) -
permission to dereference or read this symbolic link is governed by a
ptrace(2)
access modePTRACE_MODE_READ_FSCREDS
check
sourcepub fn root(&self) -> ProcResult<PathBuf>
pub fn root(&self) -> ProcResult<PathBuf>
Retrieves current root directory of the process by dereferencing /proc/<pid>/root
symbolic link.
This method has the following caveats:
-
if the pathname has been unlinked, the symbolic link will contain the string “ (deleted)“ appended to the original pathname
-
in a multithreaded process, the contents of this symbolic link are not available if the main thread has already terminated (typically by calling
pthread_exit(3)
) -
permission to dereference or read this symbolic link is governed by a
ptrace(2)
access modePTRACE_MODE_READ_FSCREDS
check
sourcepub fn environ(&self) -> ProcResult<HashMap<OsString, OsString>>
pub fn environ(&self) -> ProcResult<HashMap<OsString, OsString>>
Gets the current environment for the process. This is done by reading the
/proc/pid/environ
file.
sourcepub fn exe(&self) -> ProcResult<PathBuf>
pub fn exe(&self) -> ProcResult<PathBuf>
Retrieves the actual path of the executed command by dereferencing /proc/<pid>/exe
symbolic link.
This method has the following caveats:
-
if the pathname has been unlinked, the symbolic link will contain the string “ (deleted)“ appended to the original pathname
-
in a multithreaded process, the contents of this symbolic link are not available if the main thread has already terminated (typically by calling
pthread_exit(3)
) -
permission to dereference or read this symbolic link is governed by a
ptrace(2)
access modePTRACE_MODE_READ_FSCREDS
check
sourcepub fn io(&self) -> ProcResult<Io>
pub fn io(&self) -> ProcResult<Io>
Return the Io stats for this process, based on the /proc/pid/io
file.
(since kernel 2.6.20)
sourcepub fn maps(&self) -> ProcResult<MemoryMaps>
pub fn maps(&self) -> ProcResult<MemoryMaps>
Return a list of the currently mapped memory regions and their access permissions, based on
the /proc/pid/maps
file.
sourcepub fn smaps(&self) -> ProcResult<MemoryMaps>
pub fn smaps(&self) -> ProcResult<MemoryMaps>
Returns a list of currently mapped memory regions and verbose information about them,
such as memory consumption per mapping, based on the /proc/pid/smaps
file.
(since Linux 2.6.14 and requires CONFIG_PROG_PAGE_MONITOR)
sourcepub fn smaps_rollup(&self) -> ProcResult<SmapsRollup>
pub fn smaps_rollup(&self) -> ProcResult<SmapsRollup>
This is the sum of all the smaps data but it is much more performant to get it this way.
Since 4.14 and requires CONFIG_PROC_PAGE_MONITOR.
sourcepub fn mountstats(&self) -> ProcResult<MountStats>
pub fn mountstats(&self) -> ProcResult<MountStats>
Returns the MountStat data for this process’s mount namespace.
sourcepub fn mountinfo(&self) -> ProcResult<MountInfos>
pub fn mountinfo(&self) -> ProcResult<MountInfos>
Returns info about the mountpoints in this this process’s mount namespace.
This data is taken from the /proc/[pid]/mountinfo
file
Example:
let stats = Process::myself().unwrap().mountstats().unwrap();
for mount in stats {
println!("{} mounted on {} wth type {}",
mount.device.unwrap_or("??".to_owned()),
mount.mount_point.display(),
mount.fs
);
}
(Since Linux 2.6.26)
sourcepub fn fd_count(&self) -> ProcResult<usize>
pub fn fd_count(&self) -> ProcResult<usize>
Gets the number of open file descriptors for a process
Calling this function is more efficient than calling fd().unwrap().count()
sourcepub fn fd(&self) -> ProcResult<FDsIter>
pub fn fd(&self) -> ProcResult<FDsIter>
Gets a iterator of open file descriptors for a process
pub fn fd_from_fd(&self, fd: i32) -> ProcResult<FDInfo>
sourcepub fn coredump_filter(&self) -> ProcResult<Option<CoredumpFlags>>
pub fn coredump_filter(&self) -> ProcResult<Option<CoredumpFlags>>
Lists which memory segments are written to the core dump in the event that a core dump is performed.
By default, the following bits are set: 0, 1, 4 (if the CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS kernel configuration option is enabled), and 5. This default can be modified at boot time using the core dump_filter boot option.
This function will return Err(ProcError::NotFound)
if the coredump_filter
file can’t be
found. If it returns Ok(None)
then the process has no coredump_filter
sourcepub fn autogroup(&self) -> ProcResult<String>
pub fn autogroup(&self) -> ProcResult<String>
Gets the process’s autogroup membership
(since Linux 2.6.38 and requires CONFIG_SCHED_AUTOGROUP)
sourcepub fn auxv(&self) -> ProcResult<HashMap<u64, u64>>
pub fn auxv(&self) -> ProcResult<HashMap<u64, u64>>
Get the process’s auxiliary vector
(since 2.6.0-test7)
sourcepub fn wchan(&self) -> ProcResult<String>
pub fn wchan(&self) -> ProcResult<String>
Gets the symbolic name corresponding to the location in the kernel where the process is sleeping.
(since Linux 2.6.0)
sourcepub fn status(&self) -> ProcResult<Status>
pub fn status(&self) -> ProcResult<Status>
Return the Status
for this process, based on the /proc/[pid]/status
file.
sourcepub fn stat(&self) -> ProcResult<Stat>
pub fn stat(&self) -> ProcResult<Stat>
Returns the status info from /proc/[pid]/stat
.
sourcepub fn limits(&self) -> ProcResult<Limits>
pub fn limits(&self) -> ProcResult<Limits>
Return the limits for this process
sourcepub fn loginuid(&self) -> ProcResult<u32>
pub fn loginuid(&self) -> ProcResult<u32>
Gets the process’ login uid. May not be available.
sourcepub fn oom_score(&self) -> ProcResult<u32>
pub fn oom_score(&self) -> ProcResult<u32>
The current score that the kernel gives to this process for the purpose of selecting a process for the OOM-killer
A higher score means that the process is more likely to be selected by the OOM-killer. The basis for this score is the amount of memory used by the process, plus other factors.
(Since linux 2.6.11)
sourcepub fn statm(&self) -> ProcResult<StatM>
pub fn statm(&self) -> ProcResult<StatM>
Set process memory information
Much of this data is the same as the data from stat()
and status()
sourcepub fn task_main_thread(&self) -> ProcResult<Task>
pub fn task_main_thread(&self) -> ProcResult<Task>
Return a task for the main thread of this process
sourcepub fn task_from_tid(&self, tid: i32) -> ProcResult<Task>
pub fn task_from_tid(&self, tid: i32) -> ProcResult<Task>
Return a task for the main thread of this process
sourcepub fn schedstat(&self) -> ProcResult<Schedstat>
pub fn schedstat(&self) -> ProcResult<Schedstat>
Return the Schedstat
for this process, based on the /proc/<pid>/schedstat
file.
(Requires CONFIG_SCHED_INFO)
sourcepub fn tasks(&self) -> ProcResult<TasksIter>
pub fn tasks(&self) -> ProcResult<TasksIter>
Iterate over all the Task
s (aka Threads) in this process
Note that the iterator does not receive a snapshot of tasks, it is a lazy iterator over whatever happens to be running when the iterator gets there, see the examples below.
Examples
Simple iteration over subtasks
If you want to get the info that most closely matches what was running
when you call tasks
you should collect them as quikcly as possible,
and then run processing over that collection:
let name = "testing:example";
let t = thread::Builder::new().name(name.to_string())
.spawn(move || { // do work
})?;
let proc = Process::myself()?;
// Collect a snapshot
let threads: Vec<_> = proc.tasks()?.flatten().map(|t| t.stat().unwrap().comm).collect();
threads.iter().find(|s| &**s == name).expect("thread should exist");
The TaskIterator is lazy
This means both that tasks that stop before you get to them in iteration will not be there, and that new tasks that are created after you start the iterator will appear.
let proc = Process::myself()?;
// Task iteration is lazy
let mut task_iter = proc.tasks()?.flatten().map(|t| t.stat().unwrap().comm);
let name = "testing:lazy";
let t = thread::Builder::new().name(name.to_string())
.spawn(move || { // do work
})?;
task_iter.find(|s| &**s == name).expect("thread should exist");
Tasks that stop while you’re iterating may or may not appear:
let name = "testing:stopped";
let t = thread::Builder::new().name(name.to_string())
.spawn(move || { // do work
})?;
let proc = Process::myself()?;
// Task iteration is lazy
let mut task_iter = proc.tasks()?.flatten().map(|t| t.stat().unwrap().comm);
t.join().unwrap();
// It's impossible to know if this is going to be gone
let _ = task_iter.find(|s| &**s == name).is_some();
sourcepub fn tcp(&self) -> ProcResult<Vec<TcpNetEntry>>
pub fn tcp(&self) -> ProcResult<Vec<TcpNetEntry>>
Reads the tcp socket table from the process net namespace
sourcepub fn tcp6(&self) -> ProcResult<Vec<TcpNetEntry>>
pub fn tcp6(&self) -> ProcResult<Vec<TcpNetEntry>>
Reads the tcp6 socket table from the process net namespace
sourcepub fn udp(&self) -> ProcResult<Vec<UdpNetEntry>>
pub fn udp(&self) -> ProcResult<Vec<UdpNetEntry>>
Reads the udp socket table from the process net namespace
sourcepub fn udp6(&self) -> ProcResult<Vec<UdpNetEntry>>
pub fn udp6(&self) -> ProcResult<Vec<UdpNetEntry>>
Reads the udp6 socket table from the process net namespace
sourcepub fn dev_status(&self) -> ProcResult<HashMap<String, DeviceStatus>>
pub fn dev_status(&self) -> ProcResult<HashMap<String, DeviceStatus>>
Returns basic network device statistics for all interfaces in the process net namespace
See also the dev_status() function.
sourcepub fn unix(&self) -> ProcResult<Vec<UnixNetEntry>>
pub fn unix(&self) -> ProcResult<Vec<UnixNetEntry>>
Reads the unix socket table
sourcepub fn arp(&self) -> ProcResult<Vec<ARPEntry>>
pub fn arp(&self) -> ProcResult<Vec<ARPEntry>>
Reads the ARP table from the process net namespace
sourcepub fn route(&self) -> ProcResult<Vec<RouteEntry>>
pub fn route(&self) -> ProcResult<Vec<RouteEntry>>
Reads the ipv4 route table from the process net namespace
sourcepub fn snmp(&self) -> ProcResult<Snmp>
pub fn snmp(&self) -> ProcResult<Snmp>
Reads the network management information by Simple Network Management Protocol from the process net namespace
sourcepub fn snmp6(&self) -> ProcResult<Snmp6>
pub fn snmp6(&self) -> ProcResult<Snmp6>
Reads the network management information of IPv6 by Simple Network Management Protocol from the process net namespace
sourcepub fn mem(&self) -> ProcResult<File>
pub fn mem(&self) -> ProcResult<File>
Opens a file to the process’s memory (/proc/<pid>/mem
).
Note: you cannot start reading from the start of the file. You must first seek to a mapped page. See Process::maps.
Permission to access this file is governed by a ptrace access mode PTRACE_MODE_ATTACH_FSCREDS check
Example
Find the offset of the “hello” string in the process’s stack, and compare it to the pointer of the variable containing “hello”
let me = Process::myself().unwrap();
let mut mem = me.mem().unwrap();
let maps = me.maps().unwrap();
let hello = "hello".to_string();
for map in maps {
if map.pathname == MMapPath::Heap {
mem.seek(SeekFrom::Start(map.address.0)).unwrap();
let mut buf = vec![0; (map.address.1 - map.address.0) as usize];
mem.read_exact(&mut buf).unwrap();
let idx = buf.windows(5).position(|p| p == b"hello").unwrap();
assert_eq!(map.address.0 + idx as u64, hello.as_ptr() as u64);
}
}
sourcepub fn open_relative(&self, path: &str) -> ProcResult<File>
pub fn open_relative(&self, path: &str) -> ProcResult<File>
Returns a file which is part of the process proc structure
sourcepub fn read<T: FromRead>(&self, path: &str) -> ProcResult<T>
pub fn read<T: FromRead>(&self, path: &str) -> ProcResult<T>
Parse a file relative to the process proc structure.
sourcepub fn read_si<T: FromReadSI>(&self, path: &str) -> ProcResult<T>
pub fn read_si<T: FromReadSI>(&self, path: &str) -> ProcResult<T>
Parse a file relative to the process proc structure.
sourcepub fn clear_refs(&self, clear: ClearRefs) -> ProcResult<()>
pub fn clear_refs(&self, clear: ClearRefs) -> ProcResult<()>
Clear reference bits
See ClearRefs and Process::pagemap()