Provider

Struct Provider 

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

A connection for writing compile-time-defined Linux tracepoints.

§Overview

  1. Use define_provider!(MY_PROVIDER, ...) to define a static provider symbol.
  2. Call unsafe { MY_PROVIDER.register() }; during component initialization to open the connection. (register() is unsafe because all providers registered in a shared object must be unregistered before the shared object unloads.)
  3. Use write_event!(MY_PROVIDER, ...) to write events.
  4. Call MY_PROVIDER.unregister() during component cleanup to close the connection.

Implementations§

Source§

impl<'a> Provider<'a>

Source

pub fn name(&self) -> &str

Returns this provider’s name.

Source

pub fn options(&self) -> &str

Returns this provider’s options, e.g. “” or “Gmygroup”.

Source

pub fn unregister(&self) -> u32

Unregisters all registered tracepoints in the provider.

Returns 0 for success or an errno if any tracepoints failed to unregister. The return value is for diagnostic purposes only and should generally be ignored in retail builds.

Unregistering an unregistered tracepoint is a safe no-op, e.g. it is safe to call unregister() even if a provider has not been registered yet.

Source

pub unsafe fn register(&self) -> u32

Register all tracepoints in the provider.

Returns 0 for success or an errno if any tracepoints failed to register. The return value is for diagnostic purposes only and should generally be ignored in retail builds.

Note: All providers that are registered need to be unregistered. The call to unregister() is required even if the call to register() returns an error.

§Preconditions
  • Provider’s tracepoints must not already be registered. Verified at runtime, failure = panic.
  • For a given provider object, a call on one thread to the provider’s register method must not occur at the same time as a call to the same provider’s register or unregister method on any other thread. Verified at runtime, failure = panic.
§Safety

In code that might unload before the process exits (e.g. in a shared object), every call to provider.register() must be matched with a call to provider.unregister(). If a provider variable is registered and then unloaded from memory without being unregistered, process memory may subsequently become corrupted and the process may malfunction or crash.

This issue occurs because each of the tracepoints managed by the provider is a static varible. The provider.register() method asks the Linux kernel to automatically update the enabled/disabled status of these variables, and the provider.unregister() method asks the Linux kernel to stop these updates. If these variables are unloaded without being unregistered and then something else gets loaded into the same region of memory, that memory will be corrupted if the kernel tries to update the enabled/disabled status of a tracepoint.

This rule applies even if provider.register() returns an error. provider.register() returns an error if any of its tracepoints failed to register, but it may have successfully registered one or more tracepoints. Those tracepoints need to be unregistered before the provider unloads.

The provider cannot unregister itself when it drops because the provider is a static object and Rust does not drop static objects.

Trait Implementations§

Source§

impl Debug for Provider<'_>

Source§

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

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

impl Drop for Provider<'_>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Sync for Provider<'_>

Auto Trait Implementations§

§

impl<'a> !Freeze for Provider<'a>

§

impl<'a> RefUnwindSafe for Provider<'a>

§

impl<'a> !Send for Provider<'a>

§

impl<'a> Unpin for Provider<'a>

§

impl<'a> UnwindSafe for Provider<'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> 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, 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.