1
+ /* ****************************************************************************
2
+ *
3
+ * PROJECT: Multi Theft Auto v1.0
4
+ * LICENSE: See LICENSE in the top level directory
5
+ * FILE: multiplayer_sa/CMemoryAllocatorDiagnostics.h
6
+ * PURPOSE: Memory allocator diagnostic logging system
7
+ *
8
+ * Multi Theft Auto is available from https://www.multitheftauto.com/
9
+ *
10
+ *****************************************************************************/
11
+
12
+ #pragma once
13
+
14
+ #include < cstddef> // For std::size_t
15
+ #include < cstdint> // For std::uintptr_t
16
+
17
+ namespace mta
18
+ {
19
+ namespace memory
20
+ {
21
+ namespace diagnostics
22
+ {
23
+ // Check if memory allocation debugging should be enabled
24
+ // Returns true in debug builds OR when user has enabled EDiagnosticDebug::BAD_ALLOC (#0000 Memory allocation debug) in MTA advanced settings > "Debug setting:"
25
+ bool IsMemoryAllocationDebuggingEnabled () noexcept ;
26
+
27
+ // Core diagnostic logging function
28
+ void LogAllocationFailure (const char * reason, void * ptr = nullptr , std::size_t size = 0 , std::size_t alignment = 0 ,
29
+ void * caller = nullptr ) noexcept ;
30
+
31
+ // Specialized logging functions for different failure scenarios
32
+ void LogHeapAllocationFailure (const char * reason, void * ptr, std::size_t size, std::size_t alignment, void * caller) noexcept ;
33
+ void LogVirtualAllocFailure (const char * reason, void * ptr, std::size_t size, std::size_t alignment, void * caller) noexcept ;
34
+ void LogSafetyRejection (const char * reason, void * ptr, std::size_t size, std::size_t alignment, const char * safety_condition,
35
+ void * caller) noexcept ;
36
+ void LogCriticalSystemFailure (const char * reason, void * ptr, std::size_t size, std::size_t alignment, void * caller) noexcept ;
37
+
38
+ // Memory pressure analysis
39
+ void LogMemoryPressureDetails () noexcept ;
40
+ }
41
+ }
42
+ }
43
+
44
+ // Conditional compilation macros for diagnostic logging
45
+ // These provide zero overhead when diagnostics are disabled
46
+ #if defined(MTA_DEBUG) || defined(MTA_ENABLE_DIAGNOSTIC_LOGGING) || defined(DEBUG) || defined(_DEBUG)
47
+ #include < intrin.h> // For _ReturnAddress() intrinsic
48
+
49
+ // Debug builds: always enabled
50
+ #if defined(MTA_DEBUG) || defined(DEBUG) || defined(_DEBUG)
51
+ #define MTA_MEMORY_LOG_ALLOCATION_FAILURE (reason, ptr, size, alignment ) \
52
+ mta::memory::diagnostics::LogAllocationFailure (reason, ptr, size, alignment, _ReturnAddress())
53
+
54
+ #define MTA_MEMORY_LOG_DEALLOCATION_FAILURE (reason, ptr) \
55
+ mta::memory::diagnostics::LogAllocationFailure(reason, ptr, 0 , 0 , _ReturnAddress())
56
+
57
+ #define MTA_MEMORY_LOG_HEAP_FAILURE (reason, ptr, size, alignment) \
58
+ mta::memory::diagnostics::LogHeapAllocationFailure(reason, ptr, size, alignment, _ReturnAddress())
59
+
60
+ #define MTA_MEMORY_LOG_VIRTUAL_FAILURE (reason, ptr, size, alignment) \
61
+ mta::memory::diagnostics::LogVirtualAllocFailure(reason, ptr, size, alignment, _ReturnAddress())
62
+
63
+ #define MTA_MEMORY_LOG_SAFETY_REJECTION (reason, ptr, size, alignment, condition) \
64
+ mta::memory::diagnostics::LogSafetyRejection(reason, ptr, size, alignment, condition, _ReturnAddress())
65
+
66
+ #define MTA_MEMORY_LOG_CRITICAL_FAILURE (reason, ptr, size, alignment) \
67
+ mta::memory::diagnostics::LogCriticalSystemFailure(reason, ptr, size, alignment, _ReturnAddress())
68
+
69
+ // Release builds: conditional on user setting
70
+ #else
71
+ #define MTA_MEMORY_LOG_ALLOCATION_FAILURE (reason, ptr, size, alignment ) \
72
+ do { if (mta::memory::diagnostics::IsMemoryAllocationDebuggingEnabled ()) \
73
+ mta::memory::diagnostics::LogAllocationFailure (reason, ptr, size, alignment, _ReturnAddress ()); } while (0 )
74
+
75
+ #define MTA_MEMORY_LOG_DEALLOCATION_FAILURE (reason, ptr ) \
76
+ do { if (mta::memory::diagnostics::IsMemoryAllocationDebuggingEnabled ()) \
77
+ mta::memory::diagnostics::LogAllocationFailure (reason, ptr, 0 , 0 , _ReturnAddress ()); } while (0 )
78
+
79
+ #define MTA_MEMORY_LOG_HEAP_FAILURE (reason, ptr, size, alignment ) \
80
+ do { if (mta::memory::diagnostics::IsMemoryAllocationDebuggingEnabled ()) \
81
+ mta::memory::diagnostics::LogHeapAllocationFailure (reason, ptr, size, alignment, _ReturnAddress ()); } while (0 )
82
+
83
+ #define MTA_MEMORY_LOG_VIRTUAL_FAILURE (reason, ptr, size, alignment ) \
84
+ do { if (mta::memory::diagnostics::IsMemoryAllocationDebuggingEnabled ()) \
85
+ mta::memory::diagnostics::LogVirtualAllocFailure (reason, ptr, size, alignment, _ReturnAddress ()); } while (0 )
86
+
87
+ #define MTA_MEMORY_LOG_SAFETY_REJECTION (reason, ptr, size, alignment, condition ) \
88
+ do { if (mta::memory::diagnostics::IsMemoryAllocationDebuggingEnabled ()) \
89
+ mta::memory::diagnostics::LogSafetyRejection (reason, ptr, size, alignment, condition, _ReturnAddress ()); } while (0 )
90
+
91
+ #define MTA_MEMORY_LOG_CRITICAL_FAILURE (reason, ptr, size, alignment ) \
92
+ do { if (mta::memory::diagnostics::IsMemoryAllocationDebuggingEnabled ()) \
93
+ mta::memory::diagnostics::LogCriticalSystemFailure (reason, ptr, size, alignment, _ReturnAddress ()); } while (0 )
94
+ #endif
95
+
96
+ #else
97
+ // Release builds without diagnostic support: no-op macros for zero overhead
98
+ #define MTA_MEMORY_LOG_ALLOCATION_FAILURE (reason, ptr, size, alignment ) ((void )0 )
99
+ #define MTA_MEMORY_LOG_DEALLOCATION_FAILURE (reason, ptr ) ((void )0 )
100
+ #define MTA_MEMORY_LOG_HEAP_FAILURE (reason, ptr, size, alignment ) ((void )0 )
101
+ #define MTA_MEMORY_LOG_VIRTUAL_FAILURE (reason, ptr, size, alignment ) ((void )0 )
102
+ #define MTA_MEMORY_LOG_SAFETY_REJECTION (reason, ptr, size, alignment, condition ) ((void )0 )
103
+ #define MTA_MEMORY_LOG_CRITICAL_FAILURE (reason, ptr, size, alignment ) ((void )0 )
104
+
105
+ #endif // MTA_DEBUG || MTA_ENABLE_DIAGNOSTIC_LOGGING
0 commit comments