diff --git a/Cargo.toml b/Cargo.toml index a4a09f13a8..a78c9bb031 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -136,6 +136,8 @@ todo = "warn" unimplemented = "warn" unreachable = "warn" panic_in_result_fn = "warn" +std_instead_of_alloc = "warn" +std_instead_of_core = "warn" # TODO: Re-enable once every crate defines package keywords and categories. cargo_common_metadata = "allow" # TODO: Re-enable once the workspace dependency graph is deduplicated. diff --git a/libdd-common-ffi/Cargo.toml b/libdd-common-ffi/Cargo.toml index b7900a339d..0de874f611 100644 --- a/libdd-common-ffi/Cargo.toml +++ b/libdd-common-ffi/Cargo.toml @@ -32,3 +32,7 @@ serde = "1.0" bolero = "0.13" assert_no_alloc = "1.1.2" function_name = "0.3.0" + +[lints.clippy] +std_instead_of_alloc = "warn" +std_instead_of_core = "warn" diff --git a/libdd-common-ffi/src/array_queue.rs b/libdd-common-ffi/src/array_queue.rs index 17f3334430..3427d42c50 100644 --- a/libdd-common-ffi/src/array_queue.rs +++ b/libdd-common-ffi/src/array_queue.rs @@ -3,7 +3,7 @@ use crate::Error; use anyhow::Context; -use std::{ffi::c_void, ptr::NonNull}; +use core::{ffi::c_void, ptr::NonNull}; #[derive(Debug)] #[repr(C)] @@ -300,11 +300,11 @@ pub unsafe extern "C" fn ddog_ArrayQueue_capacity(queue_ptr: &ArrayQueue) -> Arr mod tests { use super::*; use bolero::TypeGenerator; - use std::sync::atomic::{AtomicUsize, Ordering}; + use core::sync::atomic::{AtomicUsize, Ordering}; unsafe extern "C" fn drop_item(item: *mut c_void) -> c_void { _ = Box::from_raw(item as *mut i32); - std::mem::zeroed() + core::mem::zeroed() } #[test] @@ -313,7 +313,7 @@ mod tests { assert!(matches!(queue_new_result, ArrayQueueNewResult::Ok(_))); let queue_ptr = match queue_new_result { ArrayQueueNewResult::Ok(ptr) => ptr.as_ptr(), - _ => std::ptr::null_mut(), + _ => core::ptr::null_mut(), }; let item = Box::new(1i32); let item_ptr = Box::into_raw(item); @@ -335,7 +335,7 @@ mod tests { ); let item_ptr = match result { ArrayQueuePopResult::Ok(ptr) => ptr, - _ => std::ptr::null_mut(), + _ => core::ptr::null_mut(), }; drop(Box::from_raw(item_ptr as *mut i32)); let result = ddog_ArrayQueue_push(queue, item3_ptr as *mut c_void); @@ -438,7 +438,7 @@ mod tests { assert!(matches!(queue_new_result, ArrayQueueNewResult::Ok(_))); let queue_ptr = match queue_new_result { ArrayQueueNewResult::Ok(ptr) => ptr.as_ptr(), - _ => std::ptr::null_mut(), + _ => core::ptr::null_mut(), }; let queue = unsafe { &*queue_ptr }; diff --git a/libdd-common-ffi/src/cstr.rs b/libdd-common-ffi/src/cstr.rs index 0e09516f9e..89fb12efc2 100644 --- a/libdd-common-ffi/src/cstr.rs +++ b/libdd-common-ffi/src/cstr.rs @@ -1,8 +1,11 @@ // Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use alloc::ffi::{CString as AllocCString, NulError}; +use alloc::vec::Vec; +use core::ffi::CStr as CoreCStr; use core::fmt; -use std::{ +use core::{ ffi::c_char, marker::PhantomData, mem::{self, ManuallyDrop}, @@ -17,21 +20,21 @@ pub struct CStr<'a> { ptr: ptr::NonNull, /// Length of the array, not counting the null-terminator length: usize, - _lifetime_marker: std::marker::PhantomData<&'a c_char>, + _lifetime_marker: core::marker::PhantomData<&'a c_char>, } impl<'a> CStr<'a> { - pub fn from_std(s: &'a std::ffi::CStr) -> Self { + pub fn from_std(s: &'a CoreCStr) -> Self { Self { ptr: unsafe { ptr::NonNull::new_unchecked(s.as_ptr().cast_mut()) }, length: s.to_bytes().len(), - _lifetime_marker: std::marker::PhantomData, + _lifetime_marker: core::marker::PhantomData, } } - pub fn into_std(&self) -> &'a std::ffi::CStr { + pub fn into_std(&self) -> &'a CoreCStr { unsafe { - std::ffi::CStr::from_bytes_with_nul_unchecked(std::slice::from_raw_parts( + CoreCStr::from_bytes_with_nul_unchecked(core::slice::from_raw_parts( self.ptr.as_ptr().cast_const().cast(), self.length + 1, )) @@ -56,8 +59,8 @@ impl fmt::Debug for CString { } impl CString { - pub fn new>>(t: T) -> Result { - Ok(Self::from_std(std::ffi::CString::new(t)?)) + pub fn new>>(t: T) -> Result { + Ok(Self::from_std(AllocCString::new(t)?)) } /// Creates a new `CString` from the given input, or returns an empty `CString` @@ -99,7 +102,7 @@ impl CString { } } - pub fn from_std(s: std::ffi::CString) -> Self { + pub fn from_std(s: AllocCString) -> Self { let length = s.to_bytes().len(); Self { ptr: unsafe { ptr::NonNull::new_unchecked(s.into_raw()) }, @@ -107,10 +110,10 @@ impl CString { } } - pub fn into_std(self) -> std::ffi::CString { + pub fn into_std(self) -> AllocCString { let s = ManuallyDrop::new(self); unsafe { - std::ffi::CString::from_vec_with_nul_unchecked(Vec::from_raw_parts( + AllocCString::from_vec_with_nul_unchecked(Vec::from_raw_parts( s.ptr.as_ptr().cast(), s.length + 1, // +1 for the null terminator s.length + 1, // +1 for the null terminator @@ -123,7 +126,7 @@ impl Drop for CString { fn drop(&mut self) { let ptr = mem::replace(&mut self.ptr, NonNull::dangling()); drop(unsafe { - std::ffi::CString::from_vec_with_nul_unchecked(Vec::from_raw_parts( + AllocCString::from_vec_with_nul_unchecked(Vec::from_raw_parts( ptr.as_ptr().cast(), self.length + 1, self.length + 1, @@ -138,7 +141,7 @@ mod tests { #[test] fn test_cstr() { - let s = std::ffi::CString::new("hello").unwrap(); + let s = AllocCString::new("hello").unwrap(); let cstr = CStr::from_std(&s); assert_eq!(cstr.into_std().to_str().unwrap(), "hello"); } diff --git a/libdd-common-ffi/src/endpoint.rs b/libdd-common-ffi/src/endpoint.rs index d79fdce4f3..4e2f1fdbc4 100644 --- a/libdd-common-ffi/src/endpoint.rs +++ b/libdd-common-ffi/src/endpoint.rs @@ -3,10 +3,10 @@ use crate::slice::AsBytes; use crate::Error; +use alloc::borrow::Cow; +use core::str::FromStr; use hyper::http::uri::{Authority, Parts}; use libdd_common::{parse_uri, Endpoint}; -use std::borrow::Cow; -use std::str::FromStr; #[no_mangle] #[must_use] diff --git a/libdd-common-ffi/src/error.rs b/libdd-common-ffi/src/error.rs index ab5f1cc212..74eb6e67fe 100644 --- a/libdd-common-ffi/src/error.rs +++ b/libdd-common-ffi/src/error.rs @@ -3,7 +3,7 @@ use crate::slice::{AsBytes, CharSlice}; use crate::vec::Vec; -use std::fmt::{Debug, Display, Formatter}; +use core::fmt::{Debug, Display, Formatter}; /// You probably don't want to use this directly. This constant is used by `handle_panic_error` to /// signal that something went wrong, but avoid needing any allocations to represent it. @@ -15,7 +15,7 @@ pub(crate) const CANNOT_ALLOCATE_ERROR: Error = Error { // This error message is used as a placeholder for errors without message -- corresponding to an // error where we couldn't even _allocate_ the message (or some other even weirder error). -const CANNOT_ALLOCATE: &std::ffi::CStr = +const CANNOT_ALLOCATE: &core::ffi::CStr = c"libdatadog failed: (panic) Cannot allocate error message"; const CANNOT_ALLOCATE_CHAR_SLICE: CharSlice = unsafe { crate::Slice::from_raw_parts(CANNOT_ALLOCATE.as_ptr(), CANNOT_ALLOCATE.to_bytes().len()) @@ -40,18 +40,18 @@ impl AsRef for Error { } impl Display for Error { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { f.write_str(self.as_ref()) } } impl Debug for Error { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { f.write_fmt(format_args!("Error(\"{}\")", self.as_ref())) } } -impl std::error::Error for Error {} +impl core::error::Error for Error {} impl From for Error { fn from(value: String) -> Self { @@ -63,7 +63,7 @@ impl From for Error { impl From for String { fn from(mut value: Error) -> String { let mut vec = Vec::default(); - std::mem::swap(&mut vec, &mut value.message); + core::mem::swap(&mut vec, &mut value.message); // Safety: .message is a String (just FFI safe). unsafe { String::from_utf8_unchecked(vec.into()) } } @@ -83,8 +83,8 @@ impl From for Error { } } -impl From> for Error { - fn from(value: Box<&dyn std::error::Error>) -> Self { +impl From> for Error { + fn from(value: Box<&dyn core::error::Error>) -> Self { Self::from(value.to_string()) } } diff --git a/libdd-common-ffi/src/handle.rs b/libdd-common-ffi/src/handle.rs index 25a19b59b0..7716ab7253 100644 --- a/libdd-common-ffi/src/handle.rs +++ b/libdd-common-ffi/src/handle.rs @@ -1,7 +1,7 @@ // Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 -use std::ptr::null_mut; +use core::ptr::null_mut; use anyhow::Context; @@ -48,7 +48,7 @@ impl ToInner for Handle { unsafe fn take(&mut self) -> anyhow::Result> { // Leaving a null will help with double-free issues that can arise in C. // Of course, it's best to never get there in the first place! - let raw = std::mem::replace(&mut self.inner, std::ptr::null_mut()); + let raw = core::mem::replace(&mut self.inner, core::ptr::null_mut()); anyhow::ensure!( !raw.is_null(), "inner pointer was null, indicates use after free" diff --git a/libdd-common-ffi/src/lib.rs b/libdd-common-ffi/src/lib.rs index 0fdb04b4be..c5ec15142c 100644 --- a/libdd-common-ffi/src/lib.rs +++ b/libdd-common-ffi/src/lib.rs @@ -6,6 +6,8 @@ #![cfg_attr(not(test), deny(clippy::todo))] #![cfg_attr(not(test), deny(clippy::unimplemented))] +extern crate alloc; + mod error; pub mod array_queue; diff --git a/libdd-common-ffi/src/option.rs b/libdd-common-ffi/src/option.rs index 9c3eb9fb5f..29cb572969 100644 --- a/libdd-common-ffi/src/option.rs +++ b/libdd-common-ffi/src/option.rs @@ -1,7 +1,7 @@ // Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 -use std::fmt::Debug; +use core::fmt::Debug; #[repr(C)] #[derive(Debug, PartialEq, Eq)] @@ -12,11 +12,11 @@ pub enum Option { } impl Option { - pub fn to_std(self) -> std::option::Option { + pub fn to_std(self) -> core::option::Option { self.into() } - pub fn to_std_ref(&self) -> std::option::Option<&T> { + pub fn to_std_ref(&self) -> core::option::Option<&T> { match self { Option::Some(ref s) => Some(s), Option::None => None, @@ -43,7 +43,7 @@ impl Option { } } -impl From> for std::option::Option { +impl From> for core::option::Option { fn from(o: Option) -> Self { match o { Option::Some(s) => Some(s), @@ -52,8 +52,8 @@ impl From> for std::option::Option { } } -impl From> for Option { - fn from(o: std::option::Option) -> Self { +impl From> for Option { + fn from(o: core::option::Option) -> Self { match o { Some(s) => Option::Some(s), None => Option::None, @@ -61,7 +61,7 @@ impl From> for Option { } } -impl From<&Option> for std::option::Option { +impl From<&Option> for core::option::Option { fn from(o: &Option) -> Self { match o { Option::Some(s) => Some(*s), diff --git a/libdd-common-ffi/src/slice.rs b/libdd-common-ffi/src/slice.rs index a703188e1b..58ecf96250 100644 --- a/libdd-common-ffi/src/slice.rs +++ b/libdd-common-ffi/src/slice.rs @@ -1,16 +1,16 @@ // Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use alloc::borrow::Cow; +use core::ffi::c_char; +use core::fmt::{Debug, Display, Formatter}; +use core::hash::{Hash, Hasher}; +use core::marker::PhantomData; use core::slice; +use core::str::Utf8Error; use libdd_common::error::FfiSafeErrorMessage; use serde::ser::Error; use serde::Serializer; -use std::borrow::Cow; -use std::fmt::{Debug, Display, Formatter}; -use std::hash::{Hash, Hasher}; -use std::marker::PhantomData; -use std::os::raw::c_char; -use std::str::Utf8Error; #[repr(C)] #[derive(Clone, Copy, Debug)] @@ -37,7 +37,7 @@ pub struct Slice<'a, T: 'a> { /// # Safety /// All strings are valid UTF-8 (enforced by using c-str literals in Rust). unsafe impl FfiSafeErrorMessage for SliceConversionError { - fn as_ffi_str(&self) -> &'static std::ffi::CStr { + fn as_ffi_str(&self) -> &'static core::ffi::CStr { match self { SliceConversionError::LargeLength => c"length was too large", SliceConversionError::NullPointer => c"null pointer with non-zero length", @@ -46,7 +46,7 @@ unsafe impl FfiSafeErrorMessage for SliceConversionError { } } impl Display for SliceConversionError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { Display::fmt(self.as_rust_str(), f) } } @@ -62,7 +62,7 @@ impl<'a, T: 'a> core::ops::Deref for Slice<'a, T> { } impl Debug for Slice<'_, T> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { self.as_slice().fmt(f) } } @@ -106,7 +106,7 @@ pub trait AsBytes<'a> { #[inline] fn try_to_utf8(&self) -> Result<&'a str, Utf8Error> { - std::str::from_utf8(self.as_bytes()) + core::str::from_utf8(self.as_bytes()) } fn try_to_string(&self) -> Result { @@ -127,7 +127,7 @@ pub trait AsBytes<'a> { /// # Safety /// Must only be used when the underlying data was already confirmed to be utf8. unsafe fn assume_utf8(&self) -> &'a str { - std::str::from_utf8_unchecked(self.as_bytes()) + core::str::from_utf8_unchecked(self.as_bytes()) } } @@ -276,8 +276,8 @@ impl<'a, T> Display for Slice<'a, T> where Slice<'a, T>: AsBytes<'a>, { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.try_to_utf8().map_err(|_| std::fmt::Error)?) + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.try_to_utf8().map_err(|_| core::fmt::Error)?) } } @@ -322,8 +322,8 @@ impl<'a> CharSlice<'a> { #[cfg(test)] mod tests { use super::*; + use core::ptr; use std::os::raw::c_char; - use std::ptr; #[test] fn slice_from_into_slice() { diff --git a/libdd-common-ffi/src/slice_mut.rs b/libdd-common-ffi/src/slice_mut.rs index 60bea136f2..d87df1795b 100644 --- a/libdd-common-ffi/src/slice_mut.rs +++ b/libdd-common-ffi/src/slice_mut.rs @@ -2,14 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 use crate::slice::{AsBytes, SliceConversionError}; +use core::fmt::{Debug, Display, Formatter}; +use core::hash::{Hash, Hasher}; +use core::marker::PhantomData; +use core::ptr::NonNull; use core::slice; use serde::ser::Error; use serde::Serializer; -use std::fmt::{Debug, Display, Formatter}; -use std::hash::{Hash, Hasher}; -use std::marker::PhantomData; use std::os::raw::c_char; -use std::ptr::NonNull; #[repr(C)] #[derive(Copy, Clone)] @@ -34,7 +34,7 @@ impl<'a, T: 'a> core::ops::Deref for MutSlice<'a, T> { } impl Debug for MutSlice<'_, T> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { self.as_slice().fmt(f) } } @@ -175,8 +175,8 @@ impl<'a, T> Display for MutSlice<'a, T> where MutSlice<'a, T>: AsBytes<'a>, { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.try_to_utf8().map_err(|_| std::fmt::Error)?) + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.try_to_utf8().map_err(|_| core::fmt::Error)?) } } @@ -202,7 +202,7 @@ impl<'a> From<&'a mut str> for MutSlice<'a, c_char> { #[cfg(test)] mod tests { use super::*; - use std::ptr; + use core::ptr; #[derive(Debug, Eq, PartialEq)] struct Foo(i64); diff --git a/libdd-common-ffi/src/string.rs b/libdd-common-ffi/src/string.rs index 21090f45bf..53762a63cb 100644 --- a/libdd-common-ffi/src/string.rs +++ b/libdd-common-ffi/src/string.rs @@ -29,7 +29,7 @@ impl From for StringWrapper { impl From for String { fn from(mut value: StringWrapper) -> Self { - let msg = std::mem::take(&mut value.message); + let msg = core::mem::take(&mut value.message); #[allow(clippy::unwrap_used)] String::from_utf8(msg.into()).unwrap() } diff --git a/libdd-common-ffi/src/timespec.rs b/libdd-common-ffi/src/timespec.rs index a490845c31..a86ba0ad06 100644 --- a/libdd-common-ffi/src/timespec.rs +++ b/libdd-common-ffi/src/timespec.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use chrono::{DateTime, TimeZone, Utc}; -use std::fmt::Debug; +use core::fmt::Debug; use std::time::SystemTime; /// Represents time since the Unix Epoch in seconds plus nanoseconds. diff --git a/libdd-common-ffi/src/utils.rs b/libdd-common-ffi/src/utils.rs index ee3f6f61ca..10251b7305 100644 --- a/libdd-common-ffi/src/utils.rs +++ b/libdd-common-ffi/src/utils.rs @@ -1,7 +1,8 @@ // Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 -use std::panic::{catch_unwind, AssertUnwindSafe}; +use core::panic::AssertUnwindSafe; +use std::panic::catch_unwind; /// Wraps a C-FFI function in standard form /// Expects the function to return a result type that implements into and to be decorated with @@ -9,7 +10,8 @@ use std::panic::{catch_unwind, AssertUnwindSafe}; #[macro_export] macro_rules! wrap_with_ffi_result { ($body:block) => {{ - use std::panic::{catch_unwind, AssertUnwindSafe}; + use core::panic::AssertUnwindSafe; + use std::panic::catch_unwind; catch_unwind(AssertUnwindSafe(|| { $crate::wrap_with_ffi_result_no_catch!({ $body }) @@ -38,7 +40,8 @@ macro_rules! wrap_with_ffi_result_no_catch { #[macro_export] macro_rules! wrap_with_void_ffi_result { ($body:block) => {{ - use std::panic::{catch_unwind, AssertUnwindSafe}; + use core::panic::AssertUnwindSafe; + use std::panic::catch_unwind; catch_unwind(AssertUnwindSafe(|| { $crate::wrap_with_void_ffi_result_no_catch!({ $body }) @@ -80,7 +83,7 @@ impl ToHexStr for usize { /// being unable to allocate, this helper handles failures to allocate as well, turning them into a /// fallback error. pub fn handle_panic_error( - error: Box, + error: Box, function_name: &str, ) -> crate::Error { catch_unwind(AssertUnwindSafe(|| { @@ -112,7 +115,7 @@ mod tests { #[test] fn test_handle_panic_error_fallback_does_not_allocate() { - let mut error_result_buffer: [std::os::raw::c_char; 100] = [0; 100]; + let mut error_result_buffer: [core::ffi::c_char; 100] = [0; 100]; assert_no_alloc(|| { // Simulate fallback code path of handle_panic_error + ddog_Error_message @@ -125,7 +128,7 @@ mod tests { }); unsafe { - let c_str = std::ffi::CStr::from_ptr(error_result_buffer.as_ptr()); + let c_str = core::ffi::CStr::from_ptr(error_result_buffer.as_ptr()); assert_eq!( c_str.to_str().unwrap(), "libdatadog failed: (panic) Cannot allocate error message" diff --git a/libdd-common-ffi/src/vec.rs b/libdd-common-ffi/src/vec.rs index 1635b0c7b3..e67107ad6f 100644 --- a/libdd-common-ffi/src/vec.rs +++ b/libdd-common-ffi/src/vec.rs @@ -4,10 +4,10 @@ extern crate alloc; use crate::slice::Slice; +use core::marker::PhantomData; +use core::mem::ManuallyDrop; use core::ops::Deref; -use std::marker::PhantomData; -use std::mem::ManuallyDrop; -use std::ptr::NonNull; +use core::ptr::NonNull; /// Holds the raw parts of a Rust Vec; it should only be created from Rust, /// never from C. @@ -97,7 +97,7 @@ impl<'a, T> IntoIterator for &'a Vec { } impl Vec { - fn replace(&mut self, mut vec: ManuallyDrop>) { + fn replace(&mut self, mut vec: ManuallyDrop>) { self.ptr = vec.as_mut_ptr(); self.len = vec.len(); self.capacity = vec.capacity(); diff --git a/libdd-common/Cargo.toml b/libdd-common/Cargo.toml index 7f3e66d55f..b7e19beadf 100644 --- a/libdd-common/Cargo.toml +++ b/libdd-common/Cargo.toml @@ -123,3 +123,7 @@ bench-utils = ["dep:criterion"] # normal environments, so we need to let the rust linter know that it is in # fact a real thing, though one that shows up only in some situations. unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage)'] } + +[lints.clippy] +std_instead_of_alloc = "warn" +std_instead_of_core = "warn" diff --git a/libdd-common/src/azure_app_services.rs b/libdd-common/src/azure_app_services.rs index 456e6ea6b0..1672fc10a4 100644 --- a/libdd-common/src/azure_app_services.rs +++ b/libdd-common/src/azure_app_services.rs @@ -89,7 +89,7 @@ fn read_proc_self_environ() -> HashMap { if entry.is_empty() { continue; } - let s = match std::str::from_utf8(entry) { + let s = match core::str::from_utf8(entry) { Ok(s) => s, Err(_) => continue, }; diff --git a/libdd-common/src/bench_utils.rs b/libdd-common/src/bench_utils.rs index 17337f6cd9..fc1e9ee413 100644 --- a/libdd-common/src/bench_utils.rs +++ b/libdd-common/src/bench_utils.rs @@ -7,11 +7,8 @@ #![allow(missing_docs)] -use std::{ - alloc::{GlobalAlloc, System}, - cell::Cell, - time::Duration, -}; +use core::{alloc::GlobalAlloc, cell::Cell, time::Duration}; +use std::alloc::System; use criterion::{Criterion, Throughput}; @@ -46,16 +43,16 @@ struct AllocStats { pub struct ReportingAllocator { alloc: T, - allocated_bytes: std::sync::atomic::AtomicUsize, - allocations: std::sync::atomic::AtomicUsize, + allocated_bytes: core::sync::atomic::AtomicUsize, + allocations: core::sync::atomic::AtomicUsize, } impl ReportingAllocator { pub const fn new(alloc: T) -> Self { Self { alloc, - allocated_bytes: std::sync::atomic::AtomicUsize::new(0), - allocations: std::sync::atomic::AtomicUsize::new(0), + allocated_bytes: core::sync::atomic::AtomicUsize::new(0), + allocations: core::sync::atomic::AtomicUsize::new(0), } } @@ -63,22 +60,22 @@ impl ReportingAllocator { AllocStats { allocated_bytes: self .allocated_bytes - .load(std::sync::atomic::Ordering::Relaxed), - allocations: self.allocations.load(std::sync::atomic::Ordering::Relaxed), + .load(core::sync::atomic::Ordering::Relaxed), + allocations: self.allocations.load(core::sync::atomic::Ordering::Relaxed), } } } unsafe impl GlobalAlloc for ReportingAllocator { - unsafe fn alloc(&self, layout: std::alloc::Layout) -> *mut u8 { + unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 { self.allocated_bytes - .fetch_add(layout.size(), std::sync::atomic::Ordering::Relaxed); + .fetch_add(layout.size(), core::sync::atomic::Ordering::Relaxed); self.allocations - .fetch_add(1, std::sync::atomic::Ordering::Relaxed); + .fetch_add(1, core::sync::atomic::Ordering::Relaxed); self.alloc.alloc(layout) } - unsafe fn dealloc(&self, ptr: *mut u8, layout: std::alloc::Layout) { + unsafe fn dealloc(&self, ptr: *mut u8, layout: core::alloc::Layout) { self.alloc.dealloc(ptr, layout); } } @@ -169,8 +166,9 @@ impl criterion::measurement::ValueFormatter for AllocationFormatter { #[cfg(test)] mod tests { use super::*; + use core::alloc::{GlobalAlloc, Layout}; use criterion::measurement::{Measurement, ValueFormatter}; - use std::alloc::{GlobalAlloc, Layout, System}; + use std::alloc::System; static SHARED: ReportingAllocator = ReportingAllocator::new(System); diff --git a/libdd-common/src/config.rs b/libdd-common/src/config.rs index 0019fd6b46..fe88c0f248 100644 --- a/libdd-common/src/config.rs +++ b/libdd-common/src/config.rs @@ -2,8 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 pub mod parse_env { + use core::{str::FromStr, time::Duration}; use http::Uri; - use std::{env, str::FromStr, time::Duration}; + use std::env; use crate::parse_uri; diff --git a/libdd-common/src/connector/conn_stream.rs b/libdd-common/src/connector/conn_stream.rs index 03e222c720..f7594b1983 100644 --- a/libdd-common/src/connector/conn_stream.rs +++ b/libdd-common/src/connector/conn_stream.rs @@ -1,7 +1,7 @@ // Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 -use std::{ +use core::{ pin::Pin, task::{Context, Poll}, }; @@ -35,7 +35,7 @@ pub enum ConnStream { }, } -pub type ConnStreamError = Box; +pub type ConnStreamError = Box; use hyper_util::client::legacy::connect::{self, HttpConnector}; use hyper_util::rt::TokioIo; diff --git a/libdd-common/src/connector/errors.rs b/libdd-common/src/connector/errors.rs index 2194856cef..2d3a6de6c4 100644 --- a/libdd-common/src/connector/errors.rs +++ b/libdd-common/src/connector/errors.rs @@ -1,8 +1,8 @@ // Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use alloc::fmt; use std::error; -use std::fmt; #[derive(Clone, Debug, PartialEq, Eq)] pub enum Error { diff --git a/libdd-common/src/connector/mod.rs b/libdd-common/src/connector/mod.rs index d3ac71f894..8647f8e71d 100644 --- a/libdd-common/src/connector/mod.rs +++ b/libdd-common/src/connector/mod.rs @@ -5,10 +5,10 @@ use futures::future::BoxFuture; use futures::{future, FutureExt}; use hyper_util::client::legacy::connect; -use std::future::Future; -use std::pin::Pin; +use core::future::Future; +use core::pin::Pin; +use core::task::{Context, Poll}; use std::sync::LazyLock; -use std::task::{Context, Poll}; #[cfg(unix)] pub mod uds; diff --git a/libdd-common/src/cstr.rs b/libdd-common/src/cstr.rs index 458dd4cca9..15ea126b5d 100644 --- a/libdd-common/src/cstr.rs +++ b/libdd-common/src/cstr.rs @@ -31,7 +31,7 @@ macro_rules! cstr { } $crate::cstr::validate_cstr_contents(bytes); - unsafe { std::ffi::CStr::from_bytes_with_nul_unchecked(bytes) } + unsafe { core::ffi::CStr::from_bytes_with_nul_unchecked(bytes) } }}; } @@ -39,7 +39,7 @@ macro_rules! cstr { macro_rules! cstr_u8 { ($s:literal) => {{ $crate::cstr::validate_cstr_contents($s); - unsafe { std::ffi::CStr::from_bytes_with_nul_unchecked($s as &[u8]) } + unsafe { core::ffi::CStr::from_bytes_with_nul_unchecked($s as &[u8]) } }}; } diff --git a/libdd-common/src/dump_server.rs b/libdd-common/src/dump_server.rs index 66dd352e3c..396fb5789a 100644 --- a/libdd-common/src/dump_server.rs +++ b/libdd-common/src/dump_server.rs @@ -178,7 +178,7 @@ fn is_chunked_encoding(headers: &[httparse::Header]) -> bool { headers.iter().any(|h| { h.name .eq_ignore_ascii_case(http::header::TRANSFER_ENCODING.as_str()) - && std::str::from_utf8(h.value).is_ok_and(|v| v.to_lowercase().contains("chunked")) + && core::str::from_utf8(h.value).is_ok_and(|v| v.to_lowercase().contains("chunked")) }) } @@ -190,7 +190,7 @@ fn get_content_length(headers: &[httparse::Header]) -> Option { h.name .eq_ignore_ascii_case(http::header::CONTENT_LENGTH.as_str()) }) - .and_then(|h| std::str::from_utf8(h.value).ok()) + .and_then(|h| core::str::from_utf8(h.value).ok()) .and_then(|v| v.trim().parse().ok()) } @@ -294,7 +294,7 @@ fn decode_chunked_body(chunked_data: &[u8]) -> anyhow::Result> { .with_context(|| format!("Missing CRLF after chunk size at position {}", pos))?; // Parse the chunk size (hex) - let size_str = std::str::from_utf8(&chunked_data[pos..pos + line_end]) + let size_str = core::str::from_utf8(&chunked_data[pos..pos + line_end]) .context("Invalid UTF-8 in chunk size")?; let chunk_size = usize::from_str_radix(size_str.trim(), 16) diff --git a/libdd-common/src/entity_id/unix/mod.rs b/libdd-common/src/entity_id/unix/mod.rs index 826f2e9604..91ec121ee8 100644 --- a/libdd-common/src/entity_id/unix/mod.rs +++ b/libdd-common/src/entity_id/unix/mod.rs @@ -1,8 +1,8 @@ // Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use alloc::fmt; use std::error; -use std::fmt; use std::path::Path; use std::sync::LazyLock; @@ -66,7 +66,7 @@ fn get_cgroup_path() -> &'static str { #[cfg(feature = "cgroup_testing")] return TESTING_CGROUP_PATH .get() - .map(std::ops::Deref::deref) + .map(core::ops::Deref::deref) .unwrap_or(DEFAULT_CGROUP_PATH); #[cfg(not(feature = "cgroup_testing"))] return DEFAULT_CGROUP_PATH; diff --git a/libdd-common/src/error.rs b/libdd-common/src/error.rs index b91ea2ed2e..e2e706add4 100644 --- a/libdd-common/src/error.rs +++ b/libdd-common/src/error.rs @@ -20,7 +20,7 @@ pub unsafe trait FfiSafeErrorMessage { /// Returns the error message as a static CStr. It must also be a valid /// Rust string, including being UTF-8. - fn as_ffi_str(&self) -> &'static std::ffi::CStr; + fn as_ffi_str(&self) -> &'static core::ffi::CStr; /// Returns the error message as a static Rust str, excluding the null /// terminator. If you need it, use [`FfiSafeErrorMessage::as_ffi_str`]. @@ -29,6 +29,6 @@ pub unsafe trait FfiSafeErrorMessage { fn as_rust_str(&self) -> &'static str { // Bytes will not contain the null terminator. let bytes = self.as_ffi_str().to_bytes(); - unsafe { std::str::from_utf8_unchecked(bytes) } + unsafe { core::str::from_utf8_unchecked(bytes) } } } diff --git a/libdd-common/src/http_common.rs b/libdd-common/src/http_common.rs index 1ffd3246fe..cc8ca19171 100644 --- a/libdd-common/src/http_common.rs +++ b/libdd-common/src/http_common.rs @@ -1,8 +1,8 @@ // Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use core::convert::Infallible; use core::fmt; -use std::convert::Infallible; use thiserror::Error; @@ -26,8 +26,8 @@ pub struct ClientError { kind: ErrorKind, } -impl std::fmt::Display for ClientError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for ClientError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.source.fmt(f) } } @@ -46,7 +46,7 @@ pub enum Error { } impl fmt::Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { Error::Client(e) => write!(f, "client error: {e}"), Error::Infallible(e) => match *e {}, @@ -67,15 +67,15 @@ impl From for Error { } } -impl std::error::Error for Error {} +impl core::error::Error for Error {} // --- Native-only code (hyper, Body, client builders, etc.) --- #[cfg(not(target_arch = "wasm32"))] mod native { use super::*; - use std::error::Error as _; - use std::task::Poll; + use core::error::Error as _; + use core::task::Poll; use crate::connector::Connector; use http_body_util::BodyExt; @@ -205,7 +205,7 @@ mod native { } pub fn boxed< - E: std::error::Error + Sync + Send + 'static, + E: core::error::Error + Sync + Send + 'static, T: hyper::body::Body + Sync + Send + 'static, >( body: T, @@ -253,9 +253,9 @@ mod native { type Error = Error; fn poll_frame( - self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll, Self::Error>>> { + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + ) -> core::task::Poll, Self::Error>>> { match self.project() { BodyProj::Single(pin) => pin.poll_frame(cx).map_err(Error::Infallible), BodyProj::Empty(pin) => pin.poll_frame(cx).map_err(Error::Infallible), diff --git a/libdd-common/src/lib.rs b/libdd-common/src/lib.rs index 1a3b665245..853ef18d80 100644 --- a/libdd-common/src/lib.rs +++ b/libdd-common/src/lib.rs @@ -6,12 +6,16 @@ #![cfg_attr(not(test), deny(clippy::todo))] #![cfg_attr(not(test), deny(clippy::unimplemented))] +extern crate alloc; + +use alloc::borrow::Cow; use anyhow::Context; +use core::{ops::Deref, str::FromStr}; use http::uri; use serde::de::Error; use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use std::path::PathBuf; use std::sync::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard}; -use std::{borrow::Cow, ops::Deref, path::PathBuf, str::FromStr}; pub mod azure_app_services; #[cfg(not(target_arch = "wasm32"))] @@ -461,7 +465,7 @@ impl Endpoint { // configuration will mutate the system environment (it doesn't pass // it as part of the SAPI env, it changes the actual system env). let mut builder = reqwest::Client::builder() - .timeout(std::time::Duration::from_millis(self.timeout_ms)) + .timeout(core::time::Duration::from_millis(self.timeout_ms)) .hickory_dns(!self.use_system_resolver) .no_proxy(); diff --git a/libdd-common/src/machine_id/windows.rs b/libdd-common/src/machine_id/windows.rs index 36d6badb11..4f8344aa10 100644 --- a/libdd-common/src/machine_id/windows.rs +++ b/libdd-common/src/machine_id/windows.rs @@ -17,7 +17,7 @@ use windows_sys::Win32::System::Registry::{ }; fn to_wide_null(s: &str) -> Vec { - s.encode_utf16().chain(std::iter::once(0u16)).collect() + s.encode_utf16().chain(core::iter::once(0u16)).collect() } pub fn get_machine_id_impl() -> String { @@ -44,9 +44,9 @@ pub fn get_machine_id_impl() -> String { RegQueryValueExW( hkey, value_wide.as_ptr(), - std::ptr::null_mut(), + core::ptr::null_mut(), &mut data_type, - std::ptr::null_mut(), + core::ptr::null_mut(), &mut data_len, ) }; @@ -65,7 +65,7 @@ pub fn get_machine_id_impl() -> String { RegQueryValueExW( hkey, value_wide.as_ptr(), - std::ptr::null_mut(), + core::ptr::null_mut(), &mut data_type, buf.as_mut_ptr().cast(), &mut actual_len, diff --git a/libdd-common/src/rate_limiter.rs b/libdd-common/src/rate_limiter.rs index 9d686b08d1..de2f9c1029 100644 --- a/libdd-common/src/rate_limiter.rs +++ b/libdd-common/src/rate_limiter.rs @@ -1,7 +1,7 @@ // Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 -use std::sync::atomic::{AtomicI64, AtomicU32, AtomicU64, Ordering}; +use core::sync::atomic::{AtomicI64, AtomicU32, AtomicU64, Ordering}; pub trait Limiter { /// Takes the limit per interval. @@ -158,7 +158,7 @@ impl Limiter for LocalLimiter { #[cfg(test)] mod tests { use crate::rate_limiter::{now, Limiter, LocalLimiter, MOCK_NOW, TIME_PER_SECOND}; - use std::sync::atomic::Ordering; + use core::sync::atomic::Ordering; fn set_mock_time(nanos: u64) { MOCK_NOW.store(nanos, Ordering::Relaxed); diff --git a/libdd-common/src/tag.rs b/libdd-common/src/tag.rs index 4f06abe182..7adad82511 100644 --- a/libdd-common/src/tag.rs +++ b/libdd-common/src/tag.rs @@ -1,9 +1,9 @@ // Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use alloc::borrow::Cow; +use core::fmt::{Debug, Display, Formatter}; use serde::{Deserialize, Serialize}; -use std::borrow::Cow; -use std::fmt::{Debug, Display, Formatter}; pub use static_assertions::{const_assert, const_assert_ne}; @@ -71,7 +71,7 @@ macro_rules! tag { } impl Debug for Tag { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { f.debug_struct("Tag").field("value", &self.value).finish() } } @@ -84,7 +84,7 @@ impl AsRef for Tag { // Any type which implements Display automatically has to_string. impl Display for Tag { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "{}", self.value) } } diff --git a/libdd-common/src/test_utils.rs b/libdd-common/src/test_utils.rs index e3cf75e695..0942026f42 100644 --- a/libdd-common/src/test_utils.rs +++ b/libdd-common/src/test_utils.rs @@ -36,7 +36,7 @@ impl Drop for TempFileGuard { } } -impl std::ops::Deref for TempFileGuard { +impl core::ops::Deref for TempFileGuard { type Target = PathBuf; fn deref(&self) -> &Self::Target { @@ -158,7 +158,7 @@ pub fn count_active_threads() -> anyhow::Result { #[cfg(windows)] { - use std::mem::{size_of, zeroed}; + use core::mem::{size_of, zeroed}; use windows_sys::Win32::Foundation::CloseHandle; use windows_sys::Win32::System::Diagnostics::ToolHelp::{ CreateToolhelp32Snapshot, Thread32First, Thread32Next, TH32CS_SNAPTHREAD, THREADENTRY32, @@ -529,7 +529,8 @@ mod tests { ); // Spawn some threads and verify the count increases - use std::sync::{Arc, Barrier}; + use alloc::sync::Arc; + use std::sync::Barrier; let barrier = Arc::new(Barrier::new(6)); // 5 spawned threads + main thread let handles: Vec<_> = (0..5) @@ -537,7 +538,7 @@ mod tests { let barrier = Arc::clone(&barrier); std::thread::spawn(move || { barrier.wait(); - std::thread::sleep(std::time::Duration::from_millis(50)); + std::thread::sleep(core::time::Duration::from_millis(50)); }) }) .collect(); diff --git a/libdd-common/src/timeout.rs b/libdd-common/src/timeout.rs index 3d17827370..592fe07826 100644 --- a/libdd-common/src/timeout.rs +++ b/libdd-common/src/timeout.rs @@ -1,7 +1,8 @@ // Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 -use std::time::{Duration, Instant}; +use core::time::Duration; +use std::time::Instant; pub struct TimeoutManager { start_time: Instant, @@ -38,8 +39,8 @@ impl TimeoutManager { } } -impl std::fmt::Debug for TimeoutManager { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for TimeoutManager { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("TimeoutManager") .field("start_time", &self.start_time) .field("elapsed", &self.elapsed()) diff --git a/libdd-common/src/unix_utils/execve.rs b/libdd-common/src/unix_utils/execve.rs index 4a0ea02be0..6a0063dcc9 100644 --- a/libdd-common/src/unix_utils/execve.rs +++ b/libdd-common/src/unix_utils/execve.rs @@ -1,9 +1,9 @@ // Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use alloc::ffi::{CString, NulError}; use libc::execve; use nix::errno::Errno; -use std::ffi::CString; // The args_cstrings and env_vars_strings fields are just storage. Even though they're // unreferenced, they're a necessary part of the struct. @@ -20,15 +20,15 @@ pub struct PreparedExecve { #[derive(Debug, thiserror::Error)] pub enum PreparedExecveError { #[error("Failed to convert binary path to CString: {0}")] - BinaryPathError(std::ffi::NulError), + BinaryPathError(NulError), #[error("Failed to convert argument to CString: {0}")] - ArgumentError(std::ffi::NulError), + ArgumentError(NulError), #[error("Failed to convert environment variable to CString: {0}")] - EnvironmentError(std::ffi::NulError), + EnvironmentError(NulError), } -impl From for PreparedExecveError { - fn from(err: std::ffi::NulError) -> Self { +impl From for PreparedExecveError { + fn from(err: NulError) -> Self { PreparedExecveError::BinaryPathError(err) } } @@ -47,12 +47,12 @@ impl PreparedExecve { let args_cstrings: Vec = args .iter() .map(|s| CString::new(s.as_str())) - .collect::, std::ffi::NulError>>() + .collect::, NulError>>() .map_err(PreparedExecveError::ArgumentError)?; let args_ptrs: Vec<*const libc::c_char> = args_cstrings .iter() .map(|arg| arg.as_ptr()) - .chain(std::iter::once(std::ptr::null())) // Adds a null pointer to the end of the list + .chain(core::iter::once(core::ptr::null())) // Adds a null pointer to the end of the list .collect(); // Allocate and store environment variables @@ -62,12 +62,12 @@ impl PreparedExecve { let env_str = format!("{key}={value}"); CString::new(env_str) }) - .collect::, std::ffi::NulError>>() + .collect::, NulError>>() .map_err(PreparedExecveError::EnvironmentError)?; let env_vars_ptrs: Vec<*const libc::c_char> = env_vars_cstrings .iter() .map(|env| env.as_ptr()) - .chain(std::iter::once(std::ptr::null())) // Adds a null pointer to the end of the list + .chain(core::iter::once(core::ptr::null())) // Adds a null pointer to the end of the list .collect(); Ok(Self { @@ -119,7 +119,7 @@ mod tests { // Verify the struct was created successfully // We can't directly access private fields, but we can verify the struct exists - assert!(std::mem::size_of_val(&prepared) > 0); + assert!(core::mem::size_of_val(&prepared) > 0); } #[test] @@ -131,7 +131,7 @@ mod tests { let prepared = PreparedExecve::new(binary_path, &args, &env).unwrap(); // Should still create successfully with empty args and env - assert!(std::mem::size_of_val(&prepared) > 0); + assert!(core::mem::size_of_val(&prepared) > 0); } #[test] @@ -152,7 +152,7 @@ mod tests { let prepared = PreparedExecve::new(binary_path, &args, &env).unwrap(); // Should handle complex arguments and environment variables - assert!(std::mem::size_of_val(&prepared) > 0); + assert!(core::mem::size_of_val(&prepared) > 0); } #[test] @@ -228,7 +228,7 @@ mod tests { let prepared = PreparedExecve::new(binary_path, &args, &env).unwrap(); // Should handle Unicode characters - assert!(std::mem::size_of_val(&prepared) > 0); + assert!(core::mem::size_of_val(&prepared) > 0); } #[test] @@ -240,7 +240,7 @@ mod tests { let prepared = PreparedExecve::new(binary_path, &args, &env).unwrap(); // Should handle large numbers of arguments - assert!(std::mem::size_of_val(&prepared) > 0); + assert!(core::mem::size_of_val(&prepared) > 0); } #[test] @@ -254,7 +254,7 @@ mod tests { let prepared = PreparedExecve::new(binary_path, &args, &env).unwrap(); // Should handle large numbers of environment variables - assert!(std::mem::size_of_val(&prepared) > 0); + assert!(core::mem::size_of_val(&prepared) > 0); } #[test] @@ -266,7 +266,7 @@ mod tests { let prepared = PreparedExecve::new(binary_path, &args, &env).unwrap(); // Should handle empty binary path (though this might not be valid for execve) - assert!(std::mem::size_of_val(&prepared) > 0); + assert!(core::mem::size_of_val(&prepared) > 0); } #[test] @@ -281,7 +281,7 @@ mod tests { let prepared = PreparedExecve::new(binary_path, &args, &env).unwrap(); // Should handle empty keys and values - assert!(std::mem::size_of_val(&prepared) > 0); + assert!(core::mem::size_of_val(&prepared) > 0); } #[test] diff --git a/libdd-common/src/unix_utils/fork.rs b/libdd-common/src/unix_utils/fork.rs index 58668826f7..2e06355660 100644 --- a/libdd-common/src/unix_utils/fork.rs +++ b/libdd-common/src/unix_utils/fork.rs @@ -84,7 +84,7 @@ fn is_being_traced_internal(mut file: File) -> io::Result { #[cfg(target_os = "linux")] fn check_tracer_pid_line(line: &[u8], marker: &[u8]) -> io::Result> { if line.starts_with(marker) && line.len() > marker.len() { - if let Ok(line_str) = std::str::from_utf8(line) { + if let Ok(line_str) = core::str::from_utf8(line) { let tracer_pid = line_str.split_whitespace().nth(1).unwrap_or("0"); return Ok(Some(tracer_pid != "0")); } @@ -114,7 +114,7 @@ pub fn alt_fork() -> libc::pid_t { syscall( SYS_clone, (CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD | extra_flags) as c_ulong, - std::ptr::null_mut::(), + core::ptr::null_mut::(), &mut _ptid as *mut pid_t, &mut _ctid as *mut pid_t, 0 as c_ulong, diff --git a/libdd-common/src/unix_utils/process.rs b/libdd-common/src/unix_utils/process.rs index c7704622b0..26763f1e59 100644 --- a/libdd-common/src/unix_utils/process.rs +++ b/libdd-common/src/unix_utils/process.rs @@ -103,7 +103,7 @@ pub fn wait_for_pollhup( #[cfg(test)] mod tests { use super::*; - use std::time::Duration; + use core::time::Duration; #[cfg_attr(miri, ignore)] // miri doesn't support waitpid #[test] diff --git a/libdd-crashtracker/Cargo.toml b/libdd-crashtracker/Cargo.toml index 5e88a070c4..ce3e6729f7 100644 --- a/libdd-crashtracker/Cargo.toml +++ b/libdd-crashtracker/Cargo.toml @@ -86,3 +86,7 @@ cxx-build = { version = "1.0", optional = true } # Without this, aws-lc-sys gets compiled twice: once for the normal dep graph and once for the # build-script dep graph (Cargo resolver v2 keeps these contexts separate). libdd-common = { version = "5.0.0", path = "../libdd-common", default-features = false } + +[lints.clippy] +std_instead_of_alloc = "warn" +std_instead_of_core = "warn" diff --git a/libdd-crashtracker/benches/receiver_bench.rs b/libdd-crashtracker/benches/receiver_bench.rs index d71a38c494..f2acedfdc2 100644 --- a/libdd-crashtracker/benches/receiver_bench.rs +++ b/libdd-crashtracker/benches/receiver_bench.rs @@ -1,12 +1,11 @@ // Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +#![allow(clippy::std_instead_of_alloc, clippy::std_instead_of_core)] use criterion::{black_box, criterion_group, BenchmarkId, Criterion}; -use libdd_crashtracker::benchmark::receiver_entry_point; -use libdd_crashtracker::shared::constants::*; use libdd_crashtracker::{ - default_signals, get_tests_folder_path, CrashtrackerConfiguration, SharedLibrary, - StacktraceCollection, + benchmark::receiver_entry_point, default_signals, get_tests_folder_path, shared::constants::*, + CrashtrackerConfiguration, SharedLibrary, StacktraceCollection, }; use std::fmt::Write; use std::time::Duration; diff --git a/libdd-crashtracker/src/collector/api.rs b/libdd-crashtracker/src/collector/api.rs index 874ff53d02..59d82dc824 100644 --- a/libdd-crashtracker/src/collector/api.rs +++ b/libdd-crashtracker/src/collector/api.rs @@ -25,7 +25,7 @@ pub(super) fn mark_preload_logger_collector() { unsafe { let sym = libc::dlsym(libc::RTLD_DEFAULT, SYMBOL.as_ptr() as *const _); if !sym.is_null() { - let func: extern "C" fn() = std::mem::transmute(sym); + let func: extern "C" fn() = core::mem::transmute(sym); func(); } } @@ -119,8 +119,8 @@ mod single_threaded_tests { begin_op, insert_span, insert_trace, CrashtrackerConfigurationBuilder, StacktraceCollection, }; use chrono::Utc; + use core::time::Duration; use libdd_common::tag; - use std::time::Duration; const PATH_TO_RECEIVER: &str = "/tmp/libdatadog/bin/libdatadog-crashtracking-receiver"; // We can't run this in the main test runner because it (deliberately) crashes, @@ -178,7 +178,7 @@ mod single_threaded_tests { std::thread::sleep(Duration::from_secs(2)); - let p: *const u32 = std::ptr::null(); + let p: *const u32 = core::ptr::null(); let q = unsafe { *p }; assert_eq!(q, 3); } @@ -210,11 +210,11 @@ mod single_threaded_tests { #[cfg(target_os = "linux")] fn get_sigaltstack() -> Option { let mut sigaltstack = libc::stack_t { - ss_sp: std::ptr::null_mut(), + ss_sp: core::ptr::null_mut(), ss_flags: 0, ss_size: 0, }; - let res = unsafe { libc::sigaltstack(std::ptr::null(), &mut sigaltstack) }; + let res = unsafe { libc::sigaltstack(core::ptr::null(), &mut sigaltstack) }; if res == 0 { Some(sigaltstack) } else { @@ -290,7 +290,7 @@ mod single_threaded_tests { // Check the SIGBUS and SIGSEGV handlers are set with SA_ONSTACK let mut sigaction = libc::sigaction { sa_sigaction: 0, - sa_mask: unsafe { std::mem::zeroed::() }, + sa_mask: unsafe { core::mem::zeroed::() }, sa_flags: 0, sa_restorer: None, }; @@ -300,7 +300,7 @@ mod single_threaded_tests { for signal in default_signals() { let signame = crate::signal_from_signum(signal).unwrap(); exit_code -= 1; - let res = unsafe { libc::sigaction(signal, std::ptr::null(), &mut sigaction) }; + let res = unsafe { libc::sigaction(signal, core::ptr::null(), &mut sigaction) }; if res != 0 { eprintln!("Failed to get {signame:?} handler"); std::process::exit(exit_code); @@ -399,14 +399,14 @@ mod single_threaded_tests { // we double-check here because the options need to be decoupled let mut sigaction = libc::sigaction { sa_sigaction: 0, - sa_mask: unsafe { std::mem::zeroed::() }, + sa_mask: unsafe { core::mem::zeroed::() }, sa_flags: 0, sa_restorer: None, }; // First, SIGBUS let res = - unsafe { libc::sigaction(libc::SIGBUS, std::ptr::null(), &mut sigaction) }; + unsafe { libc::sigaction(libc::SIGBUS, core::ptr::null(), &mut sigaction) }; if res != 0 { eprintln!("Failed to get SIGBUS handler"); std::process::exit(-6); @@ -418,7 +418,7 @@ mod single_threaded_tests { // Second, SIGSEGV let res = - unsafe { libc::sigaction(libc::SIGSEGV, std::ptr::null(), &mut sigaction) }; + unsafe { libc::sigaction(libc::SIGSEGV, core::ptr::null(), &mut sigaction) }; if res != 0 { eprintln!("Failed to get SIGSEGV handler"); std::process::exit(-8); @@ -513,14 +513,14 @@ mod single_threaded_tests { // Similarly, we need to be extra sure that SA_ONSTACK is not present. let mut sigaction = libc::sigaction { sa_sigaction: 0, - sa_mask: unsafe { std::mem::zeroed::() }, + sa_mask: unsafe { core::mem::zeroed::() }, sa_flags: 0, sa_restorer: None, }; // First, SIGBUS let res = - unsafe { libc::sigaction(libc::SIGBUS, std::ptr::null(), &mut sigaction) }; + unsafe { libc::sigaction(libc::SIGBUS, core::ptr::null(), &mut sigaction) }; if res != 0 { eprintln!("Failed to get SIGBUS handler"); std::process::exit(-6); @@ -532,7 +532,7 @@ mod single_threaded_tests { // Second, SIGSEGV let res = - unsafe { libc::sigaction(libc::SIGSEGV, std::ptr::null(), &mut sigaction) }; + unsafe { libc::sigaction(libc::SIGSEGV, core::ptr::null(), &mut sigaction) }; if res != 0 { eprintln!("Failed to get SIGSEGV handler"); std::process::exit(-8); diff --git a/libdd-crashtracker/src/collector/atomic_set.rs b/libdd-crashtracker/src/collector/atomic_set.rs index f57ab5821a..4b9fc87255 100644 --- a/libdd-crashtracker/src/collector/atomic_set.rs +++ b/libdd-crashtracker/src/collector/atomic_set.rs @@ -7,13 +7,13 @@ //! handler can emit that information into the crash-report. //! If this is useful for other cases, we can consider moving it to ddcommon. +use core::fmt::Debug; +use core::num::NonZeroU128; +use core::ptr::null_mut; +use core::sync::atomic::Ordering::SeqCst; use portable_atomic::AtomicUsize; use rand::Rng; -use std::fmt::Debug; use std::io::Write; -use std::num::NonZeroU128; -use std::ptr::null_mut; -use std::sync::atomic::Ordering::SeqCst; #[derive(Debug, thiserror::Error)] pub enum AtomicSetError { @@ -69,7 +69,7 @@ pub struct AtomicMultiset { impl AtomicMultiset where T: Atomic, - ::Item: std::cmp::PartialEq + Debug + Ord, + ::Item: core::cmp::PartialEq + Debug + Ord, { /// Atomicity: The individual operations of the clear are atomic, but the overall operation /// is not atomic. @@ -398,7 +398,7 @@ mod tests { #[test] fn test_string_ops() { - let mut expected = std::collections::BTreeMap::::new(); + let mut expected = alloc::collections::BTreeMap::::new(); let s = AtomicStringMultiset::<8>::new(); compare(&s, &expected); insert_and_compare(&s, &mut expected, "a".to_string()); @@ -424,7 +424,7 @@ mod tests { #[test] fn test_span_ops() { - let mut expected = std::collections::BTreeMap::::new(); + let mut expected = alloc::collections::BTreeMap::::new(); let s: AtomicSpanSet<8> = AtomicSpanSet::<8>::new(); compare(&s, &expected); insert_and_compare(&s, &mut expected, nz(42)); @@ -484,7 +484,7 @@ mod tests { fn remove_and_compare( s: &AtomicMultiset, - expected: &mut std::collections::BTreeMap, + expected: &mut alloc::collections::BTreeMap, v: T::Item, ) { remove(s, expected, v).unwrap(); @@ -493,7 +493,7 @@ mod tests { fn remove( s: &AtomicMultiset, - expected: &mut std::collections::BTreeMap, + expected: &mut alloc::collections::BTreeMap, v: T::Item, ) -> Result<(), AtomicSetError> { let idx = expected.get(&v).unwrap(); @@ -504,7 +504,7 @@ mod tests { fn compare( s: &AtomicMultiset, - expected: &std::collections::BTreeMap, + expected: &alloc::collections::BTreeMap, ) { let actual = s.values().unwrap(); let golden: Vec<_> = expected.keys().cloned().collect(); @@ -514,7 +514,7 @@ mod tests { fn insert( s: &AtomicMultiset, - expected: &mut std::collections::BTreeMap, + expected: &mut alloc::collections::BTreeMap, v: T::Item, ) -> Result<(), AtomicSetError> { expected.insert(v.clone(), s.insert(v)?); @@ -523,7 +523,7 @@ mod tests { fn insert_and_compare( s: &AtomicMultiset, - expected: &mut std::collections::BTreeMap, + expected: &mut alloc::collections::BTreeMap, v: T::Item, ) { insert(s, expected, v).unwrap(); diff --git a/libdd-crashtracker/src/collector/counters.rs b/libdd-crashtracker/src/collector/counters.rs index f1de6bb5a1..d7dab3645b 100644 --- a/libdd-crashtracker/src/collector/counters.rs +++ b/libdd-crashtracker/src/collector/counters.rs @@ -1,7 +1,7 @@ // Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 -use std::sync::atomic::{AtomicI64, Ordering}; +use core::sync::atomic::{AtomicI64, Ordering}; use thiserror::Error; #[cfg(unix)] diff --git a/libdd-crashtracker/src/collector/crash_handler.rs b/libdd-crashtracker/src/collector/crash_handler.rs index 382ae6b1d7..5e3e28e7db 100644 --- a/libdd-crashtracker/src/collector/crash_handler.rs +++ b/libdd-crashtracker/src/collector/crash_handler.rs @@ -10,6 +10,9 @@ use super::signal_handler_manager::chain_signal_handler; use crate::crash_info::Metadata; use crate::shared::configuration::CrashtrackerConfiguration; use crate::StackTrace; +use core::ptr; +use core::sync::atomic::Ordering::{Relaxed, SeqCst}; +use core::sync::atomic::{AtomicBool, AtomicI32, AtomicPtr, AtomicU64}; use errno::{errno, set_errno}; use libc::{c_void, pid_t, siginfo_t, ucontext_t}; use libdd_common::timeout::TimeoutManager; @@ -18,9 +21,6 @@ use std::os::unix::io::{AsRawFd, FromRawFd}; use std::os::unix::net::UnixStream; use std::panic; use std::panic::PanicHookInfo; -use std::ptr; -use std::sync::atomic::Ordering::{Relaxed, SeqCst}; -use std::sync::atomic::{AtomicBool, AtomicI32, AtomicPtr, AtomicU64}; // Note that this file makes use the following async-signal safe functions in a signal handler. // @@ -104,7 +104,7 @@ pub fn update_metadata(metadata: Metadata) -> anyhow::Result<()> { if !old.is_null() { // Safety: This can only come from a box above. unsafe { - std::mem::drop(Box::from_raw(old)); + core::mem::drop(Box::from_raw(old)); } } Ok(()) @@ -163,7 +163,7 @@ pub fn register_panic_hook() -> anyhow::Result<()> { // message_ptr should be null, but just in case. if !message_ptr.is_null() { unsafe { - std::mem::drop(Box::from_raw(message_ptr)); + core::mem::drop(Box::from_raw(message_ptr)); } } @@ -210,7 +210,7 @@ pub fn update_config(config: CrashtrackerConfiguration) -> anyhow::Result<()> { if !old.is_null() { // Safety: This can only come from a box above. unsafe { - std::mem::drop(Box::from_raw(old)); + core::mem::drop(Box::from_raw(old)); } } Ok(()) @@ -420,8 +420,8 @@ fn grant_ptracer_permission(receiver: &Receiver) { if expected_pid <= 0 { 0 } else { - let mut cred: libc::ucred = unsafe { std::mem::zeroed() }; - let mut len = std::mem::size_of::() as libc::socklen_t; + let mut cred: libc::ucred = unsafe { core::mem::zeroed() }; + let mut len = core::mem::size_of::() as libc::socklen_t; // SAFETY: getsockopt is async-signal-safe let ret = unsafe { libc::getsockopt( @@ -561,7 +561,7 @@ pub fn report_unhandled_exception( #[cfg(test)] mod tests { use super::*; - use std::time::Duration; + use core::time::Duration; fn make_test_metadata() -> Metadata { Metadata { diff --git a/libdd-crashtracker/src/collector/emitters.rs b/libdd-crashtracker/src/collector/emitters.rs index 4d7dda8f8a..530b0f12a7 100644 --- a/libdd-crashtracker/src/collector/emitters.rs +++ b/libdd-crashtracker/src/collector/emitters.rs @@ -212,7 +212,7 @@ unsafe fn emit_backtrace_via_libunwind( // SAFETY: UnwCursor is a repr(C) struct of plain integers (`[u64; 127]`); // all-zeros is a valid bit pattern - let mut cursor: UnwCursor = unsafe { std::mem::zeroed() }; + let mut cursor: UnwCursor = unsafe { core::mem::zeroed() }; // SAFETY: `cursor` is zeroed and is valid for initialization. // `ucontext` was checked non-null above and points to the kernel-saved @@ -244,7 +244,7 @@ unsafe fn emit_backtrace_via_libunwind( // SAFETY: Dl_info is a repr(C) struct of pointers and integers; // all-zeros (null pointers, zero integers) is a valid representation - let mut dl_info: libc::Dl_info = unsafe { std::mem::zeroed() }; + let mut dl_info: libc::Dl_info = unsafe { core::mem::zeroed() }; // SAFETY: `ip` is a code address obtained from the unwinder. // dladdr only reads ld.so internal tables (no allocation, no locks) // making it safe to call from a signal handler @@ -266,13 +266,13 @@ unsafe fn emit_backtrace_via_libunwind( &mut cursor, name_buf.as_mut_ptr(), name_buf.len(), - std::ptr::null_mut(), + core::ptr::null_mut(), ) } == 0 { // SAFETY: unw_get_proc_name returned 0 (success), guaranteeing // a NUL-terminated string was written into name_buf. - let name = unsafe { std::ffi::CStr::from_ptr(name_buf.as_ptr()) }; + let name = unsafe { core::ffi::CStr::from_ptr(name_buf.as_ptr()) }; if let Ok(s) = name.to_str() { write!(w, ", \"function\": \"{s}\"")?; } @@ -340,10 +340,10 @@ unsafe fn emit_macos_backtrace_from_ucontext( const MAX_FRAMES: usize = 512; for _ in 0..MAX_FRAMES { - if fp == 0 || fp % std::mem::align_of::() != 0 { + if fp == 0 || fp % core::mem::align_of::() != 0 { break; } - if !in_stack_bounds(fp, 2 * std::mem::size_of::()) { + if !in_stack_bounds(fp, 2 * core::mem::size_of::()) { break; } // SAFETY: `fp` is non-zero, properly aligned, and the two-word frame @@ -351,7 +351,7 @@ unsafe fn emit_macos_backtrace_from_ucontext( // bounds (checked by in_stack_bounds above). After fork(), the child // has a copy-on-write view of the parent's stack memory. let next_fp = unsafe { *(fp as *const usize) }; - let return_addr = unsafe { *((fp + std::mem::size_of::()) as *const usize) }; + let return_addr = unsafe { *((fp + core::mem::size_of::()) as *const usize) }; if return_addr == 0 { break; } @@ -372,7 +372,7 @@ unsafe fn emit_macos_backtrace_from_ucontext( unsafe fn emit_frame_with_dladdr(w: &mut impl Write, ip: usize) -> Result<(), EmitterError> { // SAFETY: Dl_info is a repr(C) struct of pointers and integers; // all-zeros (null pointers, zero integers) is a valid representation. - let mut info: libc::Dl_info = unsafe { std::mem::zeroed() }; + let mut info: libc::Dl_info = unsafe { core::mem::zeroed() }; // SAFETY: dladdr only reads dyld's internal data structures (no // allocation, no Mach IPC) making it async-signal-safe. `ip` is a code // address from the unwound stack or kernel-saved registers. @@ -391,7 +391,7 @@ unsafe fn emit_frame_with_dladdr(w: &mut impl Write, ip: usize) -> Result<(), Em // SAFETY: dladdr returned non-zero and dli_sname is non-null, so // it points to a valid NUL-terminated C string in the shared // library's string table (static lifetime, read-only). - let name = unsafe { std::ffi::CStr::from_ptr(info.dli_sname) }; + let name = unsafe { core::ffi::CStr::from_ptr(info.dli_sname) }; if let Ok(s) = name.to_str() { write!(w, ", \"function\": \"{s}\"")?; } @@ -792,7 +792,7 @@ mod tests { use crate::StackFrame; use super::*; - use std::str; + use alloc::str; #[test] fn test_emit_complete_stacktrace() { @@ -828,7 +828,7 @@ mod tests { #[test] fn test_emit_message_nullptr() { let mut buf = Vec::new(); - emit_message(&mut buf, std::ptr::null_mut()).expect("to work ;-)"); + emit_message(&mut buf, core::ptr::null_mut()).expect("to work ;-)"); assert!(buf.is_empty()); } @@ -1057,7 +1057,7 @@ mod tests { emit_backtrace_via_libunwind( &mut buf, StacktraceCollection::WithoutSymbols, - std::ptr::null(), + core::ptr::null(), ) .expect("should handle null ucontext gracefully"); } @@ -1071,7 +1071,7 @@ mod tests { fn test_emit_backtrace_via_libunwind_unw_init_failure() { // Test that when unw_init_local2 fails (e.g., with invalid context), // the function returns Ok(()) gracefully without writing anything - let context: libc::ucontext_t = unsafe { std::mem::zeroed() }; + let context: libc::ucontext_t = unsafe { core::mem::zeroed() }; let mut buf = Vec::new(); unsafe { @@ -1090,7 +1090,7 @@ mod tests { #[test] fn test_emit_ucontext_null_pointer() { let mut buf = Vec::new(); - let result = emit_ucontext(&mut buf, std::ptr::null()); + let result = emit_ucontext(&mut buf, core::ptr::null()); assert!(result.is_err()); assert!(matches!(result.unwrap_err(), EmitterError::NullUcontext)); @@ -1101,7 +1101,7 @@ mod tests { #[cfg(target_os = "linux")] fn test_emit_ucontext_linux_valid() { // Create a minimal valid ucontext_t with zeroed register values - let mut context: libc::ucontext_t = unsafe { std::mem::zeroed() }; + let mut context: libc::ucontext_t = unsafe { core::mem::zeroed() }; // Set up some test register values #[cfg(target_arch = "x86_64")] @@ -1190,10 +1190,10 @@ mod tests { fn test_emit_ucontext_macos_valid() { use libc::__darwin_ucontext; // Create a minimal valid ucontext_t for macOS - let mut context: __darwin_ucontext = unsafe { std::mem::zeroed() }; + let mut context: __darwin_ucontext = unsafe { core::mem::zeroed() }; // On macOS, we need to allocate mcontext and set up the pointer - let mut mcontext: libc::__darwin_mcontext64 = unsafe { std::mem::zeroed() }; + let mut mcontext: libc::__darwin_mcontext64 = unsafe { core::mem::zeroed() }; context.uc_mcontext = &mut mcontext as *mut libc::__darwin_mcontext64; // Set up some test register values @@ -1267,8 +1267,8 @@ mod tests { #[cfg_attr(miri, ignore)] fn test_emit_ucontext_macos_null_mcontext() { // Test the fallback case when mcontext is null - let mut context: libc::ucontext_t = unsafe { std::mem::zeroed() }; - context.uc_mcontext = std::ptr::null_mut(); // Explicitly set to null + let mut context: libc::ucontext_t = unsafe { core::mem::zeroed() }; + context.uc_mcontext = core::ptr::null_mut(); // Explicitly set to null let mut buf = Vec::new(); emit_ucontext(&mut buf, &context).expect("emit_ucontext should succeed with null mcontext"); diff --git a/libdd-crashtracker/src/collector/receiver_manager.rs b/libdd-crashtracker/src/collector/receiver_manager.rs index 4701c8d72c..699197b73b 100644 --- a/libdd-crashtracker/src/collector/receiver_manager.rs +++ b/libdd-crashtracker/src/collector/receiver_manager.rs @@ -5,14 +5,14 @@ use super::process_handle::ProcessHandle; use libdd_common::timeout::TimeoutManager; use crate::shared::configuration::CrashtrackerReceiverConfig; +use core::ptr; +use core::sync::atomic::AtomicPtr; +use core::sync::atomic::Ordering::SeqCst; use libdd_common::unix_utils::{alt_fork, open_file_or_quiet, terminate, PreparedExecve}; use nix::sys::signal::{self, SaFlags, SigAction, SigHandler, SigSet}; use nix::sys::socket; use std::os::unix::io::{IntoRawFd, RawFd}; use std::os::unix::net::UnixStream; -use std::ptr; -use std::sync::atomic::AtomicPtr; -use std::sync::atomic::Ordering::SeqCst; #[derive(Debug, thiserror::Error)] pub enum ReceiverError { @@ -150,7 +150,7 @@ impl Receiver { if !old.is_null() { // Safety: This can only come from a box above. unsafe { - std::mem::drop(Box::from_raw(old)); + core::mem::drop(Box::from_raw(old)); } } Ok(()) diff --git a/libdd-crashtracker/src/collector/saguard.rs b/libdd-crashtracker/src/collector/saguard.rs index 9a1b41ddfd..331af28524 100644 --- a/libdd-crashtracker/src/collector/saguard.rs +++ b/libdd-crashtracker/src/collector/saguard.rs @@ -97,9 +97,9 @@ impl Drop for SaGuard { #[cfg(test)] mod single_threaded_tests { use super::*; + use core::sync::atomic::{AtomicBool, Ordering}; use nix::sys::signal::{self, Signal}; use nix::unistd::Pid; - use std::sync::atomic::{AtomicBool, Ordering}; #[test] #[cfg_attr(miri, ignore)] diff --git a/libdd-crashtracker/src/collector/signal_handler_manager.rs b/libdd-crashtracker/src/collector/signal_handler_manager.rs index 983f0113a0..316e3223a3 100644 --- a/libdd-crashtracker/src/collector/signal_handler_manager.rs +++ b/libdd-crashtracker/src/collector/signal_handler_manager.rs @@ -3,15 +3,15 @@ use super::crash_handler::handle_posix_sigaction; use crate::shared::configuration::CrashtrackerConfiguration; use crate::signal_from_signum; +use core::ptr; +use core::sync::atomic::AtomicBool; +use core::sync::atomic::Ordering::SeqCst; use libc::{ c_void, mmap, sigaltstack, siginfo_t, MAP_ANON, MAP_FAILED, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE, SIGSTKSZ, }; use libdd_common::unix_utils::terminate; use nix::sys::signal::{self, SaFlags, SigAction, SigHandler}; -use std::ptr; -use std::sync::atomic::AtomicBool; -use std::sync::atomic::Ordering::SeqCst; // Linux seems to have the most, supporting up to 64 inclusive // https://man7.org/linux/man-pages/man7/signal.7.html @@ -142,7 +142,7 @@ unsafe fn create_alt_stack() -> anyhow::Result<()> { // arbitrary, but at least it's large enough for our purposes, and yet a small enough part of // the process RSS that it shouldn't be a problem. let page_size = page_size::get(); - let sigalstack_base_size = std::cmp::max(SIGSTKSZ, 16 * page_size); + let sigalstack_base_size = core::cmp::max(SIGSTKSZ, 16 * page_size); let stackp = mmap( ptr::null_mut(), sigalstack_base_size + page_size, diff --git a/libdd-crashtracker/src/collector/spans.rs b/libdd-crashtracker/src/collector/spans.rs index 3b26ffc33c..3f9442bec0 100644 --- a/libdd-crashtracker/src/collector/spans.rs +++ b/libdd-crashtracker/src/collector/spans.rs @@ -2,7 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use super::atomic_set::{AtomicSetError, AtomicSpanSet}; -use std::{io::Write, num::NonZeroU128}; +use core::num::NonZeroU128; +use std::io::Write; static ACTIVE_SPANS: AtomicSpanSet<2048> = AtomicSpanSet::new(); static ACTIVE_TRACES: AtomicSpanSet<2048> = AtomicSpanSet::new(); diff --git a/libdd-crashtracker/src/collector_windows/api.rs b/libdd-crashtracker/src/collector_windows/api.rs index dd3a34de1f..15715cd4a9 100644 --- a/libdd-crashtracker/src/collector_windows/api.rs +++ b/libdd-crashtracker/src/collector_windows/api.rs @@ -8,14 +8,14 @@ use crate::{ ThreadData, }; use anyhow::{anyhow, Context, Result}; -use core::mem::size_of; +use core::ffi::c_void; +use core::mem::{size_of, MaybeUninit}; +use core::ptr::{addr_of, read_unaligned}; +use core::{fmt, slice, str}; use libdd_common::Endpoint; use serde::{Deserialize, Serialize}; -use std::ffi::{c_void, OsString}; -use std::fmt; -use std::mem::MaybeUninit; +use std::ffi::OsString; use std::os::windows::ffi::OsStringExt; -use std::ptr::{addr_of, read_unaligned}; use std::sync::Mutex; use windows::core::{w, HSTRING, PCWSTR}; use windows::Win32::Foundation::{ERROR_SUCCESS, HANDLE, HMODULE, TRUE}; @@ -220,8 +220,8 @@ pub fn exception_event_callback( // 1. wer_context.ptr points to valid memory // 2. the total size is smaller than isize::MAX let error_context_json = - unsafe { std::slice::from_raw_parts(wer_context.ptr as *const u8, wer_context.len) }; - let error_context_str = std::str::from_utf8(error_context_json)?; + unsafe { slice::from_raw_parts(wer_context.ptr as *const u8, wer_context.len) }; + let error_context_str = str::from_utf8(error_context_json)?; let error_context: ErrorContext = serde_json::from_str(error_context_str)?; let mut builder = CrashInfoBuilder::new(); @@ -285,7 +285,7 @@ fn read_wer_context(process_handle: HANDLE, base_address: usize) -> Result anyhow::Result> { // Get the number of bytes required to store the array of module handles let mut cb_needed = 0; - unsafe { EnumProcessModules(process_handle, std::ptr::null_mut(), 0, &mut cb_needed) } + unsafe { EnumProcessModules(process_handle, core::ptr::null_mut(), 0, &mut cb_needed) } .context("Failed to get module list size")?; // Allocate enough space for the module handles @@ -655,7 +655,7 @@ fn get_pdb_info(process_handle: HANDLE, base_address: u64) -> Result { // 1. data is initialized and contained within a single allocated object // 2. data is non-null and aligned // 3. total size is smaller than isize::MAX - std::slice::from_raw_parts( + slice::from_raw_parts( debug_dir_buffer.as_ptr() as *const IMAGE_DEBUG_DIRECTORY, debug_dir_buffer.len() / size_of::(), ) @@ -759,9 +759,8 @@ mod tests { // read_wer_context makes a copy, so the address should be different assert_ne!(actual_context.ptr, expected_context.ptr); - let buffer = unsafe { - std::slice::from_raw_parts(actual_context.ptr as *const u8, actual_context.len) - }; + let buffer = + unsafe { slice::from_raw_parts(actual_context.ptr as *const u8, actual_context.len) }; assert_eq!(buffer, expected_data); } @@ -825,7 +824,7 @@ mod tests { assert_eq!(actual_pdb_info.age, expected_pdb_age); let bytes = unsafe { - std::slice::from_raw_parts( + slice::from_raw_parts( &actual_pdb_info.signature as *const Guid as *const u8, size_of::(), ) diff --git a/libdd-crashtracker/src/common.rs b/libdd-crashtracker/src/common.rs index 506d01d444..7341cba7a7 100644 --- a/libdd-crashtracker/src/common.rs +++ b/libdd-crashtracker/src/common.rs @@ -1,8 +1,8 @@ // Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use alloc::ffi::CString; use libc::c_void; -use std::ffi::CString; use std::path::Path; use std::path::PathBuf; diff --git a/libdd-crashtracker/src/crash_info/error_data.rs b/libdd-crashtracker/src/crash_info/error_data.rs index 2e4ef3139b..e426b82c02 100644 --- a/libdd-crashtracker/src/crash_info/error_data.rs +++ b/libdd-crashtracker/src/crash_info/error_data.rs @@ -2,6 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use super::stacktrace::StackTrace; #[cfg(unix)] +use alloc::rc::Rc; +#[cfg(unix)] use blazesym::helper::ElfResolver; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -9,8 +11,6 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; #[cfg(unix)] use std::path::PathBuf; -#[cfg(unix)] -use std::rc::Rc; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct ErrorData { diff --git a/libdd-crashtracker/src/crash_info/errors_intake.rs b/libdd-crashtracker/src/crash_info/errors_intake.rs index 3117ec33e2..55edc54800 100644 --- a/libdd-crashtracker/src/crash_info/errors_intake.rs +++ b/libdd-crashtracker/src/crash_info/errors_intake.rs @@ -1,6 +1,8 @@ // Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use alloc::borrow::Cow; +use core::time::Duration; use std::time::SystemTime; use crate::{OsInfo, SigInfo, Ucontext}; @@ -14,7 +16,7 @@ use chrono::{DateTime, Utc}; use http::{uri::PathAndQuery, Uri}; use libdd_common::{config::parse_env, parse_uri, Endpoint}; use serde::{Deserialize, Serialize}; -use std::{borrow::Cow, collections::HashMap, time::Duration}; +use std::collections::HashMap; pub const DEFAULT_DD_SITE: &str = "datadoghq.com"; pub const PROD_ERRORS_INTAKE_SUBDOMAIN: &str = "error-tracking-intake"; diff --git a/libdd-crashtracker/src/crash_info/stacktrace.rs b/libdd-crashtracker/src/crash_info/stacktrace.rs index 337c908c57..afd2b4646b 100644 --- a/libdd-crashtracker/src/crash_info/stacktrace.rs +++ b/libdd-crashtracker/src/crash_info/stacktrace.rs @@ -324,7 +324,7 @@ pub enum FileType { #[cfg(unix)] fn byte_slice_as_hex(bv: &[u8]) -> String { - use std::fmt::Write; + use core::fmt::Write; let mut s = String::with_capacity(bv.len() * 2); for byte in bv { diff --git a/libdd-crashtracker/src/crash_info/telemetry.rs b/libdd-crashtracker/src/crash_info/telemetry.rs index 3d92b6efa8..e35aa46639 100644 --- a/libdd-crashtracker/src/crash_info/telemetry.rs +++ b/libdd-crashtracker/src/crash_info/telemetry.rs @@ -1,6 +1,7 @@ // Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 -use std::{fmt::Write, time::SystemTime}; +use core::fmt::Write; +use std::time::SystemTime; use crate::{ErrorKind, SigInfo}; @@ -372,7 +373,7 @@ impl TelemetryCrashUploader { .body(serde_json::to_string(&payload)?.into())?; tokio::time::timeout( - std::time::Duration::from_millis({ + core::time::Duration::from_millis({ if let Some(endp) = self.cfg.endpoint() { endp.timeout_ms } else { diff --git a/libdd-crashtracker/src/lib.rs b/libdd-crashtracker/src/lib.rs index 475664297d..71ae5a4fc7 100644 --- a/libdd-crashtracker/src/lib.rs +++ b/libdd-crashtracker/src/lib.rs @@ -50,6 +50,8 @@ #![cfg_attr(not(test), deny(clippy::todo))] #![cfg_attr(not(test), deny(clippy::unimplemented))] +extern crate alloc; + #[cfg(all(unix, feature = "collector"))] mod collector; #[cfg(all(windows, feature = "collector_windows"))] diff --git a/libdd-crashtracker/src/receiver/mod.rs b/libdd-crashtracker/src/receiver/mod.rs index 1265cfca66..8b3f636726 100644 --- a/libdd-crashtracker/src/receiver/mod.rs +++ b/libdd-crashtracker/src/receiver/mod.rs @@ -1,6 +1,7 @@ // Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 #![cfg(unix)] +#![allow(clippy::std_instead_of_alloc, clippy::std_instead_of_core)] mod entry_points; pub use entry_points::{ diff --git a/libdd-crashtracker/src/runtime_callback.rs b/libdd-crashtracker/src/runtime_callback.rs index d89af02123..e09f02673c 100644 --- a/libdd-crashtracker/src/runtime_callback.rs +++ b/libdd-crashtracker/src/runtime_callback.rs @@ -7,21 +7,21 @@ //! callbacks that can provide runtime-specific stack traces during crash handling. use crate::crash_info::StackFrame; +use core::ffi::c_char; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::ffi::c_char; #[cfg(unix)] -use std::{ +use core::{ ptr, sync::atomic::{AtomicPtr, Ordering}, }; use thiserror::Error; #[cfg(unix)] -static FRAME_CSTR: &std::ffi::CStr = c"frame"; +static FRAME_CSTR: &core::ffi::CStr = c"frame"; #[cfg(unix)] -static STACKTRACE_STRING_CSTR: &std::ffi::CStr = c"stacktrace_string"; +static STACKTRACE_STRING_CSTR: &core::ffi::CStr = c"stacktrace_string"; #[cfg(unix)] #[derive(Debug)] @@ -169,10 +169,10 @@ pub(crate) unsafe fn get_registered_callback() -> Option { /// or registration functions concurrently, as those could invalidate /// the pointer between the null check and dereferencing. #[cfg(unix)] -pub unsafe fn get_registered_callback_type_ptr() -> *const std::ffi::c_char { +pub unsafe fn get_registered_callback_type_ptr() -> *const core::ffi::c_char { let callback_ptr = RUNTIME_CALLBACK.load(Ordering::SeqCst); if callback_ptr.is_null() { - return std::ptr::null(); + return core::ptr::null(); } // Safety: callback_ptr was checked to be non-null above, and was created by @@ -196,7 +196,7 @@ pub unsafe fn get_registered_callback_type_ptr() -> *const std::ffi::c_char { /// - The callback is not being used in any other way #[cfg(unix)] pub unsafe fn clear_runtime_callback() { - let old_ptr = RUNTIME_CALLBACK.swap(std::ptr::null_mut(), Ordering::SeqCst); + let old_ptr = RUNTIME_CALLBACK.swap(core::ptr::null_mut(), Ordering::SeqCst); if !old_ptr.is_null() { // Safety: old_ptr was created by Box::into_raw() in register_runtime_stack_callback(), // so it's a valid Box pointer. We reconstruct the Box to properly drop the tuple. @@ -224,7 +224,7 @@ pub(crate) unsafe fn invoke_runtime_callback_with_writer( } let callback_data = &*callback_ptr; - CURRENT_WRITER = Some(std::mem::transmute::< + CURRENT_WRITER = Some(core::mem::transmute::< &mut dyn std::io::Write, &'static mut dyn std::io::Write, >(writer)); @@ -243,7 +243,7 @@ pub(crate) unsafe fn invoke_runtime_callback_with_writer( if let Some(ref mut writer) = CURRENT_WRITER { // SAFETY: the runtime guarantees a valid, null-terminated C string. - let cstr = std::ffi::CStr::from_ptr(stacktrace_string); + let cstr = core::ffi::CStr::from_ptr(stacktrace_string); let bytes = cstr.to_bytes(); let _ = writer.write_all(bytes); let _ = writeln!(writer); @@ -353,7 +353,7 @@ mod tests { unsafe extern "C" fn test_emit_stacktrace_string_callback( emit_stacktrace_string: unsafe extern "C" fn(*const c_char), ) { - let stacktrace_string = std::ffi::CString::new("test_stacktrace_string").unwrap(); + let stacktrace_string = alloc::ffi::CString::new("test_stacktrace_string").unwrap(); emit_stacktrace_string(stacktrace_string.as_ptr()); } diff --git a/libdd-crashtracker/src/shared/configuration/builder.rs b/libdd-crashtracker/src/shared/configuration/builder.rs index c4773d0fbd..a893bb7319 100644 --- a/libdd-crashtracker/src/shared/configuration/builder.rs +++ b/libdd-crashtracker/src/shared/configuration/builder.rs @@ -1,9 +1,9 @@ // Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 use crate::{default_signals, shared::constants, signal_from_signum}; +use alloc::borrow::Cow; +use core::time::Duration; use libdd_common::Endpoint; -use std::borrow::Cow; -use std::time::Duration; use super::{default_max_threads, CrashtrackerConfiguration, StacktraceCollection}; @@ -168,7 +168,7 @@ impl CrashtrackerConfigurationBuilder { mod tests { use super::*; use crate::{default_signals, shared::constants}; - use std::time::Duration; + use core::time::Duration; #[test] fn test_build_defaults() -> anyhow::Result<()> { diff --git a/libdd-crashtracker/src/shared/configuration/mod.rs b/libdd-crashtracker/src/shared/configuration/mod.rs index 96a075f79f..b5104cb626 100644 --- a/libdd-crashtracker/src/shared/configuration/mod.rs +++ b/libdd-crashtracker/src/shared/configuration/mod.rs @@ -3,9 +3,9 @@ // mod builder; pub use builder::CrashtrackerConfigurationBuilder; +use core::time::Duration; use libdd_common::Endpoint; use serde::{Deserialize, Serialize}; -use std::time::Duration; /// Stacktrace collection occurs in the context of a crashing process. /// If the stack is sufficiently corruputed, it is possible (but unlikely), diff --git a/libdd-crashtracker/src/shared/constants.rs b/libdd-crashtracker/src/shared/constants.rs index 09999300f7..0883543fd7 100644 --- a/libdd-crashtracker/src/shared/constants.rs +++ b/libdd-crashtracker/src/shared/constants.rs @@ -1,7 +1,7 @@ // Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 -use std::time::Duration; +use core::time::Duration; pub const DD_CRASHTRACK_BEGIN_ADDITIONAL_TAGS: &str = "DD_CRASHTRACK_BEGIN_ADDITIONAL_TAGS"; pub const DD_CRASHTRACK_BEGIN_CONFIG: &str = "DD_CRASHTRACK_BEGIN_CONFIG"; diff --git a/libdd-library-config-ffi/Cargo.toml b/libdd-library-config-ffi/Cargo.toml index a8b7bd26e0..a751035173 100644 --- a/libdd-library-config-ffi/Cargo.toml +++ b/libdd-library-config-ffi/Cargo.toml @@ -29,3 +29,7 @@ build_common = { path = "../build-common" } [dev-dependencies] tempfile = { version = "3.3" } + +[lints.clippy] +std_instead_of_alloc = "warn" +std_instead_of_core = "warn" diff --git a/libdd-library-config-ffi/src/lib.rs b/libdd-library-config-ffi/src/lib.rs index 9e53349f9d..a22ad4a99e 100644 --- a/libdd-library-config-ffi/src/lib.rs +++ b/libdd-library-config-ffi/src/lib.rs @@ -1,13 +1,17 @@ // Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +extern crate alloc; + pub mod tracer_metadata; use libdd_common_ffi::{self as ffi, slice::AsBytes, CString, CharSlice, Error}; use libdd_library_config::{self as lib_config, LibraryConfigSource}; #[cfg(all(feature = "catch_panic", panic = "unwind"))] -use std::panic::{catch_unwind, AssertUnwindSafe}; +use core::panic::AssertUnwindSafe; +#[cfg(all(feature = "catch_panic", panic = "unwind"))] +use std::panic::catch_unwind; #[cfg(all(feature = "catch_panic", panic = "unwind"))] macro_rules! catch_panic { @@ -87,15 +91,15 @@ impl LibraryConfig { .into_iter() .map(|c| { Ok(LibraryConfig { - name: ffi::CString::from_std(std::ffi::CString::new(c.name)?), - value: ffi::CString::from_std(std::ffi::CString::new(c.value)?), + name: ffi::CString::from_std(alloc::ffi::CString::new(c.name)?), + value: ffi::CString::from_std(alloc::ffi::CString::new(c.value)?), source: c.source, - config_id: ffi::CString::from_std(std::ffi::CString::new( + config_id: ffi::CString::from_std(alloc::ffi::CString::new( c.config_id.unwrap_or_default(), )?), }) }) - .collect::, std::ffi::NulError>>()?; + .collect::, alloc::ffi::NulError>>()?; Ok(ffi::Vec::from_std(cfg)) } @@ -238,7 +242,7 @@ pub extern "C" fn ddog_library_config_fleet_stable_config_path() -> ffi::CStr<'s lib_config::Configurator::FLEET_STABLE_CONFIGURATION_PATH, "\0" ); - std::ffi::CStr::from_bytes_with_nul_unchecked(path.as_bytes()) + core::ffi::CStr::from_bytes_with_nul_unchecked(path.as_bytes()) }) } @@ -251,7 +255,7 @@ pub extern "C" fn ddog_library_config_local_stable_config_path() -> ffi::CStr<'s lib_config::Configurator::LOCAL_STABLE_CONFIGURATION_PATH, "\0" ); - std::ffi::CStr::from_bytes_with_nul_unchecked(path.as_bytes()) + core::ffi::CStr::from_bytes_with_nul_unchecked(path.as_bytes()) }) } diff --git a/libdd-library-config-ffi/src/tracer_metadata.rs b/libdd-library-config-ffi/src/tracer_metadata.rs index f4d3f6530f..6fbb22ad75 100644 --- a/libdd-library-config-ffi/src/tracer_metadata.rs +++ b/libdd-library-config-ffi/src/tracer_metadata.rs @@ -1,11 +1,11 @@ // Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use core::ffi::CStr; use libdd_common_ffi::Result; #[cfg(target_os = "linux")] use libdd_library_config::tracer_metadata::AnonymousFileHandle; use libdd_library_config::tracer_metadata::{self, TracerMetadata}; -use std::ffi::CStr; use std::os::raw::{c_char, c_int}; /// C-compatible representation of an anonymous file handle diff --git a/libdd-library-config/Cargo.toml b/libdd-library-config/Cargo.toml index 909a3a25c5..2c150735fb 100644 --- a/libdd-library-config/Cargo.toml +++ b/libdd-library-config/Cargo.toml @@ -36,3 +36,7 @@ serial_test = "3.2" [target.'cfg(unix)'.dependencies] memfd = { version = "0.6" } libc = "0.2" + +[lints.clippy] +std_instead_of_alloc = "warn" +std_instead_of_core = "warn" diff --git a/libdd-library-config/src/lib.rs b/libdd-library-config/src/lib.rs index f243678c09..6d473f1d84 100644 --- a/libdd-library-config/src/lib.rs +++ b/libdd-library-config/src/lib.rs @@ -1,14 +1,15 @@ // Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +extern crate alloc; + pub mod otel_process_ctx; pub mod tracer_metadata; -use std::borrow::Cow; -use std::cell::OnceCell; +use alloc::borrow::Cow; +use core::{cell::OnceCell, mem, ops::Deref}; use std::collections::HashMap; -use std::ops::Deref; use std::path::Path; -use std::{env, fs, io, mem}; +use std::{env, fs, io}; /// This struct holds maps used to match and template configurations. /// @@ -30,7 +31,7 @@ impl<'a> MatchMaps<'a> { self.env_map.get_or_init(|| { let mut map = HashMap::new(); for e in &process_info.envp { - let Ok(s) = std::str::from_utf8(e.deref()) else { + let Ok(s) = core::str::from_utf8(e.deref()) else { continue; }; let (k, v) = match s.split_once('=') { @@ -47,7 +48,7 @@ impl<'a> MatchMaps<'a> { self.args_map.get_or_init(|| { let mut map = HashMap::new(); for arg in &process_info.args { - let Ok(arg) = std::str::from_utf8(arg.deref()) else { + let Ok(arg) = core::str::from_utf8(arg.deref()) else { continue; }; // Split args between key and value on '=' @@ -145,7 +146,7 @@ impl<'a> Matcher<'a> { template_map_key(index, self.match_maps.args(self.process_info)) } "tags" => template_map_key(index, self.match_maps.tags), - _ => std::borrow::Cow::Borrowed("UNDEFINED"), + _ => alloc::borrow::Cow::Borrowed("UNDEFINED"), }; templated.push_str(&val); rest = tail; @@ -257,7 +258,7 @@ impl<'de> serde::Deserialize<'de> for ConfigMap { impl<'de> serde::de::Visitor<'de> for ConfigMapVisitor { type Value = ConfigMap; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { formatter.write_str("struct ConfigMap(HashMap)") } diff --git a/libdd-library-config/src/otel_process_ctx.rs b/libdd-library-config/src/otel_process_ctx.rs index b0f46caa97..d14beb7bb1 100644 --- a/libdd-library-config/src/otel_process_ctx.rs +++ b/libdd-library-config/src/otel_process_ctx.rs @@ -14,17 +14,17 @@ #[cfg(target_os = "linux")] #[cfg(target_has_atomic = "64")] pub mod linux { - use std::{ + use core::{ ffi::{c_void, CStr}, - mem::ManuallyDrop, - os::fd::{AsRawFd, FromRawFd, OwnedFd}, + mem::{swap, ManuallyDrop}, ptr::{self, addr_of_mut}, - sync::{ - atomic::{fence, AtomicU64, Ordering}, - Mutex, MutexGuard, - }, + sync::atomic::{fence, AtomicU64, Ordering}, time::Duration, }; + use std::{ + os::fd::{AsRawFd, FromRawFd, OwnedFd}, + sync::{Mutex, MutexGuard}, + }; use anyhow::Context; @@ -435,7 +435,7 @@ pub mod linux { // // To do so, we get the old handler back in `local_handler` and prevent `mapping` // from being dropped specifically. - std::mem::swap(&mut local_handler, handler); + swap(&mut local_handler, handler); let _: ManuallyDrop = ManuallyDrop::new(local_handler.mapping); Ok(()) @@ -466,11 +466,14 @@ pub mod linux { mod tests { use super::MappingHeader; use anyhow::ensure; + use core::{ + ptr::{self, addr_of_mut}, + sync::atomic::{fence, AtomicU64, Ordering}, + time::Duration, + }; use std::{ fs::File, io::{BufRead, BufReader}, - ptr::{self, addr_of_mut}, - sync::atomic::{fence, AtomicU64, Ordering}, }; /// Parses the start address from a /proc/self/maps line @@ -553,7 +556,7 @@ pub mod linux { let mapping_addr = find_otel_mapping()?; let header_ptr = verify_mapping_at(mapping_addr)?; // Safety: the pointer returned by `verify_mapping_at` points to an initialized header - Ok(unsafe { std::ptr::read(header_ptr) }) + Ok(unsafe { ptr::read(header_ptr) }) } #[test] @@ -569,7 +572,7 @@ pub mod linux { // Safety: the published context must have put valid bytes of size payload_size in the // context if the signature check succeded. let read_payload = unsafe { - std::slice::from_raw_parts(header.payload_ptr, header.payload_size as usize) + core::slice::from_raw_parts(header.payload_ptr, header.payload_size as usize) }; assert!(header.signature == *super::SIGNATURE, "wrong signature"); @@ -589,7 +592,7 @@ pub mod linux { let published_at_ns_v1 = header.monotonic_published_at_ns; // Ensure the clock advances so the updated timestamp is strictly greater - std::thread::sleep(std::time::Duration::from_nanos(10)); + std::thread::sleep(Duration::from_nanos(10)); super::publish_raw_payload(payload_v2.as_bytes().to_vec()) .expect("couldn't update the process context"); @@ -598,7 +601,7 @@ pub mod linux { // Safety: the published context must have put valid bytes of size payload_size in the // context if the signature check succeded. let read_payload = unsafe { - std::slice::from_raw_parts(header.payload_ptr, header.payload_size as usize) + core::slice::from_raw_parts(header.payload_ptr, header.payload_size as usize) }; assert!(header.signature == *super::SIGNATURE, "wrong signature"); diff --git a/libdd-library-config/src/tracer_metadata.rs b/libdd-library-config/src/tracer_metadata.rs index 3697e717b7..55cd56e56b 100644 --- a/libdd-library-config/src/tracer_metadata.rs +++ b/libdd-library-config/src/tracer_metadata.rs @@ -1,7 +1,7 @@ // Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use core::default::Default; use libdd_trace_protobuf::opentelemetry::proto as otel_proto; -use std::default::Default; /// Thread-level context metadata the tracer wants to publish as part of the OTel process context. /// Set [TracerMetadata::threadlocal_metadata] to `Some(_)` to enable the threadlocal section; the @@ -167,7 +167,7 @@ impl TracerMetadata { key: "threadlocal.attribute_key_map".to_owned(), value: Some(AnyValue { value: Some(any_value::Value::ArrayValue(ArrayValue { - values: std::iter::once(AnyValue { + values: core::iter::once(AnyValue { value: Some(any_value::Value::StringValue( "datadog.local_root_span_id".to_owned(), )), diff --git a/libdd-trace-obfuscation/benches/benchmarks/credit_cards_bench.rs b/libdd-trace-obfuscation/benches/benchmarks/credit_cards_bench.rs index 02520efdfd..ce0967dd57 100644 --- a/libdd-trace-obfuscation/benches/benchmarks/credit_cards_bench.rs +++ b/libdd-trace-obfuscation/benches/benchmarks/credit_cards_bench.rs @@ -1,8 +1,8 @@ // Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 -use std::hint::black_box; -use std::time::Duration; +use core::hint::black_box; +use core::time::Duration; use criterion::Throughput::Elements; use criterion::{criterion_group, BatchSize, BenchmarkId, Criterion}; diff --git a/libdd-trace-obfuscation/benches/benchmarks/ip_address_bench.rs b/libdd-trace-obfuscation/benches/benchmarks/ip_address_bench.rs index 5da38048cf..b5c0a1d4f3 100644 --- a/libdd-trace-obfuscation/benches/benchmarks/ip_address_bench.rs +++ b/libdd-trace-obfuscation/benches/benchmarks/ip_address_bench.rs @@ -1,9 +1,9 @@ // Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use alloc::borrow::Cow; use criterion::{black_box, criterion_group, Criterion}; use libdd_trace_obfuscation::ip_address; -use std::borrow::Cow; fn quantize_peer_ip_address_benchmark(c: &mut Criterion) { let mut group = c.benchmark_group("ip_address"); diff --git a/libdd-trace-obfuscation/benches/trace_obfuscation.rs b/libdd-trace-obfuscation/benches/trace_obfuscation.rs index f18ba5f9e1..100bb1bbfa 100644 --- a/libdd-trace-obfuscation/benches/trace_obfuscation.rs +++ b/libdd-trace-obfuscation/benches/trace_obfuscation.rs @@ -1,6 +1,8 @@ // Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +extern crate alloc; + use criterion::criterion_main; mod benchmarks; diff --git a/libdd-trace-obfuscation/src/http.rs b/libdd-trace-obfuscation/src/http.rs index bfedd3234f..c3cc86a707 100644 --- a/libdd-trace-obfuscation/src/http.rs +++ b/libdd-trace-obfuscation/src/http.rs @@ -5,9 +5,9 @@ // restrictive on the accepted forms of urls so that this module can be greatly simplified. // One idea for now is to match the url to a regex on both side to validate it +use core::fmt::Write; use fluent_uri::UriRef; use percent_encoding::percent_decode_str; -use std::fmt::Write; /// Returns true for Go net/url's "category 1" characters: /// ASCII bytes that always trigger escaping in URLs (plus space and quote). diff --git a/libdd-trace-obfuscation/src/ip_address.rs b/libdd-trace-obfuscation/src/ip_address.rs index 2395e5b414..d734a28867 100644 --- a/libdd-trace-obfuscation/src/ip_address.rs +++ b/libdd-trace-obfuscation/src/ip_address.rs @@ -1,8 +1,10 @@ // Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use alloc::borrow::Cow; +use core::net::Ipv6Addr; use libdd_common::regex_engine::Regex; -use std::{borrow::Cow, collections::HashSet, net::Ipv6Addr, sync::LazyLock}; +use std::{collections::HashSet, sync::LazyLock}; const ALLOWED_IP_ADDRESSES: [&str; 5] = [ // localhost diff --git a/libdd-trace-obfuscation/src/json/mod.rs b/libdd-trace-obfuscation/src/json/mod.rs index 9187926623..6618057f1e 100644 --- a/libdd-trace-obfuscation/src/json/mod.rs +++ b/libdd-trace-obfuscation/src/json/mod.rs @@ -181,7 +181,7 @@ mod tests { enabled: true, keep_keys: keep_keys .iter() - .map(std::string::ToString::to_string) + .map(alloc::string::ToString::to_string) .collect(), ..Default::default() }) @@ -192,11 +192,11 @@ mod tests { enabled: true, keep_keys: keep_keys .iter() - .map(std::string::ToString::to_string) + .map(alloc::string::ToString::to_string) .collect(), transform_keys: transform_keys .iter() - .map(std::string::ToString::to_string) + .map(alloc::string::ToString::to_string) .collect(), transformer: Some(obfuscate_sql_string), }) diff --git a/libdd-trace-obfuscation/src/lib.rs b/libdd-trace-obfuscation/src/lib.rs index d09afe6cd8..5da50c7a15 100644 --- a/libdd-trace-obfuscation/src/lib.rs +++ b/libdd-trace-obfuscation/src/lib.rs @@ -1,5 +1,7 @@ // Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +extern crate alloc; + pub mod credit_cards; pub mod http; pub mod ip_address; diff --git a/libdd-trace-obfuscation/src/obfuscation_config.rs b/libdd-trace-obfuscation/src/obfuscation_config.rs index 093df204f3..67f5526274 100644 --- a/libdd-trace-obfuscation/src/obfuscation_config.rs +++ b/libdd-trace-obfuscation/src/obfuscation_config.rs @@ -106,7 +106,7 @@ impl ObfuscationConfig { /// # Errors /// /// Returns an error if one of the regular expressions used by the config cannot be compiled. - pub fn new() -> Result> { + pub fn new() -> Result> { let tag_replace_rules: Option> = match env::var("DD_APM_REPLACE_TAGS") { Ok(replace_rules_str) => match replacer::parse_rules_from_string(&replace_rules_str) { Ok(res) => { diff --git a/libdd-trace-obfuscation/src/replacer.rs b/libdd-trace-obfuscation/src/replacer.rs index e3c8bf5ca2..6f560f3ceb 100644 --- a/libdd-trace-obfuscation/src/replacer.rs +++ b/libdd-trace-obfuscation/src/replacer.rs @@ -192,7 +192,7 @@ fn replace_all( } scratch_space.push_str(&haystack[last_match..]); } - std::mem::swap(scratch_space, haystack); + core::mem::swap(scratch_space, haystack); scratch_space.truncate(0); } diff --git a/libdd-trace-obfuscation/src/sql.rs b/libdd-trace-obfuscation/src/sql.rs index 1453d19180..0f213d3326 100644 --- a/libdd-trace-obfuscation/src/sql.rs +++ b/libdd-trace-obfuscation/src/sql.rs @@ -2276,7 +2276,7 @@ fn normalize_plan_sql(s: &str) -> String { #[cfg(test)] mod tests { use super::{DbmsKind, SqlObfuscateConfig, SqlObfuscationMode}; - use std::fmt::Write; + use core::fmt::Write; #[test] fn test_sql_obfuscation() { diff --git a/libdd-trace-obfuscation/tests/test_span_obfuscation.rs b/libdd-trace-obfuscation/tests/test_span_obfuscation.rs index 8b13f6c779..5127ca3056 100644 --- a/libdd-trace-obfuscation/tests/test_span_obfuscation.rs +++ b/libdd-trace-obfuscation/tests/test_span_obfuscation.rs @@ -9,10 +9,11 @@ clippy::format_push_string )] -use std::{ - collections::{BTreeSet, HashSet}, - fmt::{self, Display}, -}; +extern crate alloc; + +use alloc::{collections::BTreeSet, fmt}; +use core::fmt::Display; +use std::collections::HashSet; use libdd_trace_obfuscation::{obfuscate::obfuscate_span, obfuscation_config::ObfuscationConfig}; use libdd_trace_protobuf::pb::{ @@ -153,7 +154,7 @@ impl<'a> SpanComparison<'a> { } } impl Display for SpanComparison<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { fn cmp_field(left: &T, right: &T) -> String { if left == right { format!("{left:?}")