4
5
9#include "Containers/Array.h"
10#include "Containers/Map.h"
11#include "Containers/Set.h"
12#include "Containers/UnrealString.h"
14#include "HAL/MemoryBase.h"
15#include "HAL/ThreadSafeBool.h"
16#include "HAL/UnrealMemory.h"
18#include "Misc/ScopeLock.h"
20#ifndef MALLOC_LEAKDETECTION
21 #define MALLOC_LEAKDETECTION 0
25
26
63
64
65class FMallocLeakDetection
67 struct FCallstackTrack
71 FMemory::Memzero(
this,
sizeof(FCallstackTrack));
73 static constexpr int32 Depth = 32;
74 uint64 CallStack[Depth];
82 uint32 NumCheckPoints;
83 float SumOfFramesNumbers;
84 float SumOfFramesNumbersSquared;
86 float SumOfMemoryTimesFrameNumber;
92 bool operator==(
const FCallstackTrack& Other)
const
95 for (int32 i = 0; i < Depth; ++i)
97 if (CallStack[i] != Other.CallStack[i])
106 bool operator!=(
const FCallstackTrack& Other)
const
108 return !(*
this == Other);
115 CachedHash = FCrc::MemCrc32(CallStack,
sizeof(CallStack), 0);
122 FMallocLeakDetection();
123 ~FMallocLeakDetection();
128 void AddCallstack(FCallstackTrack& Callstack);
129 void RemoveCallstack(FCallstackTrack& Callstack);
132 TMap<
void*, FCallstackTrack> OpenPointers;
135 TMap<uint32, FCallstackTrack> UniqueCallstacks;
138 TSet<uint32> KnownDeleters;
141 TSet<uint32> KnownTrimmers;
144 TMap<
void*, FString> PointerContexts;
147 struct FContextString { TCHAR Buffer[64]; };
148 TArray<FContextString> Contexts;
151 FCriticalSection AllocatedPointersCritical;
160 int32 MinAllocationSize;
166 int32 AllocsWithoutCompact;
170 static FMallocLeakDetection& Get();
171 static void HandleMallocLeakCommand(
const TArray< FString >& Args);
174 void SetAllocationCollection(
bool bEnabled, int32 Size = 0);
177 bool IsAllocationCollectionEnabled(
void)
const {
return bCaptureAllocs; }
183 int32 DumpOpenCallstacks(
const TCHAR* FileName,
const FMallocLeakReportOptions& Options = FMallocLeakReportOptions());
186 void CheckpointLinearFit();
189 void Malloc(
void* Ptr, SIZE_T Size);
192 void Realloc(
void* OldPtr, SIZE_T OldSize,
void* NewPtr, SIZE_T NewSize);
195 void Free(
void* Ptr);
198 void SetDisabledForThisThread(
const bool Disabled);
201 bool IsDisabledForThisThread()
const;
204
205 void PushContext(
const FString& Context)
207 this->PushContext(*Context);
209 void PushContext(
const TCHAR* Context);
215 void GetOpenCallstacks(TArray<uint32>& OutCallstacks, SIZE_T& OutTotalSize,
const FMallocLeakReportOptions& Options = FMallocLeakReportOptions());
219
220
221
222
223
224class FMallocLeakDetectionIgnoreScope
227 FMallocLeakDetectionIgnoreScope()
229 FMallocLeakDetection::Get().SetDisabledForThisThread(
true);
232 ~FMallocLeakDetectionIgnoreScope()
234 FMallocLeakDetection::Get().SetDisabledForThisThread(
false);
238 FMallocLeakDetectionIgnoreScope(
const FMallocLeakDetectionIgnoreScope&) =
delete;
239 FMallocLeakDetectionIgnoreScope& operator=(
const FMallocLeakDetectionIgnoreScope&) =
delete;
242class FMallocLeakScopedContext
245 template <
typename ArgType>
246 explicit FMallocLeakScopedContext(ArgType&& Context)
248 FMallocLeakDetection::Get().PushContext(Forward<ArgType>(Context));
251 ~FMallocLeakScopedContext()
253 FMallocLeakDetection::Get().PopContext();
257 FMallocLeakScopedContext(
const FMallocLeakScopedContext&) =
delete;
258 FMallocLeakScopedContext& operator=(
const FMallocLeakScopedContext&) =
delete;
261#define MALLOCLEAK_IGNORE_SCOPE()
262 FMallocLeakDetectionIgnoreScope ANONYMOUS_VARIABLE(DetectionShouldIgnoreScope)
264#define MALLOCLEAK_SCOPED_CONTEXT(Context)
265 FMallocLeakScopedContext ANONYMOUS_VARIABLE(ScopedContext)(Context)
269#define MALLOCLEAK_IGNORE_SCOPE()
270#define MALLOCLEAK_SCOPED_CONTEXT(Context)
#define MALLOC_LEAKDETECTION
FMallocLeakReportOptions()
static FORCEINLINE void * Memzero(void *Dest, SIZE_T Count)