Ver Fonte

Do not escape newlines on Err(LoadError).unwrap()

Wrap verifier logs in a newtype whose `Debug` impl emits unescaped
newlines. This improves ergonomics in tests where we `Result::unwrap()`
those load errors; when these fail today they emit the errors with
newlines escaped, making them incredibly difficult to read.
Tamir Duberstein há 1 ano atrás
pai
commit
8961be9526

+ 1 - 1
aya-obj/src/btf/btf.rs

@@ -135,7 +135,7 @@ pub enum BtfError {
         #[source]
         io_error: std::io::Error,
         /// The error log produced by the kernel verifier.
-        verifier_log: String,
+        verifier_log: crate::VerifierLog,
     },
 
     /// offset not found for symbol

+ 25 - 0
aya-obj/src/lib.rs

@@ -89,3 +89,28 @@ mod util;
 
 pub use maps::Map;
 pub use obj::*;
+
+/// An error returned from the verifier.
+///
+/// Provides a [`Debug`] implementation that doesn't escape newlines.
+pub struct VerifierLog(alloc::string::String);
+
+impl VerifierLog {
+    /// Create a new verifier log.
+    pub fn new(log: alloc::string::String) -> Self {
+        Self(log)
+    }
+}
+
+impl std::fmt::Debug for VerifierLog {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        let Self(log) = self;
+        f.write_str(log)
+    }
+}
+
+impl std::fmt::Display for VerifierLog {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        <Self as std::fmt::Debug>::fmt(self, f)
+    }
+}

+ 2 - 2
aya/src/programs/mod.rs

