Giter Club home page Giter Club logo

mevi's Introduction

mevi

A memory visualizer for Linux 5.7+

Made for this video: https://www.youtube.com/watch?v=DpnXaNkM9_M

Prerequisite

The vm.unprivileged_userfaultfd sysctl needs to be switched to 1:

$ sudo sysctl -w vm.unprivileged_userfaultfd=1

Doing this effectively "softens" your system to some attacks, so only do this in a VM or if you're reckless, but also, it seems less awful than running mevi + tracees as root. (No, giving the mevi binary CAP_PTRACE isn't enough).

You can technically run a bunch of apps with only user faults, but some fairly basic stuff like cat /hosts will fail with EFAULT without it, so, I'm not making it easy to go that route - if you really know what you're doing you can figure out where to pass the "user faults only" flag.

Usage

Install the mevi executable:

$ just install

(Or, without just, look into the Justfile for the cargo invocation)

To build & serve the frontend, you'll need to install support for the wasm target via rustup:

$ rustup target add wasm32-unknown-unknown

And to have trunk installed.

$ just serve

Open the frontend in your browser: http://localhost:8080

From another terminal, start the program you want to trace via mevi:

$ mevi PROGRAM ARGS

The frontend should connect to http://localhost:5001/stream.

If you're running this on a remote server, you'll need to forward both ports, with SSH for example:

ssh -L 5001:localhost:5001 -L 8080:localhost:8080 your-remote-host

License

This project is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0).

See LICENSE-APACHE and LICENSE-MIT for details.

FAQ / Troubleshooting

I get EPERM at some point

Did you skip past that sysctl note above?

The RSS numbers don't match up with htop/btop/procmaps etc.

mevi only tracks private+anonymous memory mappings. The discrepancy probably comes from mapped files, and to a lesser extent, shared memory.

I have a tiny program and everything goes by way too fast.

Try sleeping in your loops! Computers go fast noawadays and mevi tries not to slow your program down.

I have a multi-threaded program and it's all wrong

Yeah, sorry about that. userfaultfd events don't have all the info we need, and ptrace observes events out-of-order, so the view of multi-threaded programs gets out-of-sync with the kernel.

Can I run this on a big program?

Sure, Firefox works, with a non-snap version, and with sandbox disabled, like so (THIS IS DANGEROUS, THE SANDBOX IS THERE FOR A REASON).

First let's make sure you don't have firefox running in the background:

$ pkill firefox
# you can do it several times, until `pidof firefox` returns nothing

Then:

$ RUST_LOG=error RUST_BACKTRACE=1 MOZ_DISABLE_CONTENT_SANDBOX=1 MOZ_DISABLE_GMP_SANDBOX=1 MOZ_DISABLE_RDD_SANDBOX=1 MOZ_DISABLE_SOCKET_PROCESS_SANDBOX=1 mevi /usr/lib/firefox/firefox

Does this show backtraces?

No, but you can do that in your fork.

Does this allow travelling back in time?

No, but you can do that in your fork.

Does this have yet another, secret third feature?

Clearly not, but again, you can do that in your fork. This is a research project, I will not be maintaining it beyond "have it run in its current form".

If you want to spin this out into its own product, more power to you, but I'll have already moved on.

Why isn't this published on crates.io?

It's not a library and it's not usable without the frontend anyway. One day stable cargo will let us build wasm artifacts and ship them with the resulting binary, but that day is not today.

Why isn't this using eBPF?

I wanted to see how far I could take ptrace + userfaultfd. I'm interested in exploring eBPF later.

mevi's People

Contributors

fasterthanlime 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  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  avatar  avatar  avatar  avatar  avatar

mevi's Issues

Unhandled mmap for a region without protection flags (`PROT_READ | PROT_WRITE`)

Hi! It's me again ;) Well, it's been a couple of weeks since I've been struggling with finding out why is my Rust debuginfod consuming an unexpected amount of resident memory (even after malloc_trim) and I thought your tool might help me. The project is not so complex, but it does a multithreaded inspection of RPM files.

For my demo test-case I get to something like:

$ RAYON_NUM_THREADS=100 mevi ./target/release/debuginfod-rs ~/Downloads/RPM-part
...
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
marxin   10970 21.7  0.1 8392676 105408 pts/4  Sl+  20:46   0:00 ./target/release/debuginfod-rs /home/marxin/Downloads/RPM-part

So my app consumes ~100MiB, while MEVI reports only < 1MiB which is my expected output:
Screenshot from 2024-01-15 20-47-56

Full MEVI log:
mevi-log.txt

Looking closer to pmap, there are really ranges where there are tens of mebibytes mapped:

