Skip to main content

ps_alloc/
error.rs

1use std::alloc::LayoutError;
2
3use thiserror::Error;
4
5/// Errors returned by [`crate::alloc`].
6#[derive(Debug, Error, PartialEq, Eq, Clone)]
7pub enum AllocationError {
8    /// The allocation size computation overflowed.
9    #[error("an arithmetic error occurred")]
10    ArithmeticError,
11    /// The requested size does not form a valid [`Layout`](std::alloc::Layout).
12    #[error(transparent)]
13    LayoutError(#[from] LayoutError),
14    /// The underlying allocator returned a null pointer.
15    #[error("process ran out of memory")]
16    OutOfMemory,
17}
18
19/// Errors returned by [`crate::free`].
20#[derive(Debug, Error, PartialEq, Eq, Clone)]
21pub enum DeallocationError {
22    /// The header matches neither marker: either memory corruption occurred, or the
23    /// pointer was not produced by this crate.
24    #[error("this allocation's marker is corrupted: either memory corruption occurred, or a pointer not allocated by this crate's alloc was passed to realloc or free")]
25    CorruptedMarker,
26    /// The allocation was already freed.
27    #[error("this memory was already freed")]
28    DoubleFree,
29    /// The pointer is not properly aligned.
30    #[error("the pointer provided was not properly aligned")]
31    ImproperAlignment,
32    /// The size stored in the header does not form a valid layout, which signals memory
33    /// corruption.
34    #[error(transparent)]
35    LayoutError(#[from] LayoutError),
36    /// The pointer is null.
37    #[error("tried to free a null pointer")]
38    NullPtr,
39}
40
41/// The ways a user pointer can fail validation, mapped into each public error enum.
42pub(crate) enum ValidationError {
43    ImproperAlignment,
44    MarkerFree,
45    MarkerCorrupted,
46}
47
48impl From<ValidationError> for DeallocationError {
49    fn from(error: ValidationError) -> Self {
50        match error {
51            ValidationError::ImproperAlignment => Self::ImproperAlignment,
52            ValidationError::MarkerFree => Self::DoubleFree,
53            ValidationError::MarkerCorrupted => Self::CorruptedMarker,
54        }
55    }
56}
57
58impl From<ValidationError> for ReallocationError {
59    fn from(error: ValidationError) -> Self {
60        match error {
61            ValidationError::ImproperAlignment => Self::ImproperAlignment,
62            ValidationError::MarkerFree => Self::MarkerFree,
63            ValidationError::MarkerCorrupted => Self::MarkerCorrupted,
64        }
65    }
66}
67
68/// Errors returned by [`crate::realloc`].
69#[derive(Debug, Error, PartialEq, Eq, Clone)]
70pub enum ReallocationError {
71    /// Computing the new size or allocating the new memory failed.
72    #[error(transparent)]
73    AllocationError(#[from] AllocationError),
74    /// Freeing failed; only `LayoutError` is reachable, and it signals memory corruption.
75    #[error(transparent)]
76    DeallocationError(#[from] DeallocationError),
77    /// The pointer is not properly aligned.
78    #[error("the pointer provided was not properly aligned")]
79    ImproperAlignment,
80    /// The pointer points to already freed memory.
81    #[error("the pointer provided points to already freed memory")]
82    MarkerFree,
83    /// The header matches neither marker: either memory corruption occurred, or the
84    /// pointer was not produced by this crate.
85    #[error("the pointer provided has a corrupted marker; was it allocated by this crate?")]
86    MarkerCorrupted,
87    /// The old pointer remains valid and must still be freed by the caller.
88    #[error("the new allocation failed, but your old pointer remains valid")]
89    NewAllocationFailed,
90}