Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
GenericPlatformMallocCrash.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"
6#include "HAL/CriticalSection.h"
7#include "HAL/MemoryBase.h"
8
9struct FMallocCrashPool;
10struct FPoolDesc;
11
12/** Describes a pointer. */
14{
15 /** Size of the allocation. */
16 uint64 Size;
17 /** Address of the allocation. */
18 uint8* Ptr;
19
21 /** Explicit padding for 32 bit builds */
22 uint8 Padding[4];
23#endif
24
26 Size(0),
27 Ptr(0)
28 {}
29
30 FPtrInfo( void* NewPtr ):
31 Size(0),
32 Ptr((uint8*)NewPtr)
33 {}
34};
35
36struct FMallocCrashPool;
37struct FPoolDesc;
38
39/**
40 * Simple pooled memory allocator that uses preallocated memory.
41 * Instance of this class replaces GMalloc after a crash, so we can use dynamic memory allocation even if the app crashes due to OOM.
42 */
43struct FGenericPlatformMallocCrash final : public FMalloc
44{
45 friend struct FPoolDesc;
46 friend struct FMallocCrashPool;
47
48 enum
49 {
50 LARGE_MEMORYPOOL_SIZE = 2 * 1024 * 1024,
52
55
56 MEM_TAG = 0xfe,
58 };
59
60public:
63
64 /** Creates a new instance. */
65 static FGenericPlatformMallocCrash& Get( FMalloc* MainMalloc = nullptr );
66
67 /**
68 * Sets as GMalloc.
69 * This method locks to the thread that crashed.
70 * Any next calls to this method or GMalloc from other threads will dead-lock those threads,
71 * but this is ok, because we are shutting down.
72 * This also fixes a lot of potential issues of using dynamic allocation during crash dumping.
73 *
74 * @warning
75 * This is not super safe, may interfere with other allocations, ie. replacing vtable during running
76 * the code from the previous malloc will probably crash other threads.
77 */
79
80 // FMalloc interface.
81 virtual void* Malloc( SIZE_T Size, uint32 Alignment ) override;
82
83 virtual void* Realloc( void* Ptr, SIZE_T NewSize, uint32 Alignment ) override;
84
85 virtual void Free( void* /*Ptr*/ ) override;
86
87 virtual bool GetAllocationSize( void *Original, SIZE_T &SizeOut ) override;
88
89 virtual bool IsInternallyThreadSafe() const override
90 {
91 return true;
92 }
93
94 virtual bool ValidateHeap() override
95 {
96 // Nothing to do here.
97 return true;
98 }
99
100 virtual const TCHAR * GetDescriptiveName() override
101 {
102 return TEXT( "MallocCrash" );
103 }
104
106
107protected:
108 /** Whether it is safe to call crash malloc's methods. */
109 bool IsOnCrashedThread() const;
110
111 bool IsPtrInLargePool(void* Ptr) const;
112 bool IsPtrInSmallPool(void* Ptr) const;
113
114 const FPoolDesc& GetPoolDesc( uint32 Index ) const;
117
119
120 // Choose a pool to make a new allocation from of the given size - may use a larger pool than necessary if small pools are exhausted.
121 FMallocCrashPool* ChoosePoolForSize( uint32 AllocationSize ) const;
122 // Find the pool that an allocation was made from if any.
123 FMallocCrashPool* FindPoolForAlloc(void* Ptr) const;
124 uint8* AllocateFromBookkeeping(uint32 AllocationSize);
125 uint8* AllocateFromSmallPool( uint32 AllocationSize );
126
127 uint64 GetAllocationSize(void *Original);
128
129 /**
130 * @return page size, if page size is not initialized, returns 64k.
131 */
132 static uint32 SafePageSize();
133
134protected:
135 /** Used to lock crash malloc to one thread. */
137
138 /** The id of the thread that crashed. */
140
141 /** Preallocated memory pool for large allocations. */
142 uint8* LargeMemoryPool = nullptr;
143
144 /** Current position in the large memory pool. */
146
147 /** Preallocated memory pool for small allocations. */
148 uint8* SmallMemoryPool = nullptr;
149
150 /** Current position in the small memory pool. */
153
154 /** Preallocated memory pool for bookkeeping. */
155 uint8* BookkeepingPool = nullptr;
156
157 /** Current position in the bookkeeping pool. */
160
161 /** Previously used malloc. */
163};
164
165
166
167
168
170{
173
174 /** Creates a new instance. */
175 static FGenericStackBasedMallocCrash& Get(FMalloc* MainMalloc = nullptr);
176
178
179 virtual void* Malloc(SIZE_T Size, uint32 Alignment) override;
180
181 virtual void* Realloc(void* Ptr, SIZE_T NewSize, uint32 Alignment) override;
182
183 virtual void Free(void* /*Ptr*/) override;
184
185 virtual const TCHAR * GetDescriptiveName() override
186 {
187 return TEXT("FGenericStackBasedMallocCrash");
188 }
189
190private:
191 enum
192 {
193 MEMORYPOOL_SIZE = 256 * 1024
194 };
195
198};
#define TEXT(x)
Definition Platform.h:1108
#define PLATFORM_32BITS
Definition Platform.h:629
FWindowsCriticalSection FCriticalSection
uint64 GetAllocationSize(void *Original)
uint32 CalculateSmallPoolTotalSize() const
uint32 CalculateBookkeepingPoolTotalSize() const
static FGenericPlatformMallocCrash & Get(FMalloc *MainMalloc=nullptr)
const FPoolDesc & GetPoolDesc(uint32 Index) const
virtual const TCHAR * GetDescriptiveName() override
virtual bool IsInternallyThreadSafe() const override
uint8 * AllocateFromSmallPool(uint32 AllocationSize)
static uint32 SafePageSize()
virtual void * Malloc(SIZE_T Size, uint32 Alignment) override
uint8 * AllocateFromBookkeeping(uint32 AllocationSize)
FMallocCrashPool * FindPoolForAlloc(void *Ptr) const
virtual ~FGenericPlatformMallocCrash()
virtual void Free(void *) override
virtual bool GetAllocationSize(void *Original, SIZE_T &SizeOut) override
FGenericPlatformMallocCrash(FMalloc *MainMalloc)
bool IsPtrInLargePool(void *Ptr) const
bool IsPtrInSmallPool(void *Ptr) const
virtual void * Realloc(void *Ptr, SIZE_T NewSize, uint32 Alignment) override
FMallocCrashPool * ChoosePoolForSize(uint32 AllocationSize) const
virtual const TCHAR * GetDescriptiveName() override
FGenericStackBasedMallocCrash(FMalloc *MainMalloc)
virtual void * Realloc(void *Ptr, SIZE_T NewSize, uint32 Alignment) override
static FGenericStackBasedMallocCrash & Get(FMalloc *MainMalloc=nullptr)
virtual void Free(void *) override
virtual void * Malloc(SIZE_T Size, uint32 Alignment) override
FPtrInfo(void *NewPtr)