Address           Kbytes     RSS     PSS   Dirty    Swap Mode  Mapping
00007f8e88000000   17544   14340   14340   14340       0 rw-p-   [ anon ]
00007f8e89122000   47992       0       0       0       0 ---p-   [ anon ]
00007f8e8c000000     132       4       4       4       0 rw-p-   [ anon ]
00007f8e8c021000   65404       0       0       0       0 ---p-   [ anon ]
00007f8e90000000   25548   24048   24048   24048       0 rw-p-   [ anon ]
00007f8e918f3000   39988       0       0       0       0 ---p-   [ anon ]
00007f8e94000000   12944    6164    6164    6164       0 rw-p-   [ anon ]
00007f8e94ca4000   52592       0       0       0       0 ---p-   [ anon ]
00007f8e98000000   11556    6152    6152    6152       0 rw-p-   [ anon ]
00007f8e98b49000   53980       0       0       0       0 ---p-   [ anon ]
00007f8e9c000000   10992    4128    4128    4128       0 rw-p-   [ anon ]
00007f8e9cabc000   54544       0       0       0       0 ---p-   [ anon ]
00007f8ea0000000   16240   16156   16156   16156       0 rw-p-   [ anon ]
00007f8ea0fdc000   49296       0       0       0       0 ---p-   [ anon ]
00007f8ea4000000   11312    4132    4132    4132       0 rw-p-   [ anon ]
00007f8ea4b0c000   54224       0       0       0       0 ---p-   [ anon ]
00007f8ea8000000    9860    4112    4112    4112       0 rw-p-   [ anon ]
00007f8ea89a1000   55676       0       0       0       0 ---p-   [ anon ]
00007f8eac000000   11980    6160    6160    6160       0 rw-p-   [ anon ]
00007f8eacbb3000   53556       0       0       0       0 ---p-   [ anon ]
00007f8eb0000000    9528    1016    1016    1016       0 rw-p-   [ anon ]
00007f8eb094e000   56008       0       0       0       0 ---p-   [ anon ]
00007f8eb4000000    9636    1612    1612    1612       0 rw-p-   [ anon ]
00007f8eb4969000   55900       0       0       0       0 ---p-   [ anon ]
00007f8eb8000000    8980     364     364     364       0 rw-p-   [ anon ]
00007f8eb88c5000   56556       0       0       0       0 ---p-   [ anon ]
00007f8ebc000000    8988     572     572     572       0 rw-p-   [ anon ]
00007f8ebc8c7000   56548       0       0       0       0 ---p-   [ anon ]
00007f8ec0000000     176     176     176     176       0 rw-p-   [ anon ]
00007f8ec002c000   65360       0       0       0       0 ---p-   [ anon ]
00007f8ec41e1000       4       0       0       0       0 ---p-   [ anon ]
00007f8ec41e2000    2048       8       8       8       0 rw-p-   [ anon ]

Again, I know the tool is just a hobby project, but if you are interested, I can debug the problem. But any hint would be appreciated.

Thanks!

Yanked spin version

Got the following warning on just install: warning: package ``spin v0.9.6`` in Cargo.lock is yanked in registry ``crates-io``, consider running without --locked

mevi panics when ran on sandboxed chromium

Command : target/release/mevi chromium
Result :

2023-03-23T14:52:11.818086Z  WARN mevi::tracer: a thread is changing the brk for the process, we should handle that
[26942] => [1] mapping 7fdf7a100000..7fdf7a102000 (8 KiB) with NotResident
The application panicked (crashed).
Message:  called `Option::unwrap()` on a `None` value
Location: crates/mevi/src/tracer.rs:200

'hack' to bypass the issue ? :

diff --git a/crates/mevi/src/tracer.rs b/crates/mevi/src/tracer.rs
index 4518cb1..dd0dbc4 100644
--- a/crates/mevi/src/tracer.rs
+++ b/crates/mevi/src/tracer.rs
@@ -195,7 +195,9 @@ impl Tracer {
                                         "{tid} => {for_tid} mapping {range:x?} ({}) with {state:?}",
                                         formatter(range.end - range.start)
                                     );
