Repository: aya-rs/aya (language: rust)

Issue:
Support non-UTF-8 symbol probing
See conversation: https://github.com/aya-rs/aya/pull/742#discussion_r1291191539


Discussion / hints:

Fix patch:
diff --git a/aya/src/programs/kprobe.rs b/aya/src/programs/kprobe.rs
index ef34a3f4b..c915136e2 100644
--- a/aya/src/programs/kprobe.rs
+++ b/aya/src/programs/kprobe.rs
@@ -1,5 +1,6 @@
 //! Kernel space probes.
 use std::{
+    ffi::OsStr,
     io,
     os::fd::AsFd as _,
     path::{Path, PathBuf},
@@ -71,8 +72,12 @@ impl KProbe {
     /// target function.
     ///
     /// The returned value can be used to detach from the given function, see [KProbe::detach].
-    pub fn attach(&mut self, fn_name: &str, offset: u64) -> Result<KProbeLinkId, ProgramError> {
-        attach(&mut self.data, self.kind, Path::new(fn_name), offset, None)
+    pub fn attach<T: AsRef<OsStr>>(
+        &mut self,
+        fn_name: T,
+        offset: u64,
+    ) -> Result<KProbeLinkId, ProgramError> {
+        attach(&mut self.data, self.kind, fn_name.as_ref(), offset, None)
     }
 
     /// Detaches the program.
diff --git a/aya/src/programs/probe.rs b/aya/src/programs/probe.rs
index ea0d59b5f..f8b53baec 100644
--- a/aya/src/programs/probe.rs
+++ b/aya/src/programs/probe.rs
@@ -101,7 +101,13 @@ pub(crate) struct ProbeEvent {
 pub(crate) fn attach<T: Link + From<PerfLinkInner>>(
     program_data: &mut ProgramData<T>,
     kind: ProbeKind,
-    fn_name: &Path,
+    // NB: the meaning of this argument is different for kprobe/kretprobe and uprobe/uretprobe; in
+    // the kprobe case it is the name of the function to attach to, in the uprobe case it is a path
+    // to the binary or library.
+    //
+    // TODO: consider encoding the type and the argument in the [`ProbeKind`] enum instead of a
+    // separate argument.
+    fn_name: &OsStr,
     offset: u64,
     pid: Option<pid_t>,
 ) -> Result<T::Id, ProgramError> {
@@ -140,7 +146,7 @@ pub(crate) fn detach_debug_fs(event: ProbeEvent) -> Result<(), ProgramError> {
 
 fn create_as_probe(
     kind: ProbeKind,
-    fn_name: &Path,
+    fn_name: &OsStr,
     offset: u64,
     pid: Option<pid_t>,
 ) -> Result<OwnedFd, ProgramError> {
@@ -176,7 +182,7 @@ fn create_as_probe(
 
 fn create_as_trace_point(
     kind: ProbeKind,
-    name: &Path,
+    name: &OsStr,
     offset: u64,
     pid: Option<pid_t>,
 ) -> Result<(OwnedFd, OsString), ProgramError> {
@@ -204,7 +210,7 @@ fn create_as_trace_point(
 fn create_probe_event(
     tracefs: &Path,
     kind: ProbeKind,
-    fn_name: &Path,
+    fn_name: &OsStr,
     offset: u64,
 ) -> Result<OsString, (PathBuf, io::Error)> {
     use std::os::unix::ffi::OsStrExt as _;
@@ -216,8 +222,6 @@ fn create_probe_event(
         KRetProbe | URetProbe => 'r',
     };
 
-    let fn_name = fn_name.as_os_str();
-
     let mut event_alias = OsString::new();
     write!(
         &mut event_alias,
diff --git a/aya/src/programs/uprobe.rs b/aya/src/programs/uprobe.rs
index 00d306ada..d95f6b2cd 100644
--- a/aya/src/programs/uprobe.rs
+++ b/aya/src/programs/uprobe.rs
@@ -94,7 +94,8 @@ impl UProbe {
             0
         };
 
-        attach(&mut self.data, self.kind, &path, sym_offset + offset, pid)
+        let fn_name = path.as_os_str();
+        attach(&mut self.data, self.kind, fn_name, sym_offset + offset, pid)
     }
 
     /// Detaches the program.
diff --git a/aya/src/sys/perf_event.rs b/aya/src/sys/perf_event.rs
index 000fecbc1..1659778a9 100644
--- a/aya/src/sys/perf_event.rs
+++ b/aya/src/sys/perf_event.rs
@@ -1,8 +1,7 @@
 use std::{
-    ffi::{c_long, CString},
+    ffi::{c_long, CString, OsStr},
     io, mem,
     os::fd::{BorrowedFd, FromRawFd as _, OwnedFd},
-    path::Path,
 };
 
 use libc::{c_int, pid_t};
@@ -63,7 +62,7 @@ pub(crate) fn perf_event_open_bpf(cpu: c_int) -> SysResult<OwnedFd> {
 pub(crate) fn perf_event_open_probe(
     ty: u32,
     ret_bit: Option<u32>,
-    name: &Path,
+    name: &OsStr,
     offset: u64,
     pid: Option<pid_t>,
 ) -> SysResult<OwnedFd> {
@@ -75,7 +74,7 @@ pub(crate) fn perf_event_open_probe(
         attr.config = 1 << ret_bit;
     }
 
-    let c_name = CString::new(name.as_os_str().as_bytes()).unwrap();
+    let c_name = CString::new(name.as_bytes()).unwrap();
 
     attr.size = mem::size_of::<perf_event_attr>() as u32;
     attr.type_ = ty;
diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt
index 1ef6c0c86..4c06ccf67 100644
--- a/xtask/public-api/aya.txt
+++ b/xtask/public-api/aya.txt
@@ -2896,7 +2896,7 @@ impl<T> core::convert::From<T> for aya::programs::kprobe::KProbeError
 pub fn aya::programs::kprobe::KProbeError::from(t: T) -> T
 pub struct aya::programs::kprobe::KProbe
 impl aya::programs::kprobe::KProbe
-pub fn aya::programs::kprobe::KProbe::attach(&mut self, fn_name: &str, offset: u64) -> core::result::Result<aya::programs::kprobe::KProbeLinkId, aya::programs::ProgramError>
+pub fn aya::programs::kprobe::KProbe::attach<T: core::convert::AsRef<std::ffi::os_str::OsStr>>(&mut self, fn_name: T, offset: u64) -> core::result::Result<aya::programs::kprobe::KProbeLinkId, aya::programs::ProgramError>
 pub fn aya::programs::kprobe::KProbe::detach(&mut self, link_id: aya::programs::kprobe::KProbeLinkId) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::kprobe::KProbe::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, kind: aya::programs::ProbeKind) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::kprobe::KProbe::kind(&self) -> aya::programs::ProbeKind
@@ -5997,7 +5997,7 @@ impl<T> core::convert::From<T> for aya::programs::fexit::FExit
 pub fn aya::programs::fexit::FExit::from(t: T) -> T
 pub struct aya::programs::KProbe
 impl aya::programs::kprobe::KProbe
-pub fn aya::programs::kprobe::KProbe::attach(&mut self, fn_name: &str, offset: u64) -> core::result::Result<aya::programs::kprobe::KProbeLinkId, aya::programs::ProgramError>
+pub fn aya::programs::kprobe::KProbe::attach<T: core::convert::AsRef<std::ffi::os_str::OsStr>>(&mut self, fn_name: T, offset: u64) -> core::result::Result<aya::programs::kprobe::KProbeLinkId, aya::programs::ProgramError>
 pub fn aya::programs::kprobe::KProbe::detach(&mut self, link_id: aya::programs::kprobe::KProbeLinkId) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::kprobe::KProbe::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, kind: aya::programs::ProbeKind) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::kprobe::KProbe::kind(&self) -> aya::programs::ProbeKind


Test patch: