pub struct Provider<'a> { /* private fields */ }Expand description
A connection for writing compile-time-defined Linux tracepoints.
§Overview
- Use
define_provider!(MY_PROVIDER, ...)to define a static provider symbol. - 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.) - Use
write_event!(MY_PROVIDER, ...)to write events. - Call
MY_PROVIDER.unregister()during component cleanup to close the connection.
Implementations§
Source§impl<'a> Provider<'a>
impl<'a> Provider<'a>
Sourcepub fn unregister(&self) -> u32
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.
Sourcepub unsafe fn register(&self) -> u32
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
registermethod must not occur at the same time as a call to the same provider’sregisterorunregistermethod 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.