foniod / redbpf

Rust library for building and running BPF/eBPF modules
Apache License 2.0
1.71k stars 136 forks source link

redbpf fails to parse WSL2 Kernel version #284

Closed Sparika closed 2 years ago

Sparika commented 2 years ago

I followed the tutorial on my WSL2 environment. The user space program panics when unwraping None within get_version. Here is the backtrace:

Feb 10 22:31:32.599  WARN redbpf: Failed to load BTF but BTF is optional. Ignore it
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', /home/kcorre/.cargo/registry/src/github.com-1ecc6299db9ec823/redbpf-2.3.0/src/lib.rs:2765:54
stack backtrace:
   0: rust_begin_unwind
             at /rustc/04caa632dd10c2bf64b69524c7f9c4c30a436877/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/04caa632dd10c2bf64b69524c7f9c4c30a436877/library/core/src/panicking.rs:92:14
   2: core::panicking::panic
             at /rustc/04caa632dd10c2bf64b69524c7f9c4c30a436877/library/core/src/panicking.rs:50:5
   3: core::option::Option<T>::unwrap
             at /home/kcorre/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:386:21
   4: redbpf::get_version
             at /home/kcorre/.cargo/registry/src/github.com-1ecc6299db9ec823/redbpf-2.3.0/src/lib.rs:2765:24
   5: redbpf::ModuleBuilder::parse
             at /home/kcorre/.cargo/registry/src/github.com-1ecc6299db9ec823/redbpf-2.3.0/src/lib.rs:1429:70
   6: redbpf::Module::parse
             at /home/kcorre/.cargo/registry/src/github.com-1ecc6299db9ec823/redbpf-2.3.0/src/lib.rs:1188:9
   7: redbpf::load::loader::Loader::load
             at /home/kcorre/.cargo/registry/src/github.com-1ecc6299db9ec823/redbpf-2.3.0/src/load/loader.rs:38:26
   8: redbpf_tutorial::main::{{closure}}
             at ./src/main.rs:27:22
   ...
  26: redbpf_tutorial::main
             at ./src/main.rs:36:5
  27: core::ops::function::FnOnce::call_once
             at /home/kcorre/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5

While investigating the issue, I found that parse_version function expects a kernel version in x.y.z format. However, the WSL2 kernel version I use has 4 elements.

println!("{:?}", redbpf::uname::to_str(&redbpf::uname::uname().ok().expect("it's an error").release));
println!("{:?}", redbpf::uname::get_kernel_internal_version());

RUST_BACKTRACE=1 KERNEL_VERSION=5.4.0-99-generic sudo -E ./target/debug/redbpf-tutorial 
"5.10.93.2-microsoft-standard-WSL2"
None
Sparika commented 2 years ago

https://github.com/foniod/redbpf/blob/5c58457fbb7b882b31225d1cdf07f5f00ef11390/bpf-sys/src/uname.rs#L70

Sparika commented 2 years ago

The following code snippets fix the issue for me

fn parse_version(version: &str) -> Option<(u32, u32, u32)> {
    if let Some(version) = version.splitn(2, '-').next() {
        if let Some(version) = version.splitn(2, '+').next() {
            let parts: Vec<_> = version.splitn(4, '.').filter_map(|v| u32::from_str(v).ok()).collect();
            if parts.len() < 3 {
                return None;
            }
            return Some((parts[0], parts[1], parts[2]))
        }
    }

    None
}
Forsworns commented 2 years ago

Encountered the same problem :) By the way, how do you use sudo on cargo, I tried sudo -E but it did not work

rsdy commented 2 years ago

@Forsworns you realistically cargo build --release, and sudo ./target/release/program as 2 separate steps.

rsdy commented 2 years ago

@Sparika would you mind opening a PR for the changeset that got it working for you? Seems like a useful addition to the lib.

rsdy commented 2 years ago

@Forsworns Ah, now I got ya! It would be helpful if you could open a separate issue with your problem and error messages you're getting. Unfortunately I don't have a Windows box on hand, so I can only help you remotely based on these.