|
|
@ -2,14 +2,15 @@ use libc::pid_t;
|
|
|
|
use std::{
|
|
|
|
use std::{
|
|
|
|
fs::{self, OpenOptions},
|
|
|
|
fs::{self, OpenOptions},
|
|
|
|
io::{self, Write},
|
|
|
|
io::{self, Write},
|
|
|
|
|
|
|
|
path::Path,
|
|
|
|
process,
|
|
|
|
process,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
use crate::{
|
|
|
|
programs::{
|
|
|
|
programs::{
|
|
|
|
kprobe::KProbeError, perf_attach, perf_attach::PerfLink, perf_attach_debugfs,
|
|
|
|
kprobe::KProbeError, perf_attach, perf_attach::PerfLink, perf_attach_debugfs,
|
|
|
|
trace_point::read_sys_fs_trace_point_id, uprobe::UProbeError, Link, ProgramData,
|
|
|
|
trace_point::read_sys_fs_trace_point_id, uprobe::UProbeError, utils::find_tracefs_path,
|
|
|
|
ProgramError,
|
|
|
|
Link, ProgramData, ProgramError,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
sys::{kernel_version, perf_event_open_probe, perf_event_open_trace_point},
|
|
|
|
sys::{kernel_version, perf_event_open_probe, perf_event_open_trace_point},
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -60,10 +61,12 @@ pub(crate) fn attach<T: Link + From<PerfLink>>(
|
|
|
|
pub(crate) fn detach_debug_fs(kind: ProbeKind, event_alias: &str) -> Result<(), ProgramError> {
|
|
|
|
pub(crate) fn detach_debug_fs(kind: ProbeKind, event_alias: &str) -> Result<(), ProgramError> {
|
|
|
|
use ProbeKind::*;
|
|
|
|
use ProbeKind::*;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let tracefs = find_tracefs_path()?;
|
|
|
|
|
|
|
|
|
|
|
|
match kind {
|
|
|
|
match kind {
|
|
|
|
KProbe | KRetProbe => delete_probe_event(kind, event_alias)
|
|
|
|
KProbe | KRetProbe => delete_probe_event(tracefs, kind, event_alias)
|
|
|
|
.map_err(|(filename, io_error)| KProbeError::FileError { filename, io_error })?,
|
|
|
|
.map_err(|(filename, io_error)| KProbeError::FileError { filename, io_error })?,
|
|
|
|
UProbe | URetProbe => delete_probe_event(kind, event_alias)
|
|
|
|
UProbe | URetProbe => delete_probe_event(tracefs, kind, event_alias)
|
|
|
|
.map_err(|(filename, io_error)| UProbeError::FileError { filename, io_error })?,
|
|
|
|
.map_err(|(filename, io_error)| UProbeError::FileError { filename, io_error })?,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
@ -115,15 +118,17 @@ fn create_as_trace_point(
|
|
|
|
) -> Result<(i32, String), ProgramError> {
|
|
|
|
) -> Result<(i32, String), ProgramError> {
|
|
|
|
use ProbeKind::*;
|
|
|
|
use ProbeKind::*;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let tracefs = find_tracefs_path()?;
|
|
|
|
|
|
|
|
|
|
|
|
let event_alias = match kind {
|
|
|
|
let event_alias = match kind {
|
|
|
|
KProbe | KRetProbe => create_probe_event(kind, name, offset)
|
|
|
|
KProbe | KRetProbe => create_probe_event(tracefs, kind, name, offset)
|
|
|
|
.map_err(|(filename, io_error)| KProbeError::FileError { filename, io_error })?,
|
|
|
|
.map_err(|(filename, io_error)| KProbeError::FileError { filename, io_error })?,
|
|
|
|
UProbe | URetProbe => create_probe_event(kind, name, offset)
|
|
|
|
UProbe | URetProbe => create_probe_event(tracefs, kind, name, offset)
|
|
|
|
.map_err(|(filename, io_error)| UProbeError::FileError { filename, io_error })?,
|
|
|
|
.map_err(|(filename, io_error)| UProbeError::FileError { filename, io_error })?,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
let category = format!("{}s", kind.pmu());
|
|
|
|
let category = format!("{}s", kind.pmu());
|
|
|
|
let tpid = read_sys_fs_trace_point_id(&category, &event_alias)?;
|
|
|
|
let tpid = read_sys_fs_trace_point_id(tracefs, &category, &event_alias)?;
|
|
|
|
let fd = perf_event_open_trace_point(tpid, pid).map_err(|(_code, io_error)| {
|
|
|
|
let fd = perf_event_open_trace_point(tpid, pid).map_err(|(_code, io_error)| {
|
|
|
|
ProgramError::SyscallError {
|
|
|
|
ProgramError::SyscallError {
|
|
|
|
call: "perf_event_open".to_owned(),
|
|
|
|
call: "perf_event_open".to_owned(),
|
|
|
@ -135,13 +140,14 @@ fn create_as_trace_point(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn create_probe_event(
|
|
|
|
fn create_probe_event(
|
|
|
|
|
|
|
|
tracefs: &Path,
|
|
|
|
kind: ProbeKind,
|
|
|
|
kind: ProbeKind,
|
|
|
|
fn_name: &str,
|
|
|
|
fn_name: &str,
|
|
|
|
offset: u64,
|
|
|
|
offset: u64,
|
|
|
|
) -> Result<String, (String, io::Error)> {
|
|
|
|
) -> Result<String, (String, io::Error)> {
|
|
|
|
use ProbeKind::*;
|
|
|
|
use ProbeKind::*;
|
|
|
|
|
|
|
|
|
|
|
|
let events_file_name = format!("/sys/kernel/debug/tracing/{}_events", kind.pmu());
|
|
|
|
let events_file_name = tracefs.join(format!("{}_events", kind.pmu()));
|
|
|
|
let probe_type_prefix = match kind {
|
|
|
|
let probe_type_prefix = match kind {
|
|
|
|
KProbe | UProbe => 'p',
|
|
|
|
KProbe | UProbe => 'p',
|
|
|
|
KRetProbe | URetProbe => 'r',
|
|
|
|
KRetProbe | URetProbe => 'r',
|
|
|
@ -170,20 +176,24 @@ fn create_probe_event(
|
|
|
|
let mut events_file = OpenOptions::new()
|
|
|
|
let mut events_file = OpenOptions::new()
|
|
|
|
.append(true)
|
|
|
|
.append(true)
|
|
|
|
.open(&events_file_name)
|
|
|
|
.open(&events_file_name)
|
|
|
|
.map_err(|e| (events_file_name.clone(), e))?;
|
|
|
|
.map_err(|e| (events_file_name.display().to_string(), e))?;
|
|
|
|
|
|
|
|
|
|
|
|
events_file
|
|
|
|
events_file
|
|
|
|
.write_all(probe.as_bytes())
|
|
|
|
.write_all(probe.as_bytes())
|
|
|
|
.map_err(|e| (events_file_name.clone(), e))?;
|
|
|
|
.map_err(|e| (events_file_name.display().to_string(), e))?;
|
|
|
|
|
|
|
|
|
|
|
|
Ok(event_alias)
|
|
|
|
Ok(event_alias)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn delete_probe_event(kind: ProbeKind, event_alias: &str) -> Result<(), (String, io::Error)> {
|
|
|
|
fn delete_probe_event(
|
|
|
|
let events_file_name = format!("/sys/kernel/debug/tracing/{}_events", kind.pmu());
|
|
|
|
tracefs: &Path,
|
|
|
|
|
|
|
|
kind: ProbeKind,
|
|
|
|
|
|
|
|
event_alias: &str,
|
|
|
|
|
|
|
|
) -> Result<(), (String, io::Error)> {
|
|
|
|
|
|
|
|
let events_file_name = tracefs.join(format!("{}_events", kind.pmu()));
|
|
|
|
|
|
|
|
|
|
|
|
let events =
|
|
|
|
let events = fs::read_to_string(&events_file_name)
|
|
|
|
fs::read_to_string(&events_file_name).map_err(|e| (events_file_name.clone(), e))?;
|
|
|
|
.map_err(|e| (events_file_name.display().to_string(), e))?;
|
|
|
|
|
|
|
|
|
|
|
|
let found = events.lines().any(|line| line.contains(event_alias));
|
|
|
|
let found = events.lines().any(|line| line.contains(event_alias));
|
|
|
|
|
|
|
|
|
|
|
@ -191,13 +201,13 @@ fn delete_probe_event(kind: ProbeKind, event_alias: &str) -> Result<(), (String,
|
|
|
|
let mut events_file = OpenOptions::new()
|
|
|
|
let mut events_file = OpenOptions::new()
|
|
|
|
.append(true)
|
|
|
|
.append(true)
|
|
|
|
.open(&events_file_name)
|
|
|
|
.open(&events_file_name)
|
|
|
|
.map_err(|e| (events_file_name.to_string(), e))?;
|
|
|
|
.map_err(|e| (events_file_name.display().to_string(), e))?;
|
|
|
|
|
|
|
|
|
|
|
|
let rm = format!("-:{event_alias}\n");
|
|
|
|
let rm = format!("-:{event_alias}\n");
|
|
|
|
|
|
|
|
|
|
|
|
events_file
|
|
|
|
events_file
|
|
|
|
.write_all(rm.as_bytes())
|
|
|
|
.write_all(rm.as_bytes())
|
|
|
|
.map_err(|e| (events_file_name.to_string(), e))?;
|
|
|
|
.map_err(|e| (events_file_name.display().to_string(), e))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
|