Struct Opts

Source
pub struct Opts {
Show 17 fields pub exclude: Priv, pub only_group: bool, pub pin_on_pmu: bool, pub inherit: Option<Inherit>, pub on_execve: Option<OnExecve>, pub stat_format: StatFormat, pub enable: bool, pub sample_on: SampleOn, pub sample_skid: SampleSkid, pub sample_format: SampleFormat, pub extra_record: ExtraRecord, pub record_id_all: bool, pub record_id_format: RecordIdFormat, pub wake_up: WakeUp, pub sigtrap_on_sample: Option<SigData>, pub timer: Option<Clock>, pub pause_aux: bool,
}
Expand description

Event options.

Fields§

§exclude: Priv

Exclude events with privilege levels.

For example, if we set Priv::user to true here, events that happen in user space will not be counted.

§only_group: bool

This group should be the only group on the CPU.

This means that when this counter group is on a CPU, it should be the only group using the CPU counters.

This allows monitoring programs with PMU that need to run alone so that they do not disrupt other hardware counters.

§pin_on_pmu: bool

The counter should always be on the CPU if at all possible.

If a pinned counter cannot be put onto the CPU (e.g., because there are not enough hardware counters or because of a conflict with some other event), then the counter goes into an “error” state, where stat return EOF.

§inherit: Option<Inherit>

Controls the inherit behavior.

This is incompatible with monitoring all CPUs in sampling mode.

§on_execve: Option<OnExecve>

Counter behavior when calling execve.

§stat_format: StatFormat

Controls the format of Stat.

§enable: bool

Enable counter immediately after the counter is created.

§sample_on: SampleOn

Controls when to generate a sample record.

§sample_skid: SampleSkid

Controls the amount of sample skid.

§sample_format: SampleFormat

Controls the format of sample record.

§extra_record: ExtraRecord

Generate extra record types.

§record_id_all: bool

Contains RecordId in all non-sample record types.

§record_id_format: RecordIdFormat

Controls the format of RecordId.

§wake_up: WakeUp

Wake up options for asynchronous iterators.

§sigtrap_on_sample: Option<SigData>

Enables synchronous signal delivery of SIGTRAP to the target process on event overflow.

Must be used together with OnExecve::Remove.

§Examples

use std::mem::{transmute, MaybeUninit};
use std::ptr::null_mut;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::channel;
use std::thread;

use perf_event_open::config::{Cpu, OnExecve, Opts, Proc, SampleOn, SigData};
use perf_event_open::count::Counter;
use perf_event_open::event::sw::Software;

const SIG_DATA: u64 = 123456; // Data sent on SIGTRAP.

let (pid_tx, pid_rx) = channel();
let handle = thread::spawn(move || {
    unsafe {
        let child = libc::fork();
        if child > 0 {
            pid_tx.send(child).unwrap();
            let mut code = 0;
            libc::waitpid(child, &mut code as _, 0);
            assert_eq!(code, 0);
            return;
        }
    }

    unsafe { libc::prctl(libc::PR_SET_PDEATHSIG, libc::SIGKILL) };

    let result = std::panic::catch_unwind(|| {

        static SPIN: AtomicBool = AtomicBool::new(true);

        fn handler(num: i32, info: *const libc::siginfo_t) {
            assert_eq!(num, libc::SIGTRAP);
            let sig_data = unsafe { transmute::<libc::siginfo_t, [u64; 16]>(*info) }[3];
            assert_eq!(sig_data, SIG_DATA);
            SPIN.store(false, Ordering::Relaxed);
        }

        let act = libc::sigaction {
            sa_sigaction: handler as _,
            sa_mask: unsafe { MaybeUninit::zeroed().assume_init() },
            sa_flags: libc::SA_SIGINFO,
            sa_restorer: None,
        };
        unsafe { libc::sigaction(libc::SIGTRAP, &act as _, null_mut()) };

        while SPIN.load(Ordering::Relaxed) {
            // Busy wait to ensure the task clock increments.
            std::hint::spin_loop();
        }
    });
    if result.is_err() {
        unsafe { libc::abort() };
    }

    unsafe { libc::exit(0) };
});

let event = Software::TaskClock;
let target = (Proc(pid_rx.recv().unwrap() as _), Cpu::ALL);

let mut opts = Opts::default();
opts.sample_on = SampleOn::Freq(1000);
opts.sigtrap_on_sample = Some(SigData(SIG_DATA)); // Send SIGTRAP to the target when sampling.
opts.on_execve = Some(OnExecve::Remove); // Must be used together with `sigtrap_on_sample`.

let counter = Counter::new(event, target, opts).unwrap();
counter.sampler(5).unwrap();
counter.enable().unwrap();

handle.join().unwrap();

NOTE: Child process monitoring itself seems buggy, panic in the signal handler may get the child process stuck.

Since linux-5.13: https://github.com/torvalds/linux/commit/97ba62b278674293762c3d91f724f1bb922f04e0

§timer: Option<Clock>

Selects which internal Linux timer to use for timestamps.

This can make it easier to correlate perf sample times with timestamps generated by other tools.

Since linux-4.1: https://github.com/torvalds/linux/commit/34f439278cef7b1177f8ce24f9fc81dfc6221d3b

§pause_aux: bool

Trait Implementations§

Source§

impl Clone for Opts

Source§

fn clone(&self) -> Opts

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Opts

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Opts

Source§

fn default() -> Opts

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Opts

§

impl RefUnwindSafe for Opts

§

impl Send for Opts

§

impl Sync for Opts

§

impl Unpin for Opts

§

impl UnwindSafe for Opts

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.