Giter VIP home page Giter VIP logo

libproc-rs's Introduction

Build Status codecov

libproc-rs

This is a library for getting information about running processes for Mac OS X and Linux.

Add it to your project's Cargo.toml:

libproc = "0.14.4"

And then use it in your code:

use libproc::libproc::proc_pid;

match proc_pid::pidpath(pid) {
    Ok(path) => println!("PID {}: has path {}", pid, path),
    Err(err) => writeln!(&mut std::io::stderr(), "Error: {}", err).unwrap()
}

You can find the latest published release on crates.io

You can find the browseable docs for the latest release on docs.rs.

NOTE: master branch (code and docs) can differ from those docs prior to a new release.

Minimum rust version

The minimum rust version required, by version:

  • libproc-rs: 0.14.6 --> 1.74.1
  • libproc-rs: 0.14.7 --> 1.72.0

This is tested in CI and must pass.

Test Matrix

The Github Actions CI test libproc-rs on :

rust versions:

  • stable (must pass)
  • beta (must pass)
  • 1.72.0 (currently the minimum rust version supported) (must pass)
  • nightly (allowed to fail)

on the following platforms:

  • ubuntu-latest
  • macos-11 (Big Sur) (Intel)
  • macos-12 (Monterey) (Intel)
  • macos-13 (Ventura) (Intel)
  • macos-14 (Sonoma) (Arm64)

Examples

Two simple examples are included to show libproc-rs working.

  • procinfo that takes a PID as an optional argument (uses it's own pid if none supplied) and returns information about the process on stdout
  • dmesg is a version of dmesg implemented in rust that uses libproc-rs.

These can be ran thus: sudo cargo run --example procinfo or sudo cargo run --example dmesg

Contributing

You are welcome to fork this repo and make a pull request, or write an issue.

Experiment in OSS funding

I am exploring the ideas around Open Source Software funding from RadWorks Foundation via the Drips Project

This project is in Drips here

Input Requested

  • Suggestions for API, module re-org and cross-platform abstractions are welcome.
  • How to do error reporting? Define own new Errors, or keep simple with Strings?
  • Would like Path/PathBuf returned when it makes sense instead of String?

TODO

See the list of issues. I put the "help wanted" label where I need help from others.

  • Look at what similar methods could be implemented as a starting poon Linux
  • Complete the API on Mac OS X - figuring out all the Mac OS X / Darwin version mess....
  • Add more documentation (including samples with documentation test)
  • Add own custom error type and implement From::from to ease reporting of multiple error types in clients

Build and Test Locally

If you're feeling lucky today, start with make that will run clippy, test and will build docs also.

If you want to stay "pure rust" : cargo test will build and test as usual.

However, as some functions need to be run as root to work, CI tests are run as root. So, when developing in local it's best if you use sudo cargo test.

[!NOTE] This can get you into permissions problems when switching back and for between using cargo test and sudo cargo test. To fix that run sudo cargo clean and then build or test as you prefer.

In order to have tests pass when run as root or not, some tests need to check if they are root at run-time (using our own am_root() function is handy) and avoid failing if not run as root.

Using act to run GH Actions locally

If you develop on macos but want to ensure code builds and tests pass on linux while making changes, you can use the act tool to run the Github Actions Workflows on the test matrix.

Just install act (brew install act on macOS) (previously install docker if you don't have it already, and make sure the daemon is running) then run act push. You can test a subset of the rust and os versions of the matrix with something like act push --matrix os:ubuntu-latest

Enter the matrix

If you want to test locally as much of the test matrix as possible (different OS and versions of rust), that you can use make matrix. On macos, if you have act installed, it will use it to run the linux part of the matrix.

Macos: clang detection and header file finding

Newer versions of bindgen have improved the detection of clang and hence macos header files. If you also have llvm/clang installed directly or via brew this may cause the build to fail saying it cannot find libproc.h. This can be fixed by setting CLANG_PATH="/usr/bin/clang" so that bindgen detects the Xcode version and hence can fidn the correct header files.

Other docs

LICENSE

This code is licensed under MIT license (see LICENCE).

libproc-rs's People

Contributors

akhramov avatar andrewdavidmackenzie avatar dalance avatar dependabot[bot] avatar hardfau1t avatar ivxvm avatar jeff-hiner avatar jrabinow avatar lambda-fairy avatar luozijun avatar mjpieters avatar xd009642 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

libproc-rs's Issues

fix kmsgbuf() on macos

sudo cargo run --bin dmesg
Message buffer: MessageBuffer { magic: 0x63202c64, size: 1701340001, bufx: 824188972}
Error: The magic number 0x63202c64 is incorrect

Fix the regionfilename test

Currently the test/doctest is

/// # Examples
/// ```
/// use libproc::libproc::proc_pid::regionfilename;
///
/// // This checks that it can find the regionfilename of the region at address 0, of the init process with PID 1
/// match regionfilename(1, 0) {
///     Ok(regionfilename) => println!("Region Filename (at address = 0) of init process PID = 1 is '{}'", regionfilename),
///     Err(message) => assert!(true, message)
/// }
/// ```

So, when there is a problem it does assert(true) and hence never fails.
When asserting false it returns an "Invalid utf-8 sequence" error and fails.

We should understand this call and find a way to test it successfully.

Improve the docs

Improve overall docs - I need to learn how to properly document modules, structs, traits and functions in rust following the bets guidelines.

A couple of functions need descriptions or links to the apple docs on the subject

Unnecessary big vector allocation

Hey, first of all thanks for the efforts for making this library!
I have an optimization idea for listpids:
https://github.com/andrewdavidmackenzie/libproc-rs/blob/master/src/libproc/proc_pid.rs#L232

let mut pids: Vec<u32> = Vec::with_capacity(PID_MAX);

Function allocates (99999 * 4 / 1024) =~ 390kb of space for a buffer which is not that bad by modern standards but still unnecessary because it's possible to retrieve the desired buffer size beforehand by calling proc_listpids in a special way like this:

int numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);

Example code at the bottom of the question: https://stackoverflow.com/q/3018054

implement listpids() for linux

I guess this can be done by listing the entries in /proc and filtering for numeric values.
There doesn't seem to be any other recommended syscall or similar to do it.

Problems compiling in nixpkgs

I'm running into an issue compiling in nixpkgs environment. Building master right now, I get:

   Compiling libproc v0.12.0 (/private/tmp/libproc-rs)
error[E0432]: unresolved import `crate::osx_libproc_bindings::proc_pid_rusage`
  --> src/libproc/pid_rusage.rs:12:5
   |
12 | use crate::osx_libproc_bindings::proc_pid_rusage;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------
   |     |                            |
   |     |                            help: a similar name exists in the module: `PROC_PID_RUSAGE`
   |     no `proc_pid_rusage` in `osx_libproc_bindings`

This happens with either v10 or v11 sdk. Does the generation of this part depend on some extra headers I should have available? Anything else I can provide to debug this?

This happens with rust 1.63

Improve docs in docs.rs and remove repetition from README.md

CHeck the list of methods implemented as listed in readme. If there are any important ones missing, then create issues for them.

Improve the docs in docs.rs that a user of the lib would consult, to make api methods available more obvious and easier to understand.

Put some of the readme contents as crate level docs so readers know what they are getting when they go direct to docs.rs

How can I get the current thread id?

I tried libc::pthread_self. But it seems there is a fixed offset between the value fetched from libc::pthread_self and the value fetched from listpidinfo::<ListThreads>. Don't know why.

Code:

fn main() {
    use std::sync::{Mutex, Arc};
    use std::thread;
    use std::time::Duration;

    let mut ptids = Arc::new(Mutex::new(vec![unsafe { libc::pthread_self() }]));
    let mut threads = vec![];
    for _ in 0..3 {
        let ptids = ptids.clone();
        threads.push(thread::spawn(move || {
            let mut ptids = ptids.lock().unwrap();
            (*ptids).push(unsafe { libc::pthread_self() });
            drop(ptids);
            thread::sleep(Duration::from_millis(1000));
        }));
    }

    thread::sleep(Duration::from_millis(500)); // wait for creating threads
    let pid = std::process::id() as i32;
    let info = pidinfo::<TaskAllInfo>(pid, 0).unwrap();
    let tids = listpidinfo::<ListThreads>(pid, info.ptinfo.pti_threadnum as usize).unwrap();

    println!("tids from pthread_self: {:?}", ptids.lock().unwrap());
    println!("tids from listpidinfo: {:?}", tids);

    threads.into_iter().for_each(|t| t.join().unwrap());
}

Output:

tids from pthread_self: [4509474304, 123145435578368, 123145439797248, 123145437687808]
tids from listpidinfo: [4509474528, 123145435578592, 123145437688032, 123145439797472]

Any help? @andrewdavidmackenzie

Can't compile on rustc 1.74.1

Hi,

The latest version uses std::ptr::from_mut (it looks like to fix a clippy warning), but that was only just stabilized in 1.76.0.

Nushell is building on 1.74 at the moment, and can't build anymore with the latest version. This is a breaking change to minimum Rust version.

See: nushell/nushell#12182 (comment)

Would you please replace with something that works on 1.74, or bump major and clarify minimum rust version in Cargo.toml?

Thanks.

macOS 11/Apple silicon showing high virtual memory usage

Was noticing on my mbp with an M1 Pro, the virtual memory usage is being listed as really high numbers. Nushell uses libproc get query this info, and all the virtual memory numbers that come back are hundreds of gigs.

Is there something we should be doing on the nushell side or is this libproc-related?

image

Add calls that were added in 10.7

for proc_pid.rs:

// Added in 10.7
// int proc_listallpids(void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1);
// int proc_listpgrppids(pid_t pgrpid, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1);
// int proc_listchildpids(pid_t ppid, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1);
// int proc_pidfileportinfo(int pid, uint32_t fileport, int flavor, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);

Linux support/project active?

Hi, I'm interested in the libproc functionality for a Linux project I'm working on, but it looks like the project might be abandoned/dormant? Are there any plans to continue the project and what barriers are in the way of it working on linux?

I'm more than happy to contribute to attempt to get Linux support working and help out in general. Just let me know πŸ˜„

Publish crate version 0.1.1?

I want to publish a crate that depends on libproc, but I can't because the current published version has the double-free bug fixed in this commit. e7d2319

Failed to build libproc bindings

System: macOS 11.0.1

Cargo.toml:

[package]
# ...

[dependencies]
libproc = "0.12.0"

Error:

   Compiling libproc v0.12.0
error: failed to run custom build command for `libproc v0.12.0`

Caused by:
  process didn't exit successfully: `<PROJECT PATH>/target/debug/build/libproc-7ab682cfcd895988/build-script-build` (exit status: 101)
  --- stderr
  <HOME>/.cargo/registry/src/github.com-1ecc6299db9ec823/libproc-0.12.0/libproc_rs.h:1:10: fatal error: 'libproc.h' file not found
  <HOME>/.cargo/registry/src/github.com-1ecc6299db9ec823/libproc-0.12.0/libproc_rs.h:1:10: fatal error: 'libproc.h' file not found, err: true
  thread 'main' panicked at 'Failed to build libproc bindings: ()', <HOME>/.cargo/registry/src/github.com-1ecc6299db9ec823/libproc-0.12.0/build.rs:9:10
  stack backtrace:
     0: rust_begin_unwind
               at /rustc/62b272d25c5bb8b6bb8ac73797d82b8b9a1eabda/library/std/src/panicking.rs:584:5
     1: core::panicking::panic_fmt
               at /rustc/62b272d25c5bb8b6bb8ac73797d82b8b9a1eabda/library/core/src/panicking.rs:142:14
     2: core::result::unwrap_failed
               at /rustc/62b272d25c5bb8b6bb8ac73797d82b8b9a1eabda/library/core/src/result.rs:1805:5
     3: core::result::Result<T,E>::expect
               at /rustc/62b272d25c5bb8b6bb8ac73797d82b8b9a1eabda/library/core/src/result.rs:1055:23
     4: build_script_build::main
               at ./build.rs:6:20
     5: core::ops::function::FnOnce::call_once
               at /rustc/62b272d25c5bb8b6bb8ac73797d82b8b9a1eabda/library/core/src/ops/function.rs:248:5
  note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

If I can give you any more info, please notify me in the comment.

How to collect memory information for a process on non-Mac OS?

Hey!

This library is great, but unfortunately I ran into an issue where to collect process memory, apparently I need to use libproc::pid_rusage? But that seems to be only available on Mac OS?

The docs say this "was added in Mac OS X 10.9" but it wasn't clear to me it was not available on other OSs.

What I want is probably just "resident memory" (in lay terms, how much RAM the process is using). Is there a way to get that which works on all Windows, Linux and Mac OS?

Thanks.

macos11 nightly fails with clippy misaligned access warning

I assume that this check will progress to stable before too long and break everything, so we will have to fix it.

Apart from disabling from the root of the crate, not sure there is a lot we can do, as this is in bindgen generated code.

Compiling libproc v0.11.1 (/Users/runner/work/libproc-rs/libproc-rs)
error: reference to packed field is unaligned
 --> /Users/runner/work/libproc-rs/libproc-rs/target/debug/build/libproc-ec97c35fbd[55](https://github.com/andrewdavidmackenzie/libproc-rs/runs/6163681943?check_suite_focus=true#step:4:55)2ca1/out/osx_libproc_bindings.rs:3:373846
  |
3 | ...state))) ; assert_eq ! (unsafe { & (* (:: std :: ptr :: null :: < searchstate > ())) . ss_union_flags as * const _ as usize } , 0usize...
  |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[deny(unaligned_references)]` on by default
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
  = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
  = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)

Occaisional SEG faults

Sometimes the tests fail due to a segfault, running locally this can be as infrequent as 1 in 10 to 20 runs.

So, no idea what's causing this - it makes me suspicious of the stability/usability of the underlying libproc.a library on more recent Mac OS X versions. But the 'C' version never seems to fail, so I'm not sure....

Needs investigation that's for sure.

Stable and Nightly fail due to unaligned access warning

error: reference to packed field is unaligned
 --> /Users/runner/work/libproc-rs/libproc-rs/target/debug/build/libproc-16321469bc40d5c5/out/osx_libproc_bindings.rs:3:673744
  |
3 | ...ze))) ; assert_eq ! (unsafe { & (* (:: std :: ptr :: null :: < proc_exitreasoninfo > ())) . eri_kcd_buf as * const _ as usize } , 24us...
  |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
  = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
  = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)

error: could not compile `libproc` due to 110 previous errors
Error: Process completed with exit code 101.

More detailed doc comments

It would be great for someone who understands more of the details of the Darwin kernel structures to help add more informative doc comments for them in the code

Create a mapping of OS version to XNU version to variants available

Ass Apple updates darwin, it adds some new variants (flavors) available to some API calls (e.g. proc_pidinfo()).

Create a mapping of
XNU version --> What variants available --> What versions of mac os support them

So we can make conditional code on OS versions, and maybe also allow to detect the OS version at runtime and hence check the flavors that can be used in some api calls.

Fix publishing of docs page

The GH Action claims to post to my site, but it's not working or not there - so fix it and add a link in readme or cargo.toml (for crates.io) or something.

build error in aosp rust

error 1:

error[E0425]: cannot find function `listpids` in this scope
  --> external/rust/crates/libproc-rs/src/processes.rs:68:5
   |
68 |     listpids(filter)
   |     ^^^^^^^^ not found in this scope
   |
help: consider importing this function
   |
1  + use crate::libproc::proc_pid::listpids;
   |

error: aborting due to previous error

error 2:

error[E0308]: mismatched types
   --> external/rust/crates/libproc-rs/src/processes.rs:69:14
    |
69  |     listpids(filter)
    |     -------- ^^^^^^ expected `ProcType`, found `ProcFilter`
    |     |
    |     arguments to this function are incorrect
    |
note: function defined here
   --> external/rust/crates/libproc-rs/src/libproc/proc_pid.rs:185:8
    |
185 | pub fn listpids(proc_types: ProcType) -> Result<Vec<u32>, String> {
    |        ^^^^^^^^ --------------------

error[E0308]: mismatched types
  --> external/rust/crates/libproc-rs/src/processes.rs:69:5
   |
68 | pub fn pids_by_type(filter: ProcFilter) -> io::Result<Vec<u32>> {
   |                                            -------------------- expected `Result<Vec<u32>, std::io::Error>` because of return type
69 |     listpids(filter)
   |     ^^^^^^^^^^^^^^^^ expected `Result<Vec<u32>, Error>`, found `Result<Vec<u32>, String>`
   |
   = note: expected enum `Result<_, std::io::Error>`
              found enum `Result<_, String>`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0308`.
18:21:05 ninja failed with: exit status 1

#### failed to build some targets (4 seconds) ####

MacOS: accept a typeinfo argument for listpids

Currently, listpids sets the typeinfo argument to proc_listpids to 0:

pub fn listpids(proc_types: ProcType) -> Result<Vec<u32>, String> {
let buffer_size = unsafe { proc_listpids(proc_types as u32, 0, ptr::null_mut(), 0) };

That makes perfect sense for ProcType::ProcAllPIDS, but when using any of the other ProcType variants, a call to proc_listpids only makes sense if you pass in the matching ID as the typeeinfo value, e.g. for ProcType::ProcPGRPOnly, you can pass in the program group id (PGID) and get only those processes that are part of the process group.

To illustrate, you could try creating a process with the command_group crate, such as a shell script that spawns a couple of sleep <large number> background processes. This gets you a GroupChild struct with a .id() method returning the process group ID. If you then use proc_listpids(proc_pid::ProcType::ProcPGRPOnly, child.id(), buffer_ptr, buffer_size) the buffer is filled with the PIDs of the processes in that process group.

The (abandoned?) darwin-libproc crate has separate functions for each ProcType variant to pass in the corresponding identifiers.

Can libproc-rs please offer the same options?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.