feat(log): add support for logging raw pointer types

* Requires the usage of `:p` display hint.
* Will, like stdlib, log with `0x` prefix.
create-pull-request/codegen
Christian A. Jacobsen 3 days ago committed by Tamir Duberstein
parent 29dc775535
commit a98b638fa9

@ -97,6 +97,10 @@ impl LowerMacFormatter for [u8; 6] {}
pub trait UpperMacFormatter {} pub trait UpperMacFormatter {}
impl UpperMacFormatter for [u8; 6] {} impl UpperMacFormatter for [u8; 6] {}
pub trait PointerFormatter {}
impl<T> PointerFormatter for *const T {}
impl<T> PointerFormatter for *mut T {}
#[repr(u8)] #[repr(u8)]
#[derive(Copy, Clone, Debug, IntoPrimitive)] #[derive(Copy, Clone, Debug, IntoPrimitive)]
pub enum RecordFieldKind { pub enum RecordFieldKind {
@ -144,6 +148,8 @@ pub enum ArgumentKind {
Bytes, Bytes,
Str, Str,
Pointer,
} }
/// All display hints /// All display hints
@ -162,6 +168,8 @@ pub enum DisplayHint {
LowerMac, LowerMac,
/// `:MAC` /// `:MAC`
UpperMac, UpperMac,
/// `:p`
Pointer,
} }
mod sealed { mod sealed {
@ -282,6 +290,20 @@ impl Argument for DisplayHint {
} }
} }
impl<T> sealed::Sealed for *const T {}
impl<T> Argument for *const T {
fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) {
(ArgumentKind::Pointer, (*self as usize).to_ne_bytes())
}
}
impl<T> sealed::Sealed for *mut T {}
impl<T> Argument for *mut T {
fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) {
(ArgumentKind::Pointer, (*self as usize).to_ne_bytes())
}
}
fn wire_len(value: &[u8]) -> Option<[u8; 2]> { fn wire_len(value: &[u8]) -> Option<[u8; 2]> {
match LogValueLength::try_from(value.len()) { match LogValueLength::try_from(value.len()) {
Ok(wire_len) => Some(wire_len.to_ne_bytes()), Ok(wire_len) => Some(wire_len.to_ne_bytes()),

@ -127,6 +127,9 @@ pub(crate) fn log(args: LogArgs, level_expr: Option<TokenStream>) -> Result<Toke
DisplayHint::UpperMac => { DisplayHint::UpperMac => {
(quote!(DisplayHint::UpperMac), quote!(UpperMacFormatter)) (quote!(DisplayHint::UpperMac), quote!(UpperMacFormatter))
} }
DisplayHint::Pointer => {
(quote!(DisplayHint::Pointer), quote!(PointerFormatter))
}
}; };
let hint = quote!(::aya_log_ebpf::macro_support::#hint); let hint = quote!(::aya_log_ebpf::macro_support::#hint);
let arg = quote!( let arg = quote!(

@ -59,11 +59,12 @@ fn parse_param(input: &str) -> Result<Parameter, String> {
let hint = match input.strip_prefix(":") { let hint = match input.strip_prefix(":") {
Some(input) => match input { Some(input) => match input {
"" => return Err("malformed format string (missing display hint after ':')".into()), "" => return Err("malformed format string (missing display hint after ':')".into()),
"p" | "x" => DisplayHint::LowerHex, "x" => DisplayHint::LowerHex,
"X" => DisplayHint::UpperHex, "X" => DisplayHint::UpperHex,
"i" => DisplayHint::Ip, "i" => DisplayHint::Ip,
"mac" => DisplayHint::LowerMac, "mac" => DisplayHint::LowerMac,
"MAC" => DisplayHint::UpperMac, "MAC" => DisplayHint::UpperMac,
"p" => DisplayHint::Pointer,
input => return Err(format!("unknown display hint: {input:?}")), input => return Err(format!("unknown display hint: {input:?}")),
}, },
None => { None => {
@ -155,7 +156,7 @@ mod test {
}), }),
Fragment::Literal(" lmao {} {something} ".into()), Fragment::Literal(" lmao {} {something} ".into()),
Fragment::Parameter(Parameter { Fragment::Parameter(Parameter {
hint: DisplayHint::LowerHex hint: DisplayHint::Pointer
}), }),
]) ])
); );

@ -284,6 +284,19 @@ impl Formatter<[u8; 6]> for UpperMacFormatter {
} }
} }
pub struct PointerFormatter;
impl<T> Formatter<*const T> for PointerFormatter {
fn format(v: *const T) -> String {
format!("{v:p}")
}
}
impl<T> Formatter<*mut T> for PointerFormatter {
fn format(v: *mut T) -> String {
format!("{v:p}")
}
}
trait Format { trait Format {
fn format(&self, last_hint: Option<DisplayHintWrapper>) -> Result<String, ()>; fn format(&self, last_hint: Option<DisplayHintWrapper>) -> Result<String, ()>;
} }
@ -307,6 +320,7 @@ impl Format for u32 {
Some(DisplayHint::Ip) => Ok(Ipv4Formatter::format(*self)), Some(DisplayHint::Ip) => Ok(Ipv4Formatter::format(*self)),
Some(DisplayHint::LowerMac) => Err(()), Some(DisplayHint::LowerMac) => Err(()),
Some(DisplayHint::UpperMac) => Err(()), Some(DisplayHint::UpperMac) => Err(()),
Some(DisplayHint::Pointer) => Err(()),
None => Ok(DefaultFormatter::format(self)), None => Ok(DefaultFormatter::format(self)),
} }
} }
@ -321,6 +335,7 @@ impl Format for Ipv4Addr {
Some(DisplayHint::Ip) => Ok(Ipv4Formatter::format(*self)), Some(DisplayHint::Ip) => Ok(Ipv4Formatter::format(*self)),
Some(DisplayHint::LowerMac) => Err(()), Some(DisplayHint::LowerMac) => Err(()),
Some(DisplayHint::UpperMac) => Err(()), Some(DisplayHint::UpperMac) => Err(()),
Some(DisplayHint::Pointer) => Err(()),
None => Ok(Ipv4Formatter::format(*self)), None => Ok(Ipv4Formatter::format(*self)),
} }
} }
@ -335,6 +350,7 @@ impl Format for Ipv6Addr {
Some(DisplayHint::Ip) => Ok(Ipv6Formatter::format(*self)), Some(DisplayHint::Ip) => Ok(Ipv6Formatter::format(*self)),
Some(DisplayHint::LowerMac) => Err(()), Some(DisplayHint::LowerMac) => Err(()),
Some(DisplayHint::UpperMac) => Err(()), Some(DisplayHint::UpperMac) => Err(()),
Some(DisplayHint::Pointer) => Err(()),
None => Ok(Ipv6Formatter::format(*self)), None => Ok(Ipv6Formatter::format(*self)),
} }
} }
@ -349,6 +365,7 @@ impl Format for [u8; 4] {
Some(DisplayHint::Ip) => Ok(Ipv4Formatter::format(*self)), Some(DisplayHint::Ip) => Ok(Ipv4Formatter::format(*self)),
Some(DisplayHint::LowerMac) => Err(()), Some(DisplayHint::LowerMac) => Err(()),
Some(DisplayHint::UpperMac) => Err(()), Some(DisplayHint::UpperMac) => Err(()),
Some(DisplayHint::Pointer) => Err(()),
None => Ok(Ipv4Formatter::format(*self)), None => Ok(Ipv4Formatter::format(*self)),
} }
} }
@ -363,6 +380,7 @@ impl Format for [u8; 6] {
Some(DisplayHint::Ip) => Err(()), Some(DisplayHint::Ip) => Err(()),
Some(DisplayHint::LowerMac) => Ok(LowerMacFormatter::format(*self)), Some(DisplayHint::LowerMac) => Ok(LowerMacFormatter::format(*self)),
Some(DisplayHint::UpperMac) => Ok(UpperMacFormatter::format(*self)), Some(DisplayHint::UpperMac) => Ok(UpperMacFormatter::format(*self)),
Some(DisplayHint::Pointer) => Err(()),
None => Err(()), None => Err(()),
} }
} }
@ -377,6 +395,7 @@ impl Format for [u8; 16] {
Some(DisplayHint::Ip) => Ok(Ipv6Formatter::format(*self)), Some(DisplayHint::Ip) => Ok(Ipv6Formatter::format(*self)),
Some(DisplayHint::LowerMac) => Err(()), Some(DisplayHint::LowerMac) => Err(()),
Some(DisplayHint::UpperMac) => Err(()), Some(DisplayHint::UpperMac) => Err(()),
Some(DisplayHint::Pointer) => Err(()),
None => Err(()), None => Err(()),
} }
} }
@ -391,6 +410,7 @@ impl Format for [u16; 8] {
Some(DisplayHint::Ip) => Ok(Ipv6Formatter::format(*self)), Some(DisplayHint::Ip) => Ok(Ipv6Formatter::format(*self)),
Some(DisplayHint::LowerMac) => Err(()), Some(DisplayHint::LowerMac) => Err(()),
Some(DisplayHint::UpperMac) => Err(()), Some(DisplayHint::UpperMac) => Err(()),
Some(DisplayHint::Pointer) => Err(()),
None => Err(()), None => Err(()),
} }
} }
@ -407,6 +427,7 @@ macro_rules! impl_format {
Some(DisplayHint::Ip) => Err(()), Some(DisplayHint::Ip) => Err(()),
Some(DisplayHint::LowerMac) => Err(()), Some(DisplayHint::LowerMac) => Err(()),
Some(DisplayHint::UpperMac) => Err(()), Some(DisplayHint::UpperMac) => Err(()),
Some(DisplayHint::Pointer) => Err(()),
None => Ok(DefaultFormatter::format(self)), None => Ok(DefaultFormatter::format(self)),
} }
} }
@ -436,6 +457,7 @@ macro_rules! impl_format_float {
Some(DisplayHint::Ip) => Err(()), Some(DisplayHint::Ip) => Err(()),
Some(DisplayHint::LowerMac) => Err(()), Some(DisplayHint::LowerMac) => Err(()),
Some(DisplayHint::UpperMac) => Err(()), Some(DisplayHint::UpperMac) => Err(()),
Some(DisplayHint::Pointer) => Err(()),
None => Ok(DefaultFormatter::format(self)), None => Ok(DefaultFormatter::format(self)),
} }
} }
@ -446,6 +468,24 @@ macro_rules! impl_format_float {
impl_format_float!(f32); impl_format_float!(f32);
impl_format_float!(f64); impl_format_float!(f64);
impl<T> Format for *const T {
fn format(&self, last_hint: Option<DisplayHintWrapper>) -> Result<String, ()> {
match last_hint.map(|DisplayHintWrapper(dh)| dh) {
Some(DisplayHint::Pointer) => Ok(PointerFormatter::format(*self)),
_ => Err(()),
}
}
}
impl<T> Format for *mut T {
fn format(&self, last_hint: Option<DisplayHintWrapper>) -> Result<String, ()> {
match last_hint.map(|DisplayHintWrapper(dh)| dh) {
Some(DisplayHint::Pointer) => Ok(PointerFormatter::format(*self)),
_ => Err(()),
}
}
}
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum Error { pub enum Error {
#[error("{} not found", MAP_NAME)] #[error("{} not found", MAP_NAME)]
@ -732,6 +772,13 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
} }
Err(e) => error!("received invalid utf8 string: {e}"), Err(e) => error!("received invalid utf8 string: {e}"),
}, },
ArgumentKind::Pointer => {
let value = value
.try_into()
.map_err(|std::array::TryFromSliceError { .. }| ())?;
let ptr = usize::from_ne_bytes(value) as *const ();
full_log_msg.push_str(&ptr.format(last_hint.take())?);
}
} }
buf = rest; buf = rest;

