Struct Builder

Source
pub struct Builder<'a> { /* private fields */ }
Expand description

A builder for Counters.

There are dozens of parameters that influence a Counter’s behavior. Builder lets you construct a Counter by specifying only those parameters for which you don’t want the default value.

A freshly built Counter is disabled. To begin counting events, you must call enable on the Counter or the Group to which it belongs.

For example, if you want a Counter for instructions retired by the current process, those are Builder’s defaults, so you need only write:

let mut insns = Builder::new(Hardware::INSTRUCTIONS).build()?;

If you would like to gather individual counters into a Group you can use the Group::add method. A Group allows you to enable or disable all the grouped counters atomically.

let mut group = Group::new()?;
let cycles = group.add(&Builder::new(Hardware::CPU_CYCLES))?;
let insns = group.add(&Builder::new(Hardware::INSTRUCTIONS))?;

Other methods let you select:

  • specific processes or cgroups to observe
  • specific CPU cores to observe

Builder supports only a fraction of the many knobs and dials Linux offers, but hopefully it will acquire methods to support more of them as time goes on.

Internally, a Builder is just a wrapper around the kernel’s struct perf_event_attr type.

Implementations§

Source§

impl<'a> Builder<'a>

Source

pub fn new<E: Event>(event: E) -> Self

Return a new Builder, with all parameters set to their defaults.

Return a new Builder for the specified event.

Source

pub fn event<E: Event>(&mut self, event: E) -> &mut Self

Override the event configured for this builder.

This can be used reuse other configuration for the builder (which processes/CPUs to observe, sampling fields, read format, etc.) while building counters for different events.

Before configuring the perf_event_attr struct using the event all config fields within it will be set to 0. Specifically: type_, config, config1, config2, and config3. This ensures that most events do not have to worry about resetting state that other events may have set.

Source

pub fn build(&self) -> Result<Counter>

Construct a Counter according to the specifications made on this Builder.

If you want to add this counter to a group use build_with_group instead.

By default, a newly built Counter is disabled. To begin counting events, you must call enable on the Counter or the Group to which it belongs. Alternatively, certain options (e.g. enable_on_exec) may be used to automatically enable the Counter once certain events occur.

§Errors
  • The perf_event_open syscall has a large number of different errors it can return. See the man page for details. Unfortunately, the errors returned by the kernel are not always helpful.
  • This method translates E2BIG errors (which means the kernel did not support some options) into a custom std::io::Error with kind ErrorKind::Unsupported and an internal error of UnsupportedOptionsError. This allows you to access the size of the perf_event_attr struct that the kernel was expecting.
§Panics

This method panics if attrs.size has been set to a value larger than the size of the perf_event_attr struct.

Source

pub fn build_with_group(&self, group: impl AsMut<Counter>) -> Result<Counter>

Construct a Counter as part of a group.

The group passed in must be the leader of the group you to add the resulting Counter to.

§Notes
  • The group leader does not have to be a Group (although it can be), any Counter will work just fine as a group leader provided it is not already within a group itself.
  • Similarly with enabling, disabling, or resetting all counters in the group. Any counter in the group can do those via enable_group, disable_group, and reset_group.
  • The same applies for reading group values. Any counter that has ReadFormat::GROUP set in read_formatcan read the counter values for the entire group using read_group.

Note, however, that Group is likely to be more convenient if you don’t want to set ReadFormat::GROUP on any of the counters within the group.

§Errors
  • The perf_event_open syscall has a large number of different errors it can return. See the man page for details. Unfortunately, the errors returned by the kernel are not always helpful.
  • This method translates E2BIG errors (which means the kernel did not support some options) into a custom std::io::Error with kind ErrorKind::Unsupported and an internal error of UnsupportedOptionsError. This allows you to access the size of the perf_event_attr struct that the kernel was expecting.
§Panics

This method panics if attrs.size has been set to a value larger than the size of the perf_event_attr struct.

Source

pub fn build_group(&self) -> Result<Group>

Build a Group according to the specifications made on this Builder.

Note that you will need to have set ReadFormat::GROUP within read_format to or this method will error.

§Notes
  • A Group is just a wrapper around a Counter whose methods use the corresponding *_group methods on Counter.
  • The GroupData returned from Group::read doesn’t include the group itself when being iterated over. You will likely want to use the Software::DUMMY event when constructing a group.
§Errors
§Panics

This method panics if attrs.size has been set to a value larger than the size of the perf_event_attr struct.

Source§

impl<'a> Builder<'a>

Source

pub fn attrs(&self) -> &perf_event_attr

Directly access the perf_event_attr within this builder.

Source

pub fn attrs_mut(&mut self) -> &mut perf_event_attr

Directly access the perf_event_attr within this builder.

Source

pub fn observe_self(&mut self) -> &mut Self

