UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
CallstackTracePrivate.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
5#include "CoreTypes.h"
7#include "Trace/Trace.h"
8#include "Trace/Trace.inl"
9
10#if UE_CALLSTACK_TRACE_ENABLED
11
13#if !defined(UE_CALLSTACK_TRACE_RESERVE_MB)
14 // Initial size of the known set of callstacks
15 #if WITH_EDITOR
16 #define UE_CALLSTACK_TRACE_RESERVE_MB 16 // ~1M callstacks
17 #else
18 #define UE_CALLSTACK_TRACE_RESERVE_MB 8 // ~500k callstacks
19 #endif
20#endif
21
22#if !defined(UE_CALLSTACK_TRACE_RESERVE_GROWABLE)
23 // If disabled the known set will not grow. New callstacks will not be
24 // reported if the set is full
25 #define UE_CALLSTACK_TRACE_RESERVE_GROWABLE 1
26#endif
27
28
31
36
37
38
40 {
41 public:
42 struct FBacktraceEntry
43 {
44 uint64 Hash = 0;
45 uint32 FrameCount = 0;
47 };
48
51 , CallstackIdCounter(1) // 0 is reserved for "unknown callstack"
52 {
53 }
54
56 {
57 bool bAlreadyAdded = false;
58
59 // Our set implementation doesn't allow for zero entries (zero represents an empty element
60 // in the hash table), so if we get one due to really bad luck in our 64-bit Id calculation,
61 // treat it as a "1" instead, for purposes of tracking if we've seen that callstack.
62 const uint64 Hash = FMath::Max(Entry.Hash, 1ull);
63 uint32 Id;
64 KnownSet.Find(Hash, &Id, &bAlreadyAdded);
65 if (!bAlreadyAdded)
66 {
67 Id = CallstackIdCounter.fetch_add(1, std::memory_order_relaxed);
68 // On the first callstack reserve memory up front
69 if (Id == 1)
70 {
72 }
73#if !UE_CALLSTACK_TRACE_RESERVE_GROWABLE
74 // If configured as not growable, start returning unknown id's when full.
76 {
77 return 0;
78 }
79#endif
80 KnownSet.Emplace(Hash, Id);
82 << CallstackSpec.CallstackId(Id)
83 << CallstackSpec.Frames(Entry.Frames, Entry.FrameCount);
84 }
85
86 return Id;
87 }
88 private:
90 {
91 std::atomic_uint64_t Key;
92 std::atomic_uint32_t Value;
93
94 inline uint64 GetKey() const { return Key.load(std::memory_order_relaxed); }
95 inline uint32 GetValue() const { return Value.load(std::memory_order_relaxed); }
96 inline bool IsEmpty() const { return Key.load(std::memory_order_relaxed) == 0; }
97 inline void SetKeyValue(uint64 InKey, uint32 InValue)
98 {
99 Value.store(InValue, std::memory_order_release);
100 Key.store(InKey, std::memory_order_relaxed);
101 }
102 static inline uint32 KeyHash(uint64 Key) { return static_cast<uint32>(Key); }
103 static inline void ClearEntries(FEncounteredCallstackSetEntry* Entries, int32 EntryCount)
104 {
105 memset(Entries, 0, EntryCount * sizeof(FEncounteredCallstackSetEntry));
106 }
107 };
109
110 constexpr static uint32 InitialReserveBytes = UE_CALLSTACK_TRACE_RESERVE_MB * 1024 * 1024;
112
114 std::atomic_uint32_t CallstackIdCounter;
115 };
116
117#endif
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
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
#define UE_TRACE_LOG(LoggerName, EventName, ChannelsExpr,...)
Definition Trace.h:439
#define UE_TRACE_CHANNEL_EXTERN(ChannelName,...)
Definition Trace.h:448
#define UE_TRACE_EVENT_BEGIN_EXTERN(LoggerName, EventName,...)
Definition Trace.h:435
#define UE_TRACE_EVENT_END()
Definition Trace.h:438
#define UE_TRACE_EVENT_FIELD(FieldType, FieldName)
Definition Trace.h:436
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition MemoryBase.h:99
Definition GrowOnlyLockFreeHash.h:56
T::FDataType GetValue(const UBlackboardComponent &Blackboard, const FName &Name, FBlackboard::FKey &InOutCachedKey, const typename T::FDataType &DefaultValue)
Definition ValueOrBBKey.h:51