@ -14,7 +14,8 @@ pub mod macro_support {
use aya_ebpf::maps::RingBuf; use aya_ebpf::maps::RingBuf;
pub use aya_log_common::{ pub use aya_log_common::{
Argument, DefaultFormatter, DisplayHint, Field, Header, IpFormatter, Level, LogValueLength, Argument, DefaultFormatter, DisplayHint, Field, Header, IpFormatter, Level, LogValueLength,
LowerHexFormatter, LowerMacFormatter, UpperHexFormatter, UpperMacFormatter, LowerHexFormatter, LowerMacFormatter, PointerFormatter, UpperHexFormatter,
UpperMacFormatter,
}; };
// This cfg_attr prevents compilation failures on macOS where the generated section name doesn't // This cfg_attr prevents compilation failures on macOS where the generated section name doesn't

@ -89,6 +89,8 @@ fn test_log(ctx: ProbeContext) {
&ctx, &ctx,
"{} {} {} {} {} {} {}", header, tmp, kind, value, size, op, buf "{} {} {} {} {} {} {}", header, tmp, kind, value, size, op, buf
); );
let ptr = 0xdeadbeef as *const u8;
debug!(&ctx, "ptr: {:p}", ptr);
// Testing compilation only. // Testing compilation only.
if false { if false {

@ -187,6 +187,15 @@ fn log() {
}) })
); );
assert_eq!(
records.next(),
Some(&CapturedLog {
body: "ptr: 0xdeadbeef".into(),
level: Level::Debug,
target: "log".into(),
})
);
assert_eq!( assert_eq!(
records.next(), records.next(),
Some(&CapturedLog { Some(&CapturedLog {

@ -15,6 +15,7 @@ pub aya_log_common::ArgumentKind::I8
pub aya_log_common::ArgumentKind::Ipv4Addr pub aya_log_common::ArgumentKind::Ipv4Addr
pub aya_log_common::ArgumentKind::Ipv6Addr pub aya_log_common::ArgumentKind::Ipv6Addr
pub aya_log_common::ArgumentKind::Isize pub aya_log_common::ArgumentKind::Isize
pub aya_log_common::ArgumentKind::Pointer
pub aya_log_common::ArgumentKind::Str pub aya_log_common::ArgumentKind::Str
pub aya_log_common::ArgumentKind::U16 pub aya_log_common::ArgumentKind::U16
pub aya_log_common::ArgumentKind::U32 pub aya_log_common::ArgumentKind::U32
@ -57,6 +58,7 @@ pub aya_log_common::DisplayHint::Default = 1
pub aya_log_common::DisplayHint::Ip pub aya_log_common::DisplayHint::Ip
pub aya_log_common::DisplayHint::LowerHex pub aya_log_common::DisplayHint::LowerHex
pub aya_log_common::DisplayHint::LowerMac pub aya_log_common::DisplayHint::LowerMac
pub aya_log_common::DisplayHint::Pointer
pub aya_log_common::DisplayHint::UpperHex pub aya_log_common::DisplayHint::UpperHex
pub aya_log_common::DisplayHint::UpperMac pub aya_log_common::DisplayHint::UpperMac
impl aya_log_common::Argument for aya_log_common::DisplayHint impl aya_log_common::Argument for aya_log_common::DisplayHint
@ -215,6 +217,10 @@ impl aya_log_common::Argument for u8
pub fn u8::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) pub fn u8::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>)
impl aya_log_common::Argument for usize impl aya_log_common::Argument for usize
pub fn usize::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) pub fn usize::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>)
impl<T> aya_log_common::Argument for *const T
pub fn *const T::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>)
impl<T> aya_log_common::Argument for *mut T
pub fn *mut T::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>)
impl<const N: usize> aya_log_common::Argument for [u8; N] impl<const N: usize> aya_log_common::Argument for [u8; N]
pub fn [u8; N]::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) pub fn [u8; N]::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>)
pub trait aya_log_common::DefaultFormatter pub trait aya_log_common::DefaultFormatter
@ -260,6 +266,9 @@ impl aya_log_common::LowerHexFormatter for usize
impl<const N: usize> aya_log_common::LowerHexFormatter for &[u8; N] impl<const N: usize> aya_log_common::LowerHexFormatter for &[u8; N]
pub trait aya_log_common::LowerMacFormatter pub trait aya_log_common::LowerMacFormatter
impl aya_log_common::LowerMacFormatter for [u8; 6] impl aya_log_common::LowerMacFormatter for [u8; 6]
pub trait aya_log_common::PointerFormatter
impl<T> aya_log_common::PointerFormatter for *const T
impl<T> aya_log_common::PointerFormatter for *mut T
pub trait aya_log_common::UpperHexFormatter pub trait aya_log_common::UpperHexFormatter
impl aya_log_common::UpperHexFormatter for &[u8] impl aya_log_common::UpperHexFormatter for &[u8]
impl aya_log_common::UpperHexFormatter for i16 impl aya_log_common::UpperHexFormatter for i16

