diff --git a/examples/opensnoop.rs b/examples/opensnoop.rs index db937d4..7948f0b 100644 --- a/examples/opensnoop.rs +++ b/examples/opensnoop.rs @@ -1,7 +1,7 @@ extern crate bcc; extern crate byteorder; -extern crate libc; extern crate failure; +extern crate libc; use std::ptr; @@ -16,7 +16,7 @@ use failure::Error; * Prints out the filename + PID every time a file is opened */ -/* +/* * Define the struct the BPF code writes in Rust * This must match the struct in `opensnoop.c` exactly. * The important thing to understand about the code in `opensnoop.c` is that it creates structs of @@ -27,7 +27,7 @@ struct data_t { id: u64, ts: u64, ret: libc::c_int, - comm: [u8; 16], // TASK_COMM_LEN + comm: [u8; 16], // TASK_COMM_LEN fname: [u8; 255], // NAME_MAX } @@ -56,7 +56,12 @@ fn perf_data_callback() -> Box { Box::new(|x| { // This callback let data = parse_struct(x); - println!("{:-7} {:-16} {}", data.id >> 32, get_string(&data.comm), get_string(&data.fname)); + println!( + "{:-7} {:-16} {}", + data.id >> 32, + get_string(&data.comm), + get_string(&data.fname) + ); }) } diff --git a/examples/softirqs.rs b/examples/softirqs.rs index 172be2a..a62d3e1 100644 --- a/examples/softirqs.rs +++ b/examples/softirqs.rs @@ -1,7 +1,7 @@ extern crate bcc; extern crate byteorder; -extern crate libc; extern crate failure; +extern crate libc; use bcc::core::BPF; use failure::Error; @@ -12,7 +12,6 @@ use std::{fmt, mem, ptr, thread, time}; // // Based on: https://github.com/iovisor/bcc/blob/master/tools/softirqs.py - #[repr(C)] struct irq_key_t { vec: u32, @@ -107,7 +106,6 @@ fn do_main() -> Result<(), Error> { let softirq = SoftIRQ::from(id); println!("softirq: {} time (ns): {}", softirq, time); } - } } } diff --git a/examples/strlen.rs b/examples/strlen.rs index 20a9744..ddda0bd 100644 --- a/examples/strlen.rs +++ b/examples/strlen.rs @@ -1,10 +1,10 @@ extern crate bcc; extern crate byteorder; -extern crate libc; extern crate failure; +extern crate libc; -use byteorder::{NativeEndian, ReadBytesExt}; use bcc::core::BPF; +use byteorder::{NativeEndian, ReadBytesExt}; use failure::Error; use std::io::Cursor; @@ -32,12 +32,17 @@ int count(struct pt_regs *ctx) { "; let mut module = BPF::new(code)?; let uprobe_code = module.load_uprobe("count")?; - module.attach_uprobe("/lib/x86_64-linux-gnu/libc.so.6", "strlen", uprobe_code, -1 /* all PIDs */)?; + module.attach_uprobe( + "/lib/x86_64-linux-gnu/libc.so.6", + "strlen", + uprobe_code, + -1, /* all PIDs */ + )?; let table = module.table("counts"); loop { std::thread::sleep(std::time::Duration::from_millis(1000)); for e in &table { - // key and value are each a Vec so we need to transform them into a string and + // key and value are each a Vec so we need to transform them into a string and // a u64 respectively let key = get_string(&e.key); let value = Cursor::new(e.value).read_u64::().unwrap(); diff --git a/rustfmt.toml b/rustfmt.toml index 0468aa5..f3986a8 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,2 +1,4 @@ reorder_imports = true -reorder_imported_names = true +reorder_modules = true +use_field_init_shorthand = true +use_try_shorthand = true \ No newline at end of file diff --git a/src/core/kprobe.rs b/src/core/kprobe.rs index 03f140f..cb2b07b 100644 --- a/src/core/kprobe.rs +++ b/src/core/kprobe.rs @@ -1,7 +1,7 @@ -use failure::Error; -use bcc_sys::bccapi::*; use bcc_sys::bccapi::bpf_probe_attach_type_BPF_PROBE_ENTRY as BPF_PROBE_ENTRY; use bcc_sys::bccapi::bpf_probe_attach_type_BPF_PROBE_RETURN as BPF_PROBE_RETURN; +use bcc_sys::bccapi::*; +use failure::Error; use core::make_alphanumeric; use types::MutPointer; @@ -21,12 +21,10 @@ pub struct Kprobe { impl Kprobe { fn new(name: &str, attach_type: u32, function: &str, code: File) -> Result { - let cname = CString::new(name).map_err(|_| { - format_err!("Nul byte in Kprobe name: {}", name) - })?; - let cfunction = CString::new(function).map_err(|_| { - format_err!("Nul byte in Kprobe function: {}", function) - })?; + let cname = + CString::new(name).map_err(|_| format_err!("Nul byte in Kprobe name: {}", name))?; + let cfunction = CString::new(function) + .map_err(|_| format_err!("Nul byte in Kprobe function: {}", function))?; let (pid, cpu, group_fd) = (-1, 0, -1); let ptr = unsafe { bpf_attach_kprobe( diff --git a/src/core/mod.rs b/src/core/mod.rs index 55eef20..bfa5f1e 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -2,8 +2,8 @@ mod kprobe; mod tracepoint; mod uprobe; -use failure::Error; use bcc_sys::bccapi::*; +use failure::Error; use self::kprobe::Kprobe; use self::tracepoint::Tracepoint; @@ -27,17 +27,17 @@ pub struct BPF { } fn make_alphanumeric(s: &str) -> String { - s.replace(|c| { - !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) - }, "_") + s.replace( + |c| !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')), + "_", + ) } impl BPF { /// `code` is a string containing C code. See https://github.com/iovisor/bcc for examples pub fn new(code: &str) -> Result { let cs = CString::new(code)?; - let ptr = - unsafe { bpf_module_create_c_from_string(cs.as_ptr(), 2, ptr::null_mut(), 0) }; + let ptr = unsafe { bpf_module_create_c_from_string(cs.as_ptr(), 2, ptr::null_mut(), 0) }; if ptr.is_null() { return Err(format_err!("couldn't create BPF program")); } diff --git a/src/core/tracepoint.rs b/src/core/tracepoint.rs index 5e76d9f..9383aac 100644 --- a/src/core/tracepoint.rs +++ b/src/core/tracepoint.rs @@ -1,5 +1,5 @@ -use failure::Error; use bcc_sys::bccapi::*; +use failure::Error; use types::MutPointer; @@ -18,17 +18,11 @@ pub struct Tracepoint { } impl Tracepoint { - pub fn attach_tracepoint( - subsys: &str, - name: &str, - file: File, - ) -> Result { - let cname = CString::new(name).map_err(|_| { - format_err!("Nul byte in Tracepoint name: {}", name) - })?; - let csubsys = CString::new(subsys).map_err(|_| { - format_err!("Nul byte in Tracepoint subsys: {}", subsys) - })?; + pub fn attach_tracepoint(subsys: &str, name: &str, file: File) -> Result { + let cname = + CString::new(name).map_err(|_| format_err!("Nul byte in Tracepoint name: {}", name))?; + let csubsys = CString::new(subsys) + .map_err(|_| format_err!("Nul byte in Tracepoint subsys: {}", subsys))?; // NOTE: BPF events are system-wide and do not support CPU filter let (pid, cpu, group_fd) = (-1, 0, -1); let ptr = unsafe { @@ -44,9 +38,13 @@ impl Tracepoint { ) }; if ptr.is_null() { - return Err(format_err!("Failed to attach tracepoint: {}:{}", subsys, name)); + return Err(format_err!( + "Failed to attach tracepoint: {}:{}", + subsys, + name + )); } else { - Ok(Self{ + Ok(Self { subsys: csubsys, name: cname, code_fd: file, diff --git a/src/core/uprobe.rs b/src/core/uprobe.rs index aac5cd7..0c458af 100644 --- a/src/core/uprobe.rs +++ b/src/core/uprobe.rs @@ -1,7 +1,7 @@ -use failure::Error; -use bcc_sys::bccapi::*; use bcc_sys::bccapi::bpf_probe_attach_type_BPF_PROBE_ENTRY as BPF_PROBE_ENTRY; use bcc_sys::bccapi::bpf_probe_attach_type_BPF_PROBE_RETURN as BPF_PROBE_RETURN; +use bcc_sys::bccapi::*; +use failure::Error; use core::make_alphanumeric; use symbol; @@ -29,12 +29,10 @@ impl Uprobe { file: File, pid: pid_t, ) -> Result { - let cname = CString::new(name).map_err(|_| { - format_err!("Nul byte in Uprobe name: {}", name) - })?; - let cpath = CString::new(path).map_err(|_| { - format_err!("Nul byte in Uprobe path: {}", name) - })?; + let cname = + CString::new(name).map_err(|_| format_err!("Nul byte in Uprobe name: {}", name))?; + let cpath = + CString::new(path).map_err(|_| format_err!("Nul byte in Uprobe path: {}", name))?; // TODO: maybe pass in the CPU & PID instead of let (cpu, group_fd) = (0, -1); let uprobe_ptr = unsafe { @@ -54,7 +52,7 @@ impl Uprobe { if uprobe_ptr.is_null() { return Err(format_err!("Failed to attach Uprobe: {}", name)); } else { - Ok(Self{ + Ok(Self { code_fd: file, name: cname, p: uprobe_ptr, @@ -62,7 +60,12 @@ impl Uprobe { } } - pub fn attach_uprobe(binary_path: &str, symbol: &str, code: File, pid: pid_t) -> Result { + pub fn attach_uprobe( + binary_path: &str, + symbol: &str, + code: File, + pid: pid_t, + ) -> Result { let (path, addr) = symbol::resolve_symbol_path(binary_path, symbol, 0x0, pid)?; let alpha_path = make_alphanumeric(&path); let ev_name = format!("r_{}_0x{:x}", &alpha_path, addr); @@ -70,7 +73,12 @@ impl Uprobe { .map_err(|_| format_err!("Failed to attach Uprobe to binary: {}", binary_path)) } - pub fn attach_uretprobe(binary_path: &str, symbol: &str, code: File, pid: pid_t) -> Result { + pub fn attach_uretprobe( + binary_path: &str, + symbol: &str, + code: File, + pid: pid_t, + ) -> Result { let (path, addr) = symbol::resolve_symbol_path(binary_path, symbol, 0x0, pid)?; let alpha_path = make_alphanumeric(&path); let ev_name = format!("r_{}_0x{:x}", &alpha_path, addr); diff --git a/src/cpuonline.rs b/src/cpuonline.rs index e57b1f7..6324cad 100644 --- a/src/cpuonline.rs +++ b/src/cpuonline.rs @@ -1,7 +1,7 @@ -use std::fs::File; -use std::str::FromStr; -use std::io::Read; use failure::Error; +use std::fs::File; +use std::io::Read; +use std::str::FromStr; const CPUONLINE: &'static str = "/sys/devices/system/cpu/online"; @@ -48,51 +48,51 @@ mod tests { lazy_static! { static ref TEST: Vec> = vec![ - TestData { - data: "", - expected: Vec::new(), - valid: false, - }, - TestData { - data: "0-3\n", - expected: vec!{0, 1, 2, 3}, - valid: true, - }, - TestData { - data: " 0-2,5", - expected: vec!{0, 1, 2, 5}, - valid: true, - }, - TestData { - data: "0,2,4-5,7-9", - expected: vec!{0, 2, 4, 5, 7, 8, 9}, - valid: true, - }, - TestData { - data: "0,2", - expected: vec!{0, 2}, - valid: true, - }, - TestData { - data: "0", - expected: vec!{0}, - valid: true, - }, - TestData { - data: "-2,5", - expected: Vec::new(), - valid: false, - }, - TestData { - data: "2-@,5", - expected: Vec::new(), - valid: false, - }, - TestData { - data: "-", - expected: Vec::new(), - valid: false, - }, + TestData { + data: "", + expected: Vec::new(), + valid: false, + }, + TestData { + data: "0-3\n", + expected: vec!{0, 1, 2, 3}, + valid: true, + }, + TestData { + data: " 0-2,5", + expected: vec!{0, 1, 2, 5}, + valid: true, + }, + TestData { + data: "0,2,4-5,7-9", + expected: vec!{0, 2, 4, 5, 7, 8, 9}, + valid: true, + }, + TestData { + data: "0,2", + expected: vec!{0, 2}, + valid: true, + }, + TestData { + data: "0", + expected: vec!{0}, + valid: true, + }, + TestData { + data: "-2,5", + expected: Vec::new(), + valid: false, + }, + TestData { + data: "2-@,5", + expected: Vec::new(), + valid: false, + }, + TestData { + data: "-", + expected: Vec::new(), + valid: false, + }, ]; } #[test] diff --git a/src/lib.rs b/src/lib.rs index b086284..2c24973 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,16 +8,17 @@ //! * see pub mod core; -pub mod symbol; +mod cpuonline; pub mod perf; +pub mod symbol; pub mod table; mod types; -mod cpuonline; #[macro_use] extern crate failure; -extern crate libc; extern crate bcc_sys; extern crate byteorder; -#[cfg(test)] #[macro_use] +extern crate libc; +#[cfg(test)] +#[macro_use] extern crate lazy_static; diff --git a/src/perf.rs b/src/perf.rs index 1dfaeb6..65669f2 100644 --- a/src/perf.rs +++ b/src/perf.rs @@ -1,15 +1,15 @@ extern crate libc; +use bcc_sys::bccapi::*; +use byteorder::{NativeEndian, WriteBytesExt}; +use cpuonline; use failure::Error; use failure::ResultExt; -use byteorder::{NativeEndian, WriteBytesExt}; -use bcc_sys::bccapi::*; -use cpuonline; use std; use std::io::Cursor; -use types::*; use table::Table; +use types::*; struct PerfCallback { raw_cb: Box, @@ -21,9 +21,7 @@ unsafe extern "C" fn raw_callback(pc: MutPointer, ptr: MutPointer, size: i32) { let slice = std::slice::from_raw_parts(ptr as *const u8, size as usize); // prevent unwinding into C code // no custom panic hook set, panic will be printed as is - let _ = std::panic::catch_unwind(|| { - (*(*(pc as *mut PerfCallback)).raw_cb)(slice) - }); + let _ = std::panic::catch_unwind(|| (*(*(pc as *mut PerfCallback)).raw_cb)(slice)); } // need this to be represented in memory as just a pointer!! @@ -81,9 +79,9 @@ where callbacks.push(callback); cur.write_u32::(perf_fd)?; - table.set(&mut key, &mut cur.get_mut()).context( - "Unable to initialize perf map", - )?; + table + .set(&mut key, &mut cur.get_mut()) + .context("Unable to initialize perf map")?; let r = bpf_get_next_key( fd, key.as_mut_ptr() as MutPointer, @@ -118,7 +116,7 @@ fn open_perf_buffer( cpu: usize, raw_cb: Box, ) -> Result<(PerfReader, Box), Error> { - let mut callback = Box::new(PerfCallback { raw_cb: raw_cb }); + let mut callback = Box::new(PerfCallback { raw_cb }); let reader = unsafe { bpf_open_perf_buffer( Some(raw_callback), @@ -132,5 +130,10 @@ fn open_perf_buffer( if reader.is_null() { return Err(format_err!("failed to open perf buffer")); } - Ok((PerfReader { ptr: reader as *mut perf_reader }, callback)) + Ok(( + PerfReader { + ptr: reader as *mut perf_reader, + }, + callback, + )) } diff --git a/src/symbol.rs b/src/symbol.rs index 067370a..967dca5 100644 --- a/src/symbol.rs +++ b/src/symbol.rs @@ -1,10 +1,10 @@ -use failure::Error; use bcc_sys::bccapi::*; +use failure::Error; +use std::ffi::CStr; +use std::ffi::CString; use std::mem; use std::ptr; -use std::ffi::CString; -use std::ffi::CStr; use libc::{c_void, free}; @@ -51,11 +51,13 @@ pub fn resolve_symname( )) } else { let module = unsafe { - CStr::from_ptr(symbol.module as *mut i8).to_str()?.to_string() + CStr::from_ptr(symbol.module as *mut i8) + .to_str()? + .to_string() }; // symbol.module was allocated somewhere inside `bcc_resolve_symname` // so we need to free it manually - unsafe {free(symbol.module as *mut c_void)}; + unsafe { free(symbol.module as *mut c_void) }; Ok((module, symbol.offset)) } } diff --git a/src/table.rs b/src/table.rs index 0896b1b..6d4bc21 100644 --- a/src/table.rs +++ b/src/table.rs @@ -1,12 +1,11 @@ -use libc::{size_t, c_int}; -use failure::Error; use bcc_sys::bccapi::*; +use failure::Error; +use libc::{c_int, size_t}; use types::MutPointer; -use std::ffi::CStr; use std; - +use std::ffi::CStr; #[derive(Clone, Debug)] pub struct Table { @@ -102,10 +101,10 @@ impl IntoIterator for Table { type Item = Entry; type IntoIter = EntryIter; fn into_iter(self) -> Self::IntoIter { - EntryIter{ + EntryIter { current: None, table: self, - fd: None + fd: None, } } } @@ -124,7 +123,6 @@ pub struct Entry { pub value: Vec, } - pub struct EntryIter { current: Option, fd: Option, @@ -134,7 +132,10 @@ pub struct EntryIter { impl EntryIter { pub fn entry_ptrs(&mut self) -> Option<(*mut std::os::raw::c_void, *mut std::os::raw::c_void)> { match self.current.as_mut() { - Some(&mut Entry{ref mut key, ref mut value}) => Some(( + Some(&mut Entry { + ref mut key, + ref mut value, + }) => Some(( key.as_mut_ptr() as *mut u8 as *mut std::os::raw::c_void, value.as_mut_ptr() as *mut u8 as *mut std::os::raw::c_void, )), @@ -146,7 +147,10 @@ impl EntryIter { self.fd = Some(self.table.fd()); let key_size = self.table.key_size(); let leaf_size = self.table.leaf_size(); - let entry = Entry{key: vec![0; key_size], value: vec![0; leaf_size]}; + let entry = Entry { + key: vec![0; key_size], + value: vec![0; leaf_size], + }; self.current = Some(entry); unsafe { let (k, _) = self.entry_ptrs().unwrap();