.github,aya,test: clean up interface and script per review comments

- .github: Ensure we only download the debug package that matches the kernel we
  downloaded.
- aya: Constrain the breakpoint interface to only valid combinations of
  options.
- test: Document what the test is actually doing for future readers who might
  be unfamiliar with modprobe_path.
reviewable/pr1365/r7
Friday Ortiz 3 weeks ago committed by GitHub
parent 38e3f7fce2
commit 61e0aef8b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -27,20 +27,22 @@ for VERSION in "${VERSIONS[@]}"; do
FILES+=("$match")
# The debug package contains the actual System.map. Debian has transitioned
# between -dbg and -dbgsym suffixes, so try both.
DEBUG_REGEX_BASE="linux-image-${VERSION//./\\.}\\.[0-9]+(-[0-9]+)?(\+bpo|\+deb[0-9]+)?-cloud-${ARCHITECTURE}-"
debug_match=""
for debug_suffix in dbg dbgsym; do
regex="${DEBUG_REGEX_BASE}${debug_suffix}_.*\\.deb"
debug_match=$(printf '%s\n' "$URLS" | grep -E "$regex" | sort -V | tail -n1 || true)
if [[ -n "$debug_match" ]]; then
break
fi
done
if [[ -z "$debug_match" ]]; then
printf 'Failed to locate debug package for VERSION=%s (tried dbg/dbgsym)\n' "$VERSION" >&2
# between -dbg and -dbgsym suffixes, so match either for the specific kernel
# we just selected.
kernel_basename=$(basename "$match")
kernel_prefix=${kernel_basename%%_*}
kernel_suffix=${kernel_basename#${kernel_prefix}_}
base_prefix=${kernel_prefix%-unsigned}
base_prefix_regex=$(printf '%s\n' "$base_prefix" | sed 's/[][(){}.^$*+?|\\-]/\\&/g')
kernel_suffix_regex=$(printf '%s\n' "$kernel_suffix" | sed 's/[][(){}.^$*+?|\\-]/\\&/g')
DEBUG_REGEX="${base_prefix_regex}-dbg(sym)?_${kernel_suffix_regex}"
debug_match=$(printf '%s\n' "$URLS" | grep -E "$DEBUG_REGEX" | sort -V | tail -n1) || {
printf 'Failed to locate debug package matching %s\n%s\nVERSION=%s\nREGEX=%s\n' \
"$kernel_basename" "$URLS" "$VERSION" "$DEBUG_REGEX" >&2
exit 1
fi
}
FILES+=("$debug_match")
done

@ -236,10 +236,6 @@ pub enum ProgramError {
/// An error occurred while working with Netlink.
#[error(transparent)]
NetlinkError(#[from] NetlinkError),
/// The perf event breakpoint is underspecified
#[error("the breakpoint description is missing or incomplete")]
IncompleteBreakpoint,
}
/// A [`Program`] file descriptor.

@ -3,10 +3,8 @@
use std::os::fd::AsFd as _;
use aya_obj::generated::{
HW_BREAKPOINT_EMPTY, HW_BREAKPOINT_INVALID, HW_BREAKPOINT_LEN_1, HW_BREAKPOINT_LEN_2,
HW_BREAKPOINT_LEN_3, HW_BREAKPOINT_LEN_4, HW_BREAKPOINT_LEN_5, HW_BREAKPOINT_LEN_6,
HW_BREAKPOINT_LEN_7, HW_BREAKPOINT_LEN_8, HW_BREAKPOINT_R, HW_BREAKPOINT_RW, HW_BREAKPOINT_W,
HW_BREAKPOINT_X, bpf_link_type,
HW_BREAKPOINT_LEN_1, HW_BREAKPOINT_LEN_2, HW_BREAKPOINT_LEN_4, HW_BREAKPOINT_LEN_8,
bpf_link_type,
bpf_prog_type::BPF_PROG_TYPE_PERF_EVENT,
perf_hw_cache_id, perf_hw_cache_op_id, perf_hw_cache_op_result_id, perf_hw_id, perf_sw_ids,
perf_type_id,
@ -21,7 +19,7 @@ use crate::{
FdLink, LinkError, ProgramData, ProgramError, ProgramType, impl_try_into_fdlink,
links::define_link_wrapper,
load_program,
perf_attach::{PerfLinkIdInner, PerfLinkInner},
perf_attach::{PerfLinkIdInner, PerfLinkInner, perf_attach},
},
sys::{SyscallError, bpf_link_get_info_by_fd, perf_event_open},
};
@ -62,16 +60,7 @@ pub enum PerfEventConfig {
},
/// A hardware breakpoint.
#[doc(alias = "PERF_TYPE_BREAKPOINT")]
Breakpoint {
/// The address to set the breakpoint on
address: u64,
/// The breakpoint size. For HwBreakpointX this must be sizeof(long). For
/// all other types it should be one of HwBreakpointLen1, HwBreakpointLen2,,
/// HwBreakpointLen4 or HwBreakpointLen8.
length: PerfBreakpointSize,
/// The breakpoint type, one of HW_BREAKPOINT_{R,W,RW,X}
type_: PerfBreakpointType,
},
Breakpoint(BreakpointConfig),
/// The dynamic PMU (Performance Monitor Unit) event to report.
///
/// Available PMU's may be found under `/sys/bus/event_source/devices`.
@ -290,38 +279,51 @@ impl HwCacheResult {
}
}
/// Type of hardware breakpoint, determines if we break on read, write, or execute.
#[repr(u32)]
/// Type of hardware breakpoint, determines if we break on read, write, or
/// execute, or if there should be no breakpoint on the given address.
#[derive(Debug, Clone, Copy)]
pub enum PerfBreakpointType {
/// HW_BREAKPOINT_EMPTY
pub enum BreakpointConfig {
/// HW_BREAKPOINT_EMPTY, no breakpoint.
#[doc(alias = "HW_BREAKPOINT_EMPTY")]
HwBreakpointEmpty = HW_BREAKPOINT_EMPTY,
/// HW_BREAKPOINT_R
Empty {
/// The size of the breakpoint being measured.
size: PerfBreakpointSize,
/// The address of the breakpoint.
address: u64,
},
/// HW_BREAKPOINT_R, count when we read the memory location.
#[doc(alias = "HW_BREAKPOINT_R")]
HwBreakpointR = HW_BREAKPOINT_R,
/// HW_BREAKPOINT_W
Read {
/// The size of the breakpoint being measured.
size: PerfBreakpointSize,
/// The address of the breakpoint.
address: u64,
},
/// HW_BREAKPOINT_W, count when we write the memory location.
#[doc(alias = "HW_BREAKPOINT_W")]
HwBreakpointW = HW_BREAKPOINT_W,
/// HW_BREAKPOINT_RW
Write {
/// The size of the breakpoint being measured.
size: PerfBreakpointSize,
/// The address of the breakpoint.
address: u64,
},
/// HW_BREAKPOINT_RW, count when we read or write the memory location.
#[doc(alias = "HW_BREAKPOINT_RW")]
HwBreakpointRW = HW_BREAKPOINT_RW,
/// HW_BREAKPOINT_X
ReadWrite {
/// The size of the breakpoint being measured.
size: PerfBreakpointSize,
/// The address of the breakpoint.
address: u64,
},
/// HW_BREAKPOINT_X, count when we execute code at the memory location.
#[doc(alias = "HW_BREAKPOINT_X")]
HwBreakpointX = HW_BREAKPOINT_X,
/// HW_BREAKPOINT_INVALID
#[doc(alias = "HW_BREAKPOINT_INVALID")]
HwBreakpointInvalid = HW_BREAKPOINT_INVALID,
}
impl PerfBreakpointType {
pub(crate) const fn into_primitive(self) -> u32 {
const _: [(); 4] = [(); std::mem::size_of::<PerfBreakpointType>()];
self as u32
}
Execute {
/// The address of the breakpoint.
address: u64,
},
}
/// The size of the breakpoint being measured
/// The size of the breakpoint being observed in bytes.
#[repr(u64)]
#[derive(Debug, Clone, Copy)]
pub enum PerfBreakpointSize {
@ -331,21 +333,9 @@ pub enum PerfBreakpointSize {
/// HW_BREAKPOINT_LEN_2
#[doc(alias = "HW_BREAKPOINT_LEN_2")]
HwBreakpointLen2 = HW_BREAKPOINT_LEN_2 as u64,
/// HW_BREAKPOINT_LEN_3
#[doc(alias = "HW_BREAKPOINT_LEN_3")]
HwBreakpointLen3 = HW_BREAKPOINT_LEN_3 as u64,
/// HW_BREAKPOINT_LEN_4
#[doc(alias = "HW_BREAKPOINT_LEN_4")]
HwBreakpointLen4 = HW_BREAKPOINT_LEN_4 as u64,
/// HW_BREAKPOINT_LEN_5
#[doc(alias = "HW_BREAKPOINT_LEN_5")]
HwBreakpointLen5 = HW_BREAKPOINT_LEN_5 as u64,
/// HW_BREAKPOINT_LEN_6
#[doc(alias = "HW_BREAKPOINT_LEN_6")]
HwBreakpointLen6 = HW_BREAKPOINT_LEN_6 as u64,
/// HW_BREAKPOINT_LEN_7
#[doc(alias = "HW_BREAKPOINT_LEN_7")]
HwBreakpointLen7 = HW_BREAKPOINT_LEN_7 as u64,
/// HW_BREAKPOINT_LEN_8
#[doc(alias = "HW_BREAKPOINT_LEN_8")]
HwBreakpointLen8 = HW_BREAKPOINT_LEN_8 as u64,
@ -356,6 +346,16 @@ impl PerfBreakpointSize {
const _: [(); 8] = [(); std::mem::size_of::<PerfBreakpointSize>()];
self as u64
}
pub(crate) const fn from_primitive(size: u64) -> Self {
match size {
n if n == Self::HwBreakpointLen1.into_primitive() => Self::HwBreakpointLen1,
n if n == Self::HwBreakpointLen2.into_primitive() => Self::HwBreakpointLen2,
n if n == Self::HwBreakpointLen4.into_primitive() => Self::HwBreakpointLen4,
n if n == Self::HwBreakpointLen8.into_primitive() => Self::HwBreakpointLen8,
_ => panic!("invalid hardware breakpoint size"),
}
}
}
/// Sample Policy
@ -473,6 +473,7 @@ impl PerfEvent {
let prog_fd = self.fd()?;
let prog_fd = prog_fd.as_fd();
let mut breakpoint = None;
let (perf_type, config) = match perf_config {
PerfEventConfig::Pmu { pmu_type, config } => (pmu_type, config),
PerfEventConfig::Hardware(hw_event) => (
@ -497,11 +498,10 @@ impl PerfEvent {
| (u64::from(result.into_primitive()) << 16),
),
PerfEventConfig::Raw { event_id } => (perf_type_id_to_u32(PERF_TYPE_RAW), event_id),
PerfEventConfig::Breakpoint {
address: _,
length: _,
type_: _,
} => (perf_type_id_to_u32(PERF_TYPE_BREAKPOINT), 0),
PerfEventConfig::Breakpoint(config) => {
breakpoint = Some(config);
(perf_type_id_to_u32(PERF_TYPE_BREAKPOINT), 0)
}
};
let (sample_period, sample_frequency) = match sample_policy {
SamplePolicy::Period(period) => (period, None),
@ -521,18 +521,16 @@ impl PerfEvent {
cpu,
sample_period,
sample_frequency,
// wakeup=true for breakpoints, false for all other types
perf_type == perf_type_id_to_u32(PERF_TYPE_BREAKPOINT),
inherit,
0,
Some(perf_config),
breakpoint,
)
.map_err(|io_error| SyscallError {
call: "perf_event_open",
io_error,
})?;
let link = crate::programs::perf_attach(prog_fd, fd, None /* cookie */)?;
let link = perf_attach(prog_fd, fd, None /* cookie */)?;
self.data.links.insert(PerfEventLink::new(link))
}
}

@ -5,6 +5,7 @@ use std::{
};
use aya_obj::generated::{
HW_BREAKPOINT_EMPTY, HW_BREAKPOINT_R, HW_BREAKPOINT_RW, HW_BREAKPOINT_W, HW_BREAKPOINT_X,
PERF_FLAG_FD_CLOEXEC, perf_event_attr,
perf_event_sample_format::PERF_SAMPLE_RAW,
perf_sw_ids::PERF_COUNT_SW_BPF_OUTPUT,
@ -13,7 +14,7 @@ use aya_obj::generated::{
use libc::pid_t;
use super::{PerfEventIoctlRequest, Syscall, syscall};
use crate::programs::perf_event::PerfEventConfig;
use crate::programs::perf_event::{BreakpointConfig, PerfBreakpointSize};
#[expect(clippy::too_many_arguments)]
pub(crate) fn perf_event_open(
@ -23,10 +24,9 @@ pub(crate) fn perf_event_open(
cpu: c_int,
sample_period: u64,
sample_frequency: Option<u64>,
wakeup: bool,
inherit: bool,
flags: u32,
perf_config: Option<PerfEventConfig>,
breakpoint: Option<BreakpointConfig>,
) -> io::Result<crate::MockableFd> {
let mut attr = unsafe { mem::zeroed::<perf_event_attr>() };
@ -35,7 +35,6 @@ pub(crate) fn perf_event_open(
attr.type_ = perf_type;
attr.sample_type = PERF_SAMPLE_RAW as u64;
attr.set_inherit(if inherit { 1 } else { 0 });
attr.__bindgen_anon_2.wakeup_events = u32::from(wakeup);
if let Some(frequency) = sample_frequency {
attr.set_freq(1);
@ -44,16 +43,25 @@ pub(crate) fn perf_event_open(
attr.__bindgen_anon_1.sample_period = sample_period;
}
if let Some(PerfEventConfig::Breakpoint {
address,
length,
type_,
}) = perf_config
{
attr.bp_type = type_.into_primitive();
if let Some(bp) = breakpoint {
let (type_, length, address) = match bp {
BreakpointConfig::Empty { size, address } => (HW_BREAKPOINT_EMPTY, size, address),
BreakpointConfig::Read { size, address } => (HW_BREAKPOINT_R, size, address),
BreakpointConfig::Write { size, address } => (HW_BREAKPOINT_W, size, address),
BreakpointConfig::ReadWrite { size, address } => (HW_BREAKPOINT_RW, size, address),
BreakpointConfig::Execute { address } => (
HW_BREAKPOINT_X,
PerfBreakpointSize::from_primitive(std::mem::size_of::<libc::c_long>() as u64),
address,
),
};
attr.bp_type = type_;
attr.__bindgen_anon_3.bp_addr = address;
attr.__bindgen_anon_4.bp_len = length.into_primitive();
attr.set_precise_ip(2);
attr.__bindgen_anon_2.wakeup_events = u32::from(true);
} else {
attr.__bindgen_anon_2.wakeup_events = u32::from(false);
}
perf_event_sys(attr, pid, cpu, flags)
@ -68,7 +76,6 @@ pub(crate) fn perf_event_open_bpf(cpu: c_int) -> io::Result<crate::MockableFd> {
1,
None,
true,
false,
PERF_FLAG_FD_CLOEXEC,
None,
)

@ -7,10 +7,7 @@ use aya::{
Ebpf,
programs::{
PerfEventScope, SamplePolicy,
perf_event::{
PerfBreakpointSize::HwBreakpointLen1, PerfBreakpointType::HwBreakpointRW,
PerfEventConfig,
},
perf_event::{BreakpointConfig, PerfBreakpointSize::HwBreakpointLen1, PerfEventConfig},
},
util::online_cpus,
};
@ -72,6 +69,10 @@ fn find_kallsyms_symbol(sym: &str) -> Option<u64> {
#[test_log::test]
fn perf_event_bp() {
let mut bpf = Ebpf::load(crate::PERF_EVENT_BP).unwrap();
// Search for the address of modprobe_path. Prefer to grab it directly from
// kallsyms, but if it's not there we can grab it from System.map and apply
// the kaslr offset.
let attach_addr = if let Some(addr) = find_kallsyms_symbol("modprobe_path") {
addr
} else {
@ -91,15 +92,13 @@ fn perf_event_bp() {
.unwrap();
prog.load().unwrap();
// attach hardware breakpoint to modprobe_path global
for cpu in online_cpus().unwrap() {
info!("attaching to cpu {cpu}");
prog.attach(
PerfEventConfig::Breakpoint {
PerfEventConfig::Breakpoint(BreakpointConfig::ReadWrite {
address: attach_addr,
length: HwBreakpointLen1,
type_: HwBreakpointRW,
},
size: HwBreakpointLen1,
}),
PerfEventScope::AllProcessesOneCpu { cpu },
SamplePolicy::Period(1),
true,
@ -107,10 +106,14 @@ fn perf_event_bp() {
.unwrap();
}
// trigger hardware breakpoint by reading modprobe_path via procfs
let _ = fs::read_to_string("/proc/sys/kernel/modprobe");
// Trigger the hardware breakpoint by reading /proc/sys/kernel/modprobe, the
// sysctl connected to modprobe_path.
//
// See: https://elixir.bootlin.com/linux/v6.1.155/source/kernel/sysctl.c#L1770
fs::read_to_string("/proc/sys/kernel/modprobe").expect("failed to read modprobe");
// assert that the map contains an entry for this process
// Assert that the map contains an entry for this process, and that we read
// the address we expected to.
let map: aya::maps::HashMap<_, u32, u64> =
aya::maps::HashMap::try_from(bpf.map_mut("READERS").unwrap()).unwrap();
let tgid = std::process::id();

@ -5299,6 +5299,54 @@ pub fn aya::programs::perf_attach::PerfLinkId::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::programs::perf_attach::PerfLinkId
pub fn aya::programs::perf_attach::PerfLinkId::from(t: T) -> T
pub mod aya::programs::perf_event
pub enum aya::programs::perf_event::BreakpointConfig
pub aya::programs::perf_event::BreakpointConfig::Empty
pub aya::programs::perf_event::BreakpointConfig::Empty::address: u64
pub aya::programs::perf_event::BreakpointConfig::Empty::size: aya::programs::perf_event::PerfBreakpointSize
pub aya::programs::perf_event::BreakpointConfig::Execute
pub aya::programs::perf_event::BreakpointConfig::Execute::address: u64
pub aya::programs::perf_event::BreakpointConfig::Read
pub aya::programs::perf_event::BreakpointConfig::Read::address: u64
pub aya::programs::perf_event::BreakpointConfig::Read::size: aya::programs::perf_event::PerfBreakpointSize
pub aya::programs::perf_event::BreakpointConfig::ReadWrite
pub aya::programs::perf_event::BreakpointConfig::ReadWrite::address: u64
pub aya::programs::perf_event::BreakpointConfig::ReadWrite::size: aya::programs::perf_event::PerfBreakpointSize
pub aya::programs::perf_event::BreakpointConfig::Write
pub aya::programs::perf_event::BreakpointConfig::Write::address: u64
pub aya::programs::perf_event::BreakpointConfig::Write::size: aya::programs::perf_event::PerfBreakpointSize
impl core::clone::Clone for aya::programs::perf_event::BreakpointConfig
pub fn aya::programs::perf_event::BreakpointConfig::clone(&self) -> aya::programs::perf_event::BreakpointConfig
impl core::fmt::Debug for aya::programs::perf_event::BreakpointConfig
pub fn aya::programs::perf_event::BreakpointConfig::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl core::marker::Copy for aya::programs::perf_event::BreakpointConfig
impl core::marker::Freeze for aya::programs::perf_event::BreakpointConfig
impl core::marker::Send for aya::programs::perf_event::BreakpointConfig
impl core::marker::Sync for aya::programs::perf_event::BreakpointConfig
impl core::marker::Unpin for aya::programs::perf_event::BreakpointConfig
impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::BreakpointConfig
impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::BreakpointConfig
impl<T, U> core::convert::Into<U> for aya::programs::perf_event::BreakpointConfig where U: core::convert::From<T>
pub fn aya::programs::perf_event::BreakpointConfig::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::programs::perf_event::BreakpointConfig where U: core::convert::Into<T>
pub type aya::programs::perf_event::BreakpointConfig::Error = core::convert::Infallible
pub fn aya::programs::perf_event::BreakpointConfig::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::programs::perf_event::BreakpointConfig where U: core::convert::TryFrom<T>
pub type aya::programs::perf_event::BreakpointConfig::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::programs::perf_event::BreakpointConfig::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> alloc::borrow::ToOwned for aya::programs::perf_event::BreakpointConfig where T: core::clone::Clone
pub type aya::programs::perf_event::BreakpointConfig::Owned = T
pub fn aya::programs::perf_event::BreakpointConfig::clone_into(&self, target: &mut T)
pub fn aya::programs::perf_event::BreakpointConfig::to_owned(&self) -> T
impl<T> core::any::Any for aya::programs::perf_event::BreakpointConfig where T: 'static + ?core::marker::Sized
pub fn aya::programs::perf_event::BreakpointConfig::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::programs::perf_event::BreakpointConfig where T: ?core::marker::Sized
pub fn aya::programs::perf_event::BreakpointConfig::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::programs::perf_event::BreakpointConfig where T: ?core::marker::Sized
pub fn aya::programs::perf_event::BreakpointConfig::borrow_mut(&mut self) -> &mut T
impl<T> core::clone::CloneToUninit for aya::programs::perf_event::BreakpointConfig where T: core::clone::Clone
pub unsafe fn aya::programs::perf_event::BreakpointConfig::clone_to_uninit(&self, dest: *mut u8)
impl<T> core::convert::From<T> for aya::programs::perf_event::BreakpointConfig
pub fn aya::programs::perf_event::BreakpointConfig::from(t: T) -> T
#[repr(u32)] pub enum aya::programs::perf_event::HardwareEvent
pub aya::programs::perf_event::HardwareEvent::BranchInstructions = 4
pub aya::programs::perf_event::HardwareEvent::BranchMisses = 5
@ -5460,11 +5508,7 @@ pub fn aya::programs::perf_event::HwCacheResult::from(t: T) -> T
#[repr(u64)] pub enum aya::programs::perf_event::PerfBreakpointSize
pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen1 = 1
pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen2 = 2
pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen3 = 3
pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen4 = 4
pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen5 = 5
pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen6 = 6
pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen7 = 7
pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen8 = 8
impl core::clone::Clone for aya::programs::perf_event::PerfBreakpointSize
pub fn aya::programs::perf_event::PerfBreakpointSize::clone(&self) -> aya::programs::perf_event::PerfBreakpointSize
@ -5499,51 +5543,8 @@ impl<T> core::clone::CloneToUninit for aya::programs::perf_event::PerfBreakpoint
pub unsafe fn aya::programs::perf_event::PerfBreakpointSize::clone_to_uninit(&self, dest: *mut u8)
impl<T> core::convert::From<T> for aya::programs::perf_event::PerfBreakpointSize
pub fn aya::programs::perf_event::PerfBreakpointSize::from(t: T) -> T
#[repr(u32)] pub enum aya::programs::perf_event::PerfBreakpointType
pub aya::programs::perf_event::PerfBreakpointType::HwBreakpointEmpty = 0
pub aya::programs::perf_event::PerfBreakpointType::HwBreakpointInvalid = 7
pub aya::programs::perf_event::PerfBreakpointType::HwBreakpointR = 1
pub aya::programs::perf_event::PerfBreakpointType::HwBreakpointRW = 3
pub aya::programs::perf_event::PerfBreakpointType::HwBreakpointW = 2
pub aya::programs::perf_event::PerfBreakpointType::HwBreakpointX = 4
impl core::clone::Clone for aya::programs::perf_event::PerfBreakpointType
pub fn aya::programs::perf_event::PerfBreakpointType::clone(&self) -> aya::programs::perf_event::PerfBreakpointType
impl core::fmt::Debug for aya::programs::perf_event::PerfBreakpointType
pub fn aya::programs::perf_event::PerfBreakpointType::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl core::marker::Copy for aya::programs::perf_event::PerfBreakpointType
impl core::marker::Freeze for aya::programs::perf_event::PerfBreakpointType
impl core::marker::Send for aya::programs::perf_event::PerfBreakpointType
impl core::marker::Sync for aya::programs::perf_event::PerfBreakpointType
impl core::marker::Unpin for aya::programs::perf_event::PerfBreakpointType
impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::PerfBreakpointType
impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::PerfBreakpointType
impl<T, U> core::convert::Into<U> for aya::programs::perf_event::PerfBreakpointType where U: core::convert::From<T>
pub fn aya::programs::perf_event::PerfBreakpointType::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::programs::perf_event::PerfBreakpointType where U: core::convert::Into<T>
pub type aya::programs::perf_event::PerfBreakpointType::Error = core::convert::Infallible
pub fn aya::programs::perf_event::PerfBreakpointType::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::programs::perf_event::PerfBreakpointType where U: core::convert::TryFrom<T>
pub type aya::programs::perf_event::PerfBreakpointType::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::programs::perf_event::PerfBreakpointType::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> alloc::borrow::ToOwned for aya::programs::perf_event::PerfBreakpointType where T: core::clone::Clone
pub type aya::programs::perf_event::PerfBreakpointType::Owned = T
pub fn aya::programs::perf_event::PerfBreakpointType::clone_into(&self, target: &mut T)
pub fn aya::programs::perf_event::PerfBreakpointType::to_owned(&self) -> T
impl<T> core::any::Any for aya::programs::perf_event::PerfBreakpointType where T: 'static + ?core::marker::Sized
pub fn aya::programs::perf_event::PerfBreakpointType::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::programs::perf_event::PerfBreakpointType where T: ?core::marker::Sized
pub fn aya::programs::perf_event::PerfBreakpointType::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::programs::perf_event::PerfBreakpointType where T: ?core::marker::Sized
pub fn aya::programs::perf_event::PerfBreakpointType::borrow_mut(&mut self) -> &mut T
impl<T> core::clone::CloneToUninit for aya::programs::perf_event::PerfBreakpointType where T: core::clone::Clone
pub unsafe fn aya::programs::perf_event::PerfBreakpointType::clone_to_uninit(&self, dest: *mut u8)
impl<T> core::convert::From<T> for aya::programs::perf_event::PerfBreakpointType
pub fn aya::programs::perf_event::PerfBreakpointType::from(t: T) -> T
pub enum aya::programs::perf_event::PerfEventConfig
pub aya::programs::perf_event::PerfEventConfig::Breakpoint
pub aya::programs::perf_event::PerfEventConfig::Breakpoint::address: u64
pub aya::programs::perf_event::PerfEventConfig::Breakpoint::length: aya::programs::perf_event::PerfBreakpointSize
pub aya::programs::perf_event::PerfEventConfig::Breakpoint::type_: aya::programs::perf_event::PerfBreakpointType
pub aya::programs::perf_event::PerfEventConfig::Breakpoint(aya::programs::perf_event::BreakpointConfig)
pub aya::programs::perf_event::PerfEventConfig::Hardware(aya::programs::perf_event::HardwareEvent)
pub aya::programs::perf_event::PerfEventConfig::HwCache
pub aya::programs::perf_event::PerfEventConfig::HwCache::event: aya::programs::perf_event::HwCacheEvent
@ -8297,7 +8298,6 @@ pub aya::programs::ProgramError::AttachCookieNotSupported
pub aya::programs::ProgramError::Btf(aya_obj::btf::btf::BtfError)
pub aya::programs::ProgramError::ExtensionError(aya::programs::extension::ExtensionError)
pub aya::programs::ProgramError::IOError(std::io::error::Error)
pub aya::programs::ProgramError::IncompleteBreakpoint
pub aya::programs::ProgramError::InvalidName
pub aya::programs::ProgramError::InvalidName::name: alloc::string::String
pub aya::programs::ProgramError::KProbeError(aya::programs::kprobe::KProbeError)

Loading…
Cancel
Save