@ -223,6 +223,33 @@ impl<T> core::borrow::BorrowMut<T> for aya_log::LowerMacFormatter where T: ?core
pub fn aya_log::LowerMacFormatter::borrow_mut(&mut self) -> &mut T pub fn aya_log::LowerMacFormatter::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_log::LowerMacFormatter impl<T> core::convert::From<T> for aya_log::LowerMacFormatter
pub fn aya_log::LowerMacFormatter::from(t: T) -> T pub fn aya_log::LowerMacFormatter::from(t: T) -> T
pub struct aya_log::PointerFormatter
impl<T> aya_log::Formatter<*const T> for aya_log::PointerFormatter
pub fn aya_log::PointerFormatter::format(v: *const T) -> alloc::string::String
impl<T> aya_log::Formatter<*mut T> for aya_log::PointerFormatter
pub fn aya_log::PointerFormatter::format(v: *mut T) -> alloc::string::String
impl core::marker::Freeze for aya_log::PointerFormatter
impl core::marker::Send for aya_log::PointerFormatter
impl core::marker::Sync for aya_log::PointerFormatter
impl core::marker::Unpin for aya_log::PointerFormatter
impl core::panic::unwind_safe::RefUnwindSafe for aya_log::PointerFormatter
impl core::panic::unwind_safe::UnwindSafe for aya_log::PointerFormatter
impl<T, U> core::convert::Into<U> for aya_log::PointerFormatter where U: core::convert::From<T>
pub fn aya_log::PointerFormatter::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_log::PointerFormatter where U: core::convert::Into<T>
pub type aya_log::PointerFormatter::Error = core::convert::Infallible
pub fn aya_log::PointerFormatter::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_log::PointerFormatter where U: core::convert::TryFrom<T>
pub type aya_log::PointerFormatter::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_log::PointerFormatter::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya_log::PointerFormatter where T: 'static + ?core::marker::Sized
pub fn aya_log::PointerFormatter::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_log::PointerFormatter where T: ?core::marker::Sized
pub fn aya_log::PointerFormatter::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_log::PointerFormatter where T: ?core::marker::Sized
pub fn aya_log::PointerFormatter::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_log::PointerFormatter
pub fn aya_log::PointerFormatter::from(t: T) -> T
pub struct aya_log::UpperHexBytesFormatter pub struct aya_log::UpperHexBytesFormatter
impl aya_log::Formatter<&[u8]> for aya_log::UpperHexBytesFormatter impl aya_log::Formatter<&[u8]> for aya_log::UpperHexBytesFormatter
pub fn aya_log::UpperHexBytesFormatter::format(v: &[u8]) -> alloc::string::String pub fn aya_log::UpperHexBytesFormatter::format(v: &[u8]) -> alloc::string::String
@ -309,6 +336,10 @@ impl aya_log::Formatter<[u8; 6]> for aya_log::LowerMacFormatter
pub fn aya_log::LowerMacFormatter::format(v: [u8; 6]) -> alloc::string::String pub fn aya_log::LowerMacFormatter::format(v: [u8; 6]) -> alloc::string::String
impl aya_log::Formatter<[u8; 6]> for aya_log::UpperMacFormatter impl aya_log::Formatter<[u8; 6]> for aya_log::UpperMacFormatter
pub fn aya_log::UpperMacFormatter::format(v: [u8; 6]) -> alloc::string::String pub fn aya_log::UpperMacFormatter::format(v: [u8; 6]) -> alloc::string::String
impl<T> aya_log::Formatter<*const T> for aya_log::PointerFormatter
pub fn aya_log::PointerFormatter::format(v: *const T) -> alloc::string::String
impl<T> aya_log::Formatter<*mut T> for aya_log::PointerFormatter
pub fn aya_log::PointerFormatter::format(v: *mut T) -> alloc::string::String
impl<T> aya_log::Formatter<T> for aya_log::DefaultFormatter where T: alloc::string::ToString impl<T> aya_log::Formatter<T> for aya_log::DefaultFormatter where T: alloc::string::ToString
pub fn aya_log::DefaultFormatter::format(v: T) -> alloc::string::String pub fn aya_log::DefaultFormatter::format(v: T) -> alloc::string::String
impl<T> aya_log::Formatter<T> for aya_log::Ipv4Formatter where T: core::convert::Into<core::net::ip_addr::Ipv4Addr> impl<T> aya_log::Formatter<T> for aya_log::Ipv4Formatter where T: core::convert::Into<core::net::ip_addr::Ipv4Addr>

Loading…
Cancel
Save