UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
UnixForkPageProtector.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
7
8#if COMPILE_FORK_PAGE_PROTECTOR
9#include "Containers/Map.h"
10
11#include <sys/mman.h>
12
13namespace UE
14{
15/*
16 * Simple dynamic array that can only grow, avoids allocation code
17 * directly calls mmap this is to avoid recursive calls when collecting memory address
18 */
19template <typename T>
21{
22public:
24 {
25 Elements = static_cast<T*>(mmap(nullptr, Capacity * sizeof(T), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0));
26 }
27
29 {
30 munmap(Elements, Capacity);
31 }
32
33 void Emplace(T&& Elem)
34 {
35 // MMap most likely failed in the ctor, cant do much with out memory
36 if (Elements == nullptr)
37 {
38 return;
39 }
40
41 if (Size + 1 > Capacity)
42 {
43 SIZE_T OldCapacity = Capacity;
44 Capacity *= 2;
45
46 T* NewElements = static_cast<T*>(mmap(nullptr, Capacity * sizeof(T), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0));
47 T* OldElements = Elements;
48
49 // MMap has failed
50 if (NewElements == nullptr)
51 {
52 return;
53 }
54
55 FMemory::Memcpy(NewElements, Elements, Size * sizeof(T));
56 Elements = MoveTemp(NewElements);
57
58 munmap(OldElements, OldCapacity);
59 }
60
61 Elements[Size] = MoveTemp(Elem);
62 Size++;
63 }
64
65 T* begin() const
66 {
67 return Elements;
68 }
69
70 T* end() const
71 {
72 return Elements + Size;
73 }
74
75 T& Get(SIZE_T Index)
76 {
77 return *Elements[Index];
78 }
79
80 SIZE_T GetSize()
81 {
82 return Size;
83 }
84
85private:
86 SIZE_T Capacity = 1000U;
87 SIZE_T Size = 0U;
88 T* Elements = nullptr;
89};
90
91namespace
92{
93 struct FBlock;
94}
95
96/*
97 * Linked list allocator that knows if a given pointer was created by this allocator else a previous allocator
98 *
99 * Maintains a linked list of Blocks and each Block has linked list of FreeNodes
100 *
101 */
102class FMallocLinked : public FMalloc
103{
104public:
106
107 virtual ~FMallocLinked();
108
109 virtual void* Malloc(SIZE_T Size, uint32 Alignment) override;
110 virtual void* Realloc(void* Ptr, SIZE_T NewSize, uint32 Alignment) override;
111 virtual void Free(void* Ptr) override;
112 virtual const TCHAR * GetDescriptiveName() override;
113 virtual bool IsInternallyThreadSafe() const override;
114
115 void DebugVisualize();
116
117private:
118 bool OwnsPointer(void* Ptr) const;
119
120 FMalloc* PreviousMalloc = nullptr;
121 FBlock* Blocks = nullptr;
122
123 FCriticalSection AllocatorMutex;
124};
125
126class FForkPageProtector
127{
128public:
129 static FForkPageProtector& Get();
130
131 /*
132 * These functions are used on the parent to collect memory regions, as well as keep track of ones that were freed
133 */
134 void AddMemoryRegion(void* Address, uint64 Size);
135 void FreeMemoryRegion(void* Address);
136
137 /*
138 * This should be used right after fork protect all the memory regions collected above
139 * some may be missed, further consideration may be needed here
140 */
142
143 /*
144 * This should be used if all pages need to be reset to being unprotected
145 */
147
148 /*
149 * This function should only be called in the signal handler *after* the ProtectMemoryRegions function has been called
150 *
151 * Given a CrashAddress we will move that addresses page back to READ/WRITE
152 * As well as store information about the current callstack and other data
153 *
154 * Returns ture if the CrashAddress was handle
155 * if false this means some internal error or the same CrashAddress was sent twice in a row
156 */
158
159 /*
160 * Overrides GMalloc with our own allocator so we don't stomp on possible protected pages when allocating
161 */
162 static void OverrideGMalloc();
163
164private:
165 FForkPageProtector() = default;
167
168 void SetupOutputFile();
169
171
172 void SetupSignalHandler();
173
174 const FString& GetOutputFileLocation();
175
176 // The lower bit of the address will be set to 1 if free'ed
178 {
179 uint64 Address = 0U;
180 uint64 Size = 0U;
181 };
182
185
186 struct CallstackHashData
187 {
188 uint32 Count = 0U;
190 };
191
193
194 int ProtectedPagesFileFD = -1;
196 void* LastCrashAddress = nullptr;
197 bool bSetupSignalHandler = false;
198};
199#else
200namespace UE
201{
203{
204public:
206 {
208 return PageProtector;
209 }
210
211 void AddMemoryRegion(void* Address, uint64 Size) {}
212 void FreeMemoryRegion(void* Address) {}
215 bool HandleNewCrashAddress(void* CrashAddress) { return false; }
216
217 static void OverrideGMalloc() {}
218};
219#endif // COMPILE_FORK_PAGE_PROTECTOR
220} // namespace UE
FPlatformTypes::SIZE_T SIZE_T
An unsigned integer the same size as a pointer, the same as UPTRINT.
Definition Platform.h:1150
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
UE::FPlatformRecursiveMutex FCriticalSection
Definition CriticalSection.h:53
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32 Size
Definition VulkanMemory.cpp:4034
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition MemoryBase.h:99
Definition UnrealString.h.inl:34
Definition UnixForkPageProtector.h:203
void UnProtectMemoryRegions()
Definition UnixForkPageProtector.h:214
static FForkPageProtector & Get()
Definition UnixForkPageProtector.h:205
void ProtectMemoryRegions()
Definition UnixForkPageProtector.h:213
void FreeMemoryRegion(void *Address)
Definition UnixForkPageProtector.h:212
static void OverrideGMalloc()
Definition UnixForkPageProtector.h:217
bool HandleNewCrashAddress(void *CrashAddress)
Definition UnixForkPageProtector.h:215
void AddMemoryRegion(void *Address, uint64 Size)
Definition UnixForkPageProtector.h:211
FORCEINLINE T * Get(const FObjectPtr &ObjectPtr)
Definition ObjectPtr.h:426
FORCEINLINE FStridedReferenceIterator begin(FStridedReferenceView View)
Definition FastReferenceCollector.h:490
FORCEINLINE FStridedReferenceIterator end(FStridedReferenceView View)
Definition FastReferenceCollector.h:491
Definition AdvancedWidgetsModule.cpp:13
U16 Index
Definition radfft.cpp:71
static UE_FORCEINLINE_HINT void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
Definition UnrealMemory.h:160