Observe the calling process. (This is the default.)

Source

pub fn observe_pid(&mut self, pid: pid_t) -> &mut Self

Observe the process with the given process id. This requires CAP_SYS_PTRACE capabilities.

Source

pub fn any_pid(&mut self) -> &mut Self

Observe all processes.

Linux does not support observing all processes on all CPUs without restriction, so combining any_pid with any_cpu will cause the final build to return an error. This must be used together with one_cpu, to select a specific CPU to observe.

This requires CAP_PERFMON or CAP_SYS_ADMIN capabilities, or a /proc/sys/kernel/perf_event_paranoid value of less than 1.

Source

pub fn observe_cgroup(&mut self, cgroup: &'a File) -> &mut Self

Observe code running in the given cgroup (container). The cgroup argument should be a File referring to the cgroup’s directory in the cgroupfs filesystem.

Source

pub fn one_cpu(&mut self, cpu: usize) -> &mut Self

Observe only code running on the given CPU core.

Source

pub fn any_cpu(&mut self) -> &mut Self

Observe code running on any CPU core. (This is the default.)

Linux does not support observing all processes on all CPUs without restriction, so combining any_cpu with any_pid will cause build to return an error. This must be used with observe_self (the default), observe_pid, or observe_cgroup.

Source

pub fn sample(&mut self, sample: SampleFlag) -> &mut Self

Indicate additional values to include in the generated sample events.

Note that this method is additive and does not remove previously added sample types. See the documentation of SampleFlag or the manpage for what’s available to be collected.

§Example

Here we build a sampler that grabs the instruction pointer, process ID, thread ID, and timestamp whenever the underlying event triggers a sampling.

let mut sampler = Builder::new(Hardware::INSTRUCTIONS)
    .sample(SampleFlag::IP)
    .sample(SampleFlag::TID)
    .sample(SampleFlag::TIME)
    .build()?
    .sampled(8192)?;
Source

pub fn read_format(&mut self, read_format: ReadFormat) -> &mut Self

Set the fields to include when reading from the counter.

Note that this method is not additive, unlike sample.

The implementation of this library will silently mask out certain flags if they would be invalid. For example, we will not allow you to set ReadFormat::GROUP when building a single counter.

Source§

impl<'a> Builder<'a>

Source

pub fn enabled(&mut self, enabled: bool) -> &mut Self

Whether this counter should start off enabled.

When this is set, the counter will immediately start being recorded as soon as it is created.

By default, this is false.

Source

pub fn inherit(&mut self, inherit: bool) -> &mut Self

Set whether this counter is inherited by new threads.

When this flag is set, this counter observes activity in new threads created by any thread already being observed.

By default, the flag is unset: counters are not inherited, and observe only the threads specified when they are created.

This flag cannot be set if the counter belongs to a Group. Doing so will result in an error when the counter is built. This is a kernel limitation.

Source

pub fn pinned(&mut self, pinned: bool) -> &mut Self

Set whether the counter is pinned to the PMU.

If this flag is set, the kernel will attempt to keep the counter on always on the CPU if at all possible. If it fails to do so, the counter will enter an error state where reading it will always return EOF. For this crate, that would result in Counter::read returning an error with kind ErrorKind::UnexpectedEof.

This option only applies to hardware counters and group leaders. At this time this crate provides no way to configure group leaders so this option will only work when the resulting counter is not in a group.

This is false by default.

Source

pub fn exclusive(&mut self, exclusive: bool) -> &mut Self

Controls whether the counter or group can be scheduled onto a CPU alongside other counters or groups.

This is false by default.

Source

pub fn exclude_user(&mut self, exclude_user: bool) -> &mut Self

Whether we should exclude events that occur in user space.

This is false by default.

Source

pub fn exclude_kernel(&mut self, exclude_kernel: bool) -> &mut Self

Whether we should exclude events that occur in kernel space.

Note that setting this to false may result in permission errors if the current perf_event_paranoid value is greater than 1.

This is true by default.

Source

pub fn include_kernel(&mut self) -> &mut Self

Include kernel code.

See exclude_kernel.

Source

pub fn exclude_hv(&mut self, exclude_hv: bool) -> &mut Self

Whether we should exclude events that happen in the hypervisor.

This is not supported on all architectures as it required built-in support within the CPU itself.

Note that setting this to false may result in permission errors if the current perf_event_paranoid value is greater than 1.

This is true by default

Source

pub fn include_hv(&mut self) -> &mut Self

Include hypervisor code.

See exclude_hv.

Source

pub fn exclude_idle(&mut self, exclude_idle: bool) -> &mut Self

Whether to exclude events that occur when running the idle task.

Note that this only has an effect for software events.

Source

pub fn mmap(&mut self, mmap: bool) -> &mut Self

Enable the generation of MMAP records for executable memory maps.

MMAP records are emitted when the process/thread that is being observed creates a new executable memory mapping.

Source

pub fn comm(&mut self, comm: bool) -> &mut Self

Enable the tracking of process command name changes.

This can happen when a process calls execve(2), prctl(PR_SET_NAME), or writes to /proc/self/comm.

If you also set the comm_exec flag, then the kernel will indicate which of these process name changes were due to calls to execve(2).

Source

pub fn sample_period(&mut self, period: u64) -> &mut Self

Set the period at which the kernel will generate sample events.

As an example, if the event is Hardware::INSTRUCTIONS and period is 100_000 then every 100_000 instructions the kernel will generate an event.

Note that the actual precision at which the sample corresponds to the instant and location at which Nth event occurred is controlled by the precise_ip option.

This setting is mutually exclusive with sample_frequency.

Source

pub fn sample_frequency(&mut self, frequency: u64) -> &mut Self

Set the frequency at which the kernel will generate sample events (in Hz).

Note that this is not guaranteed to be exact. The kernel will adjust the period to attempt to keep the desired frequency but the rate at which events occur varies drastically then samples may not occur at the specified frequency.

The amount to which samples correspond to the instant and location at which an event occurred is controlled by the precise_ip option.

This setting is mutually exclusive with sample_period.

Source

pub fn inherit_stat(&mut self, inherit_stat: bool) -> &mut Self

Save event counts on context switch for inherited tasks.

This option is only meaningful if inherit is also enabled.

Source

pub fn enable_on_exec(&mut self, enable_on_exec: bool) -> &mut Self

Enable the counter automatically after a call to execve(2).

Source

pub fn task(&mut self, task: bool) -> &mut Self

If set, then the kernel will generate fork and exit records.

Source

pub fn wakeup_watermark(&mut self, watermark: usize) -> &mut Self

Set how many bytes will be written before the kernel sends an overflow notification.

This controls how much data will be emitted before Sampler::next_blocking will wake up once blocked.

This setting is mutually exclusive with wakeup_events.

Source

pub fn wakeup_events(&mut self, events: usize) -> &mut Self

Set how many samples will be written before the kernel sends an overflow notification.

This controls how much data will be emitted before Sampler::next_blocking will wake up once blocked. Note that only sample records (PERF_RECORD_SAMPLE) count towards the event count.

Some caveats apply, see the manpage for the full documentation.

This method is mutually exclusive with wakeup_watermark.

Source

pub fn precise_ip(&mut self, skid: SampleSkid) -> &mut Self

Control how much skid is permitted when recording events.

Skid is the number of instructions that occur between an event occuring and a sample being gathered by the kernel. Less skid is better but there are hardware limitations around how small the skid can be.

Also see SampleSkid.

Source

pub fn mmap_data(&mut self, mmap_data: bool) -> &mut Self

Enable the generation of MMAP records for non-executable memory maps.

This is the data counterpart of mmap.

Source

pub fn sample_id_all(&mut self, sample_id_all: bool) -> &mut Self

If enabled, then a subset of the sample fields will additionally be included in most non-PERF_RECORD_SAMPLE samples.

See the manpage for the exact fields that are included and which records include the trailer.

Source

pub fn exclude_host(&mut self, exclude_host: bool) -> &mut Self

Only collect measurements for events occurring inside a VM instance.

This is only meaningful when profiling from outside the VM instance.

See the manpage for more documentation.

Source

pub fn exclude_guest(&mut self, exclude_guest: bool) -> &mut Self

Don’t collect measurements for events occurring inside a VM instance.

This is only meaningful when profiling from outside the VM instance.

See the manpage for more documentation.

Source

pub fn exclude_callchain_kernel(&mut self, exclude_kernel: bool) -> &mut Self

Do not include stack frames in the kernel when gathering callchains as a part of recording a sample.

Source

pub fn exclude_callchain_user(&mut self, exclude_user: bool) -> &mut Self

Do not include stack frames from userspace when gathering a callchain as a part of recording a sample.

Source

pub fn mmap2(&mut self, mmap2: bool) -> &mut Self

Generate an extended executable mmap record.

This record has enough info to uniquely identify which instance of a shared map it corresponds to. Note that you also need to set the mmap option for this to work.

Source

pub fn comm_exec(&mut self, comm_exec: bool) -> &mut Self

Check whether the kernel will annotate COMM records with the COMM_EXEC bit when they occur due to an execve(2) call.

This option doesn’t actually change the behaviour of the kernel. Instead, it is useful for feature detection.

Source

pub fn clockid(&mut self, clockid: impl Into<Option<Clock>>) -> &mut Self

Select which linux clock to use for timestamps.

If clockid is None then the kernel will use an internal timer. This timer may not be any of the options for clockid.

See Clock and the clock_getttime(2) manpage for documentation on what the different clock values mean.

Source

pub fn context_switch(&mut self, context_switch: bool) -> &mut Self

Generate SWITCH records when a context switch occurs.

Also enables the generation of SWITCH_CPU_WIDE records if profiling in cpu-wide mode.

Source

pub fn namespaces(&mut self, namespaces: bool) -> &mut Self

Generate NAMESPACES records when a task enters a new namespace.

Source

pub fn ksymbol(&mut self, ksymbol: bool) -> &mut Self

Generate KSYMBOL records when kernel symbols are registered or unregistered.

Source

pub fn bpf_event(&mut self, bpf_event: bool) -> &mut Self

Generate BPF_EVENT records when eBPF programs are loaded or unloaded.

Source

pub fn aux_output(&mut self, aux_output: bool) -> &mut Self

Output data for non-aux events to the aux buffer, if supported by the hardware.

Source

pub fn cgroup(&mut self, cgroup: bool) -> &mut Self

Generate CGROUP records when a new cgroup is created.

Source

pub fn text_poke(&mut self, text_poke: bool) -> &mut Self

Generate TEXT_POKE records when the kernel text (i.e. code) is modified.

Source

pub fn build_id(&mut self, build_id: bool) -> &mut Self

Whether to include the build id in MMAP2 events.

Source

pub fn inherit_thread(&mut self, inherit_thread: bool) -> &mut Self

Only inherit the counter to new threads in the same process, not to other processes.

Source

pub fn remove_on_exec(&mut self, remove_on_exec: bool) -> &mut Self

Disable this counter when it successfully calls execve(2).

Source

pub fn sigtrap(&mut self, sigtrap: bool) -> &mut Self

Synchronously send SIGTRAP to the process that created the counter when the sampled events overflow.

Source

pub fn sig_data(&mut self, sig_data: u64) -> &mut Self

Copy data to the user’s signal handler (via si_perf in siginfo_t).

This can be used to figure out which event caused the signal to be sent. It does nothing unless sigtrap is also set to true.

Source

pub fn branch_sample_type(&mut self, flags: SampleBranchFlag) -> &mut Self

Specify which branches to include in the branch record.

This does nothing unless SampleFlag::BRANCH_STACK is specified in the sample flags.

Source

pub fn sample_regs_user(&mut self, regs: u64) -> &mut Self

Specify which CPU registers to dump in a sample.

This does nothing unless SampleFlag::REGS_USER is part of the specified sample flags.

The actual layout of the register mask is architecture specific. You will generally want the PERF_REG_<arch> constants in perf_event_open_sys. (e.g. PERF_REG_X86_SP).

Source

pub fn sample_regs_intr(&mut self, regs: u64) -> &mut Self

Specify which CPU registers to dump in a sample.

This does nothing unless SampleFlag::REGS_INTR is part of the specified sample flags.

The actual layout of the register mask is architecture specific. You will generally want the PERF_REG_<arch> constants in perf_event_open_sys. (e.g. PERF_REG_X86_SP).

Source

pub fn sample_stack_user(&mut self, stack: u32) -> &mut Self

Specify the maximum size of the user stack to dump.

This option does nothing unless SampleFlag::STACK_USER is set in the sample flags.

Note that the size of the array allocated within the sample record will always be exactly this size, even if the actual collected stack data is much smaller. The allocated sample buffer (when constructing a Sampler) will need to be large enough to accommodate the chosen stack size or else samples will be lost.

Source

pub fn sample_max_stack(&mut self, max_stack: u16) -> &mut Self

Specify the maximum number of stack frames to include when unwinding the user stack.

This does nothing unless SampleFlag::CALLCHAIN is set in the sample flags.

Note that the kernel has a user configurable limit specified at /proc/sys/kernel/perf_event_max_stack. Setting sample_max_stack to larger than that limit will result in an EOVERFLOW error when building the counter.

Source

pub fn aux_watermark(&mut self, watermark: u32) -> &mut Self

Specify how much data is required before the kernel emits an AUX record.

Source

pub fn aux_sample_size(&mut self, sample_size: u32) -> &mut Self

Specify the desired size of AUX data.

This does nothing unless SampleFlag::AUX is set in the sample flags. Note that the emitted aux data can be smaller than the requested size.

Trait Implementations§

Source§

impl<'a> Clone for Builder<'a>

Source§

fn clone(&self) -> Builder<'a>

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 Builder<'_>

Source§

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

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

impl RefUnwindSafe for Builder<'_>

Source§

impl UnwindSafe for Builder<'_>

Auto Trait Implementations§

§

impl<'a> Freeze for Builder<'a>

§

impl<'a> Send for Builder<'a>

§

impl<'a> Sync for Builder<'a>

§

impl<'a> Unpin for Builder<'a>

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.
Source§

impl<T> EventData for T
where T: Send + Sync,