Skip to content

Commit

Permalink
adds signal handler to examples (#43)
Browse files Browse the repository at this point in the history
Adds signal handlers for SIGINT and SIGTEM to the examples so that
the `Drop` implementations are invoked following ctrl-c.
  • Loading branch information
brayniac committed Jun 24, 2019
1 parent 9202efb commit 410f568
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 14 deletions.
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ homepage = "https://github.com/rust-bpf/rust-bcc"
edition = '2018'

[dependencies]
libc = "0.2.55"
bcc-sys = "0.9.2"
failure = "0.1.5"
byteorder = "1.3.1"
failure = "0.1.5"
libc = "0.2.55"

[dev-dependencies]
lazy_static = "1.3.0"
clap = "2.33.0"
ctrlc = "3.1.3"
lazy_static = "1.3.0"

[features]
static = ["bcc-sys/static"]
Expand Down
20 changes: 15 additions & 5 deletions examples/opensnoop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ extern crate byteorder;
extern crate failure;
extern crate libc;

use std::ptr;

use bcc::core::BPF;
use bcc::perf::init_perf_map;
use failure::Error;

use core::sync::atomic::{AtomicBool, Ordering};
use std::ptr;
use std::sync::Arc;

/*
* Basic Rust clone of `opensnoop`, from the iovisor tools.
* https://github.com/iovisor/bcc/blob/master/tools/opensnoop.py
Expand All @@ -31,7 +33,7 @@ struct data_t {
fname: [u8; 255], // NAME_MAX
}

fn do_main() -> Result<(), Error> {
fn do_main(runnable: Arc<AtomicBool>) -> Result<(), Error> {
let code = include_str!("opensnoop.c");
// compile the above BPF code!
let mut module = BPF::new(code)?;
Expand All @@ -47,9 +49,10 @@ fn do_main() -> Result<(), Error> {
// print a header
println!("{:-7} {:-16} {}", "PID", "COMM", "FILENAME");
// this `.poll()` loop is what makes our callback get called
loop {
while runnable.load(Ordering::SeqCst) {
perf_map.poll(200);
}
Ok(())
}

fn perf_data_callback() -> Box<FnMut(&[u8]) + Send> {
Expand Down Expand Up @@ -77,7 +80,14 @@ fn get_string(x: &[u8]) -> String {
}

fn main() {
match do_main() {
let runnable = Arc::new(AtomicBool::new(true));
let r = runnable.clone();
ctrlc::set_handler(move || {
r.store(false, Ordering::SeqCst);
})
.expect("Failed to set handler for SIGINT / SIGTERM");

match do_main(runnable) {
Err(x) => {
eprintln!("Error: {}", x);
eprintln!("{}", x.backtrace());
Expand Down
16 changes: 13 additions & 3 deletions examples/softirqs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use bcc::core::BPF;
use clap::{App, Arg};
use failure::Error;

use core::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::{fmt, mem, ptr, thread, time};

// A simple tool for reporting on time spent in softirq handlers
Expand Down Expand Up @@ -71,7 +73,7 @@ impl fmt::Display for SoftIRQ {
}
}

fn do_main() -> Result<(), Error> {
fn do_main(runnable: Arc<AtomicBool>) -> Result<(), Error> {
let matches = App::new("softirqs")
.about("Reports time spent in IRQ Handlers")
.arg(
Expand Down Expand Up @@ -112,7 +114,7 @@ fn do_main() -> Result<(), Error> {
let table = module.table("dist");
let mut window = 0;

loop {
while runnable.load(Ordering::SeqCst) {
thread::sleep(time::Duration::new(interval as u64, 0));
println!("======");
for entry in table.iter() {
Expand All @@ -138,14 +140,22 @@ fn do_main() -> Result<(), Error> {
}
}
}
Ok(())
}

fn parse_struct(x: &[u8]) -> irq_key_t {
unsafe { ptr::read(x.as_ptr() as *const irq_key_t) }
}

fn main() {
match do_main() {
let runnable = Arc::new(AtomicBool::new(true));
let r = runnable.clone();
ctrlc::set_handler(move || {
r.store(false, Ordering::SeqCst);
})
.expect("Failed to set handler for SIGINT / SIGTERM");

match do_main(runnable) {
Err(x) => {
eprintln!("Error: {}", x);
eprintln!("{}", x.backtrace());
Expand Down
17 changes: 14 additions & 3 deletions examples/strlen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ extern crate libc;
use bcc::core::BPF;
use byteorder::{NativeEndian, ReadBytesExt};
use failure::Error;

use core::sync::atomic::{AtomicBool, Ordering};
use std::io::Cursor;
use std::sync::Arc;

fn do_main() -> Result<(), Error> {
fn do_main(runnable: Arc<AtomicBool>) -> Result<(), Error> {
let code = "
#include <uapi/linux/ptrace.h>
Expand Down Expand Up @@ -39,7 +42,7 @@ int count(struct pt_regs *ctx) {
-1, /* all PIDs */
)?;
let table = module.table("counts");
loop {
while runnable.load(Ordering::SeqCst) {
std::thread::sleep(std::time::Duration::from_millis(1000));
for e in &table {
// key and value are each a Vec<u8> so we need to transform them into a string and
Expand All @@ -51,6 +54,7 @@ int count(struct pt_regs *ctx) {
}
}
}
Ok(())
}

fn get_string(x: &[u8]) -> String {
Expand All @@ -61,7 +65,14 @@ fn get_string(x: &[u8]) -> String {
}

fn main() {
match do_main() {
let runnable = Arc::new(AtomicBool::new(true));
let r = runnable.clone();
ctrlc::set_handler(move || {
r.store(false, Ordering::SeqCst);
})
.expect("Failed to set handler for SIGINT / SIGTERM");

match do_main(runnable) {
Err(x) => {
eprintln!("Error: {}", x);
eprintln!("{}", x.backtrace());
Expand Down

0 comments on commit 410f568

Please sign in to comment.