blob: 1118d33950b8ddd905ab3583d33fc192be8ca280 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include <zencore/trace.h>
#if ZEN_PLATFORM_WINDOWS
# include <intrin.h>
# define PLATFORM_RETURN_ADDRESS() _ReturnAddress()
# define PLATFORM_RETURN_ADDRESS_POINTER() _AddressOfReturnAddress()
# define PLATFORM_RETURN_ADDRESS_FOR_CALLSTACKTRACING PLATFORM_RETURN_ADDRESS_POINTER
#endif
////////////////////////////////////////////////////////////////////////////////
#if !defined(UE_CALLSTACK_TRACE_ENABLED)
# if ZEN_WITH_TRACE
# if ZEN_PLATFORM_WINDOWS
# define UE_CALLSTACK_TRACE_ENABLED 1
# endif
# endif
#endif
#if !defined(UE_CALLSTACK_TRACE_ENABLED)
# define UE_CALLSTACK_TRACE_ENABLED 0
#endif
////////////////////////////////////////////////////////////////////////////////
#if UE_CALLSTACK_TRACE_ENABLED
# include "platformtls.h"
namespace zen {
/**
* Creates callstack tracing.
* @param Malloc Allocator instance to use.
*/
void CallstackTrace_Create(class FMalloc* Malloc);
/**
* Initializes callstack tracing. On some platforms this has to be delayed due to initialization order.
*/
void CallstackTrace_Initialize();
/**
* Capture the current callstack, and trace the definition if it has not already been encountered. The returned value
* can be used in trace events and be resolved in analysis.
* @return Unique id identifying the current callstack.
*/
uint32_t CallstackTrace_GetCurrentId();
/**
* Callstack Trace Scoped Macro to avoid resolving the full callstack
* can be used when some external libraries are not compiled with frame pointers
* preventing us to resolve it without crashing. Instead the callstack will be
* only the caller address.
*/
# define CALLSTACK_TRACE_LIMIT_CALLSTACKRESOLVE_SCOPE() FCallStackTraceLimitResolveScope PREPROCESSOR_JOIN(FCTLMScope, __LINE__)
extern uint32_t GCallStackTracingTlsSlotIndex;
/**
* @return the fallback callstack address
*/
inline void*
CallstackTrace_GetFallbackPlatformReturnAddressData()
{
if (FPlatformTLS::IsValidTlsSlot(GCallStackTracingTlsSlotIndex))
return FPlatformTLS::GetTlsValue(GCallStackTracingTlsSlotIndex);
else
return nullptr;
}
/**
* @return Needs full callstack resolve
*/
inline bool
CallstackTrace_ResolveFullCallStack()
{
return CallstackTrace_GetFallbackPlatformReturnAddressData() == nullptr;
}
/*
* Callstack Trace scope for override CallStack
*/
class FCallStackTraceLimitResolveScope
{
public:
ZEN_FORCENOINLINE FCallStackTraceLimitResolveScope()
{
if (FPlatformTLS::IsValidTlsSlot(GCallStackTracingTlsSlotIndex))
{
FPlatformTLS::SetTlsValue(GCallStackTracingTlsSlotIndex, PLATFORM_RETURN_ADDRESS_FOR_CALLSTACKTRACING());
}
}
ZEN_FORCENOINLINE ~FCallStackTraceLimitResolveScope()
{
if (FPlatformTLS::IsValidTlsSlot(GCallStackTracingTlsSlotIndex))
{
FPlatformTLS::SetTlsValue(GCallStackTracingTlsSlotIndex, nullptr);
}
}
};
} // namespace zen
#else // UE_CALLSTACK_TRACE_ENABLED
namespace zen {
inline void
CallstackTrace_Create(class FMalloc* /*Malloc*/)
{
}
inline void
CallstackTrace_Initialize()
{
}
inline uint32_t
CallstackTrace_GetCurrentId()
{
return 0;
}
inline void*
CallstackTrace_GetCurrentReturnAddressData()
{
return nullptr;
}
inline void*
CallstackTrace_GetFallbackPlatformReturnAddressData()
{
return nullptr;
}
inline bool
CallstackTrace_ResolveFullCallStack()
{
return true;
}
# define CALLSTACK_TRACE_LIMIT_CALLSTACKRESOLVE_SCOPE()
} // namespace zen
#endif // UE_CALLSTACK_TRACE_ENABLED
|