@@ -107,7 +107,7 @@ pub use xdp::{Xdp, XdpError, XdpFlags};
 use crate::{
     generated::{bpf_attach_type, bpf_prog_info, bpf_prog_type},
     maps::MapError,
-    obj::{self, btf::BtfError, Function},
+    obj::{self, btf::BtfError, Function, VerifierLog},
     pin::PinError,
     sys::{
         bpf_btf_get_fd_by_id, bpf_get_object, bpf_load_program, bpf_pin_object,
@@ -143,7 +143,7 @@ pub enum ProgramError {
         #[source]
         io_error: io::Error,
         /// The error log produced by the kernel verifier.
-        verifier_log: String,
+        verifier_log: VerifierLog,
     },
 
     /// A syscall failed.

+ 3 - 3
aya/src/sys/bpf.rs

@@ -11,7 +11,7 @@ use crate::util::KernelVersion;
 use libc::{c_char, c_long, close, ENOENT, ENOSPC};
 use obj::{
     maps::{bpf_map_def, LegacyMap},
-    BpfSectionKind,
+    BpfSectionKind, VerifierLog,
 };
 
 use crate::{
@@ -1008,7 +1008,7 @@ pub(crate) fn bpf_prog_get_next_id(id: u32) -> Result<Option<u32>, (c_long, io::
 pub(crate) fn retry_with_verifier_logs<T>(
     max_retries: usize,
     f: impl Fn(&mut [u8]) -> SysResult<T>,
-) -> (SysResult<T>, String) {
+) -> (SysResult<T>, VerifierLog) {
     const MIN_LOG_BUF_SIZE: usize = 1024 * 10;
     const MAX_LOG_BUF_SIZE: usize = (std::u32::MAX >> 8) as usize;
 
@@ -1034,7 +1034,7 @@ pub(crate) fn retry_with_verifier_logs<T>(
         }
         let log_buf = String::from_utf8(log_buf).unwrap();
 
-        break (ret, log_buf);
+        break (ret, VerifierLog::new(log_buf));
     }
 }
 

+ 31 - 1
xtask/public-api/aya-obj.txt

@@ -25,7 +25,7 @@ pub aya_obj::btf::BtfError::InvalidTypeKind
 pub aya_obj::btf::BtfError::InvalidTypeKind::kind: u32
 pub aya_obj::btf::BtfError::LoadError
 pub aya_obj::btf::BtfError::LoadError::io_error: std::io::error::Error
-pub aya_obj::btf::BtfError::LoadError::verifier_log: alloc::string::String
+pub aya_obj::btf::BtfError::LoadError::verifier_log: aya_obj::VerifierLog
 pub aya_obj::btf::BtfError::MaximumTypeDepthReached
 pub aya_obj::btf::BtfError::MaximumTypeDepthReached::type_id: u32
 pub aya_obj::btf::BtfError::SymbolOffsetNotFound
@@ -6813,5 +6813,35 @@ impl<T> core::borrow::BorrowMut<T> for aya_obj::Program where T: core::marker::S
 pub fn aya_obj::Program::borrow_mut(&mut self) -> &mut T
 impl<T> core::convert::From<T> for aya_obj::Program
 pub fn aya_obj::Program::from(t: T) -> T
+pub struct aya_obj::VerifierLog(_)
+impl aya_obj::VerifierLog
+pub fn aya_obj::VerifierLog::new(log: alloc::string::String) -> Self
+impl core::fmt::Debug for aya_obj::VerifierLog
+pub fn aya_obj::VerifierLog::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for aya_obj::VerifierLog
+pub fn aya_obj::VerifierLog::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Send for aya_obj::VerifierLog
+impl core::marker::Sync for aya_obj::VerifierLog
+impl core::marker::Unpin for aya_obj::VerifierLog
+impl core::panic::unwind_safe::RefUnwindSafe for aya_obj::VerifierLog
+impl core::panic::unwind_safe::UnwindSafe for aya_obj::VerifierLog
+impl<T, U> core::convert::Into<U> for aya_obj::VerifierLog where U: core::convert::From<T>
+pub fn aya_obj::VerifierLog::into(self) -> U
+impl<T, U> core::convert::TryFrom<U> for aya_obj::VerifierLog where U: core::convert::Into<T>
+pub type aya_obj::VerifierLog::Error = core::convert::Infallible
+pub fn aya_obj::VerifierLog::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
+impl<T, U> core::convert::TryInto<U> for aya_obj::VerifierLog where U: core::convert::TryFrom<T>
+pub type aya_obj::VerifierLog::Error = <U as core::convert::TryFrom<T>>::Error
+pub fn aya_obj::VerifierLog::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
+impl<T> alloc::string::ToString for aya_obj::VerifierLog where T: core::fmt::Display + core::marker::Sized
+pub fn aya_obj::VerifierLog::to_string(&self) -> alloc::string::String
+impl<T> core::any::Any for aya_obj::VerifierLog where T: 'static + core::marker::Sized
+pub fn aya_obj::VerifierLog::type_id(&self) -> core::any::TypeId
+impl<T> core::borrow::Borrow<T> for aya_obj::VerifierLog where T: core::marker::Sized
+pub fn aya_obj::VerifierLog::borrow(&self) -> &T
+impl<T> core::borrow::BorrowMut<T> for aya_obj::VerifierLog where T: core::marker::Sized
+pub fn aya_obj::VerifierLog::borrow_mut(&mut self) -> &mut T
+impl<T> core::convert::From<T> for aya_obj::VerifierLog
+pub fn aya_obj::VerifierLog::from(t: T) -> T
 pub fn aya_obj::copy_instructions(data: &[u8]) -> core::result::Result<alloc::vec::Vec<aya_obj::generated::bpf_insn>, aya_obj::ParseError>
 pub fn aya_obj::parse_map_info(info: aya_obj::generated::bpf_map_info, pinned: aya_obj::maps::PinningType) -> aya_obj::maps::Map

+ 1 - 1
xtask/public-api/aya.txt

@@ -5169,7 +5169,7 @@ pub aya::programs::ProgramError::InvalidName::name: alloc::string::String
 pub aya::programs::ProgramError::KProbeError(aya::programs::kprobe::KProbeError)
 pub aya::programs::ProgramError::LoadError
 pub aya::programs::ProgramError::LoadError::io_error: std::io::error::Error
-pub aya::programs::ProgramError::LoadError::verifier_log: alloc::string::String
+pub aya::programs::ProgramError::LoadError::verifier_log: aya_obj::VerifierLog
 pub aya::programs::ProgramError::MapError(aya::maps::MapError)
 pub aya::programs::ProgramError::NotAttached
 pub aya::programs::ProgramError::NotLoaded