-                                    let target = self.tracees.get(&for_tid).unwrap();
+                                    let target = self.tracees.get(&for_tid);
+                                    if target.is_some() {
+                                    let target = target.unwrap();
                                     match &target.kind {
                                         TraceeKind::Fresh => unreachable!(),
                                         TraceeKind::Process { uffd, .. } => {
@@ -213,6 +215,7 @@ impl Tracer {
                                             panic!("thread {for_tid} of process {pid} mapping memory should show up in the parent");
                                         }
                                     }
+                                }

                                     let ev = MeviEvent::TraceeEvent(
                                         for_tid,

Build failure: "uffd_msg_union_(unnamed_at_/usr/include/linux/userfaultfd_h_109_2)" is not a valid Ident

First of all, I would like to thank you for the great videos you've been doing!
I wanted to build the project, but I've got the following error:

just install
cargo install --locked --path crates/mevi
warning: virtual workspace defaulting to `resolver = "1"` despite one or more workspace members being on edition 2021 which implies `resolver = "2"`
note: to keep the current resolver, specify `workspace.resolver = "1"` in the workspace root's manifest
note: to use the edition 2021 resolver, specify `workspace.resolver = "2"` in the workspace root's manifest
note: for more details see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions
warning: virtual workspace defaulting to `resolver = "1"` despite one or more workspace members being on edition 2021 which implies `resolver = "2"`
note: to keep the current resolver, specify `workspace.resolver = "1"` in the workspace root's manifest
note: to use the edition 2021 resolver, specify `workspace.resolver = "2"` in the workspace root's manifest
note: for more details see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions
  Installing mevi v0.1.0 (/home/marxin/Programming/mevi/crates/mevi)
    Updating crates.io index
warning: package `bumpalo v3.12.1` in Cargo.lock is yanked in registry `crates-io`, consider running without --locked
warning: package `hermit-abi v0.3.1` in Cargo.lock is yanked in registry `crates-io`, consider running without --locked
   Compiling userfaultfd-sys v0.4.2 (https://github.com/fasterthanlime/userfaultfd-rs?rev=e9160a896f7d8d80c8b0943480885598bd698d0#e9160a89)
   Compiling heapless v0.7.16
   Compiling serde_json v1.0.96
   Compiling tokio-tungstenite v0.18.0
   Compiling serde_urlencoded v0.7.1
   Compiling tower v0.4.13
   Compiling serde_path_to_error v0.1.11
   Compiling rangemap v1.3.0
   Compiling hyper v0.14.26
   Compiling postcard v1.0.4
error: failed to run custom build command for `userfaultfd-sys v0.4.2 (https://github.com/fasterthanlime/userfaultfd-rs?rev=e9160a896f7d8d80c8b0943480885598bd698d0#e9160a89)`

Caused by:
  process didn't exit successfully: `/home/marxin/Programming/mevi/target/release/build/userfaultfd-sys-dd81e8e5c79cc072/build-script-build` (exit status: 101)
  --- stderr
  thread 'main' panicked at /home/marxin/.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/src/fallback.rs:811:9:
  "uffd_msg_union_(unnamed_at_/usr/include/linux/userfaultfd_h_109_2)" is not a valid Ident
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
error: failed to compile `mevi v0.1.0 (/home/marxin/Programming/mevi/crates/mevi)`, intermediate artifacts can be found at `/home/marxin/Programming/mevi/target`.
To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path.
error: Recipe `install` failed on line 7 with exit code 101

CLang is required to install, but not in Readme.md

While trying to install mevi to my PopOS machine I got the following error:

error: failed to run custom build command for `userfaultfd-sys v0.4.2 (https://github.com/fasterthanlime/userfaultfd-rs?rev=e9160a896f7d8d80c8b0943480885598bd698d0#e9160a89)`

Caused by:
  process didn't exit successfully: `/home/sotrh/code/mevi/target/release/build/userfaultfd-sys-fcd893f786207cc7/build-script-build` (exit status: 101)
  --- stderr
  thread 'main' panicked at 'Unable to find libclang: "couldn't find any valid shared libraries matching: ['libclang.so', 'libclang-*.so', 'libclang.so.*', 'libclang-*.so.*'], set the `LIBCLANG_PATH` environment variable to a path where one of these files can be found (invalid: [])"', /home/sotrh/.cargo/registry/src/github.com-1ecc6299db9ec823/bindgen-0.60.1/src/lib.rs:2172:31
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
error: failed to compile `mevi v0.1.0 (/home/sotrh/code/mevi/crates/mevi)`, intermediate artifacts can be found at `/home/sotrh/code/mevi/target`
error: Recipe `install` failed on line 7 with exit code 101

Doing sudo apt install clang fixed the issue, but the Readme should include that CLang is required to install this project.

Error build serve

just serve trunk serve --release crates/mevi-frontend/index.html sh: line 1: trunk: command not found error: Recipe servefailed on line 10 with exit code 127

cannot find value `_UFFDIO_WRITEPROTECT` in this scope

I try to build on Ubuntu 2004, and I've this error during the build of userfaultfd-rs crate:

  error[E0425]: cannot find value `_UFFDIO_WRITEPROTECT` in this scope
  --> src/linux5_7.rs:20:74
   |
20 |     1 << _UFFDIO_WAKE | 1 << _UFFDIO_COPY | 1 << _UFFDIO_ZEROPAGE | 1 << _UFFDIO_WRITEPROTECT;
   |                                                                          ^^^^^^^^^^^^^^^^^^^^ help: a constant with a similar name exists: `UFFDIO_WRITEPROTECT`
...
38 | pub const UFFDIO_WRITEPROTECT: u32 = 0xc018aa06;
   | ------------------------------------------------ similarly named constant `UFFDIO_WRITEPROTECT` defined here

I try several kernel headers versions after 5.7 but none works.

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.