Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/common/debug.cpp
1693 views
1
//
2
// Copyright 2002 The ANGLE Project Authors. All rights reserved.
3
// Use of this source code is governed by a BSD-style license that can be
4
// found in the LICENSE file.
5
//
6
7
// debug.cpp: Debugging utilities.
8
9
#include "common/debug.h"
10
11
#include <stdarg.h>
12
13
#include <array>
14
#include <cstdio>
15
#include <cstring>
16
#include <fstream>
17
#include <ostream>
18
#include <vector>
19
20
#if defined(ANGLE_PLATFORM_ANDROID)
21
# include <android/log.h>
22
#endif
23
24
#if defined(ANGLE_PLATFORM_APPLE)
25
# include <os/log.h>
26
#endif
27
28
#include "anglebase/no_destructor.h"
29
#include "common/Optional.h"
30
#include "common/angleutils.h"
31
#include "common/entry_points_enum_autogen.h"
32
#include "common/system_utils.h"
33
34
namespace gl
35
{
36
37
namespace
38
{
39
40
DebugAnnotator *g_debugAnnotator = nullptr;
41
42
std::mutex *g_debugMutex = nullptr;
43
44
constexpr std::array<const char *, LOG_NUM_SEVERITIES> g_logSeverityNames = {
45
{"EVENT", "INFO", "WARN", "ERR", "FATAL"}};
46
47
constexpr const char *LogSeverityName(int severity)
48
{
49
return (severity >= 0 && severity < LOG_NUM_SEVERITIES) ? g_logSeverityNames[severity]
50
: "UNKNOWN";
51
}
52
53
bool ShouldCreateLogMessage(LogSeverity severity)
54
{
55
#if defined(ANGLE_TRACE_ENABLED)
56
return true;
57
#elif defined(ANGLE_ENABLE_ASSERTS)
58
return severity == LOG_FATAL || severity == LOG_ERR || severity == LOG_WARN;
59
#else
60
return false;
61
#endif
62
}
63
64
} // namespace
65
66
namespace priv
67
{
68
69
bool ShouldCreatePlatformLogMessage(LogSeverity severity)
70
{
71
#if defined(ANGLE_TRACE_ENABLED)
72
return true;
73
#else
74
return severity != LOG_EVENT;
75
#endif
76
}
77
78
// This is never instantiated, it's just used for EAT_STREAM_PARAMETERS to an object of the correct
79
// type on the LHS of the unused part of the ternary operator.
80
std::ostream *gSwallowStream;
81
} // namespace priv
82
83
bool DebugAnnotationsActive()
84
{
85
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) || defined(ANGLE_ENABLE_DEBUG_TRACE)
86
return g_debugAnnotator != nullptr && g_debugAnnotator->getStatus();
87
#else
88
return false;
89
#endif
90
}
91
92
bool ShouldBeginScopedEvent()
93
{
94
#if defined(ANGLE_ENABLE_ANNOTATOR_RUN_TIME_CHECKS)
95
return DebugAnnotationsActive();
96
#else
97
return true;
98
#endif // defined(ANGLE_ENABLE_ANNOTATOR_RUN_TIME_CHECKS)
99
}
100
101
bool DebugAnnotationsInitialized()
102
{
103
return g_debugAnnotator != nullptr;
104
}
105
106
void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator)
107
{
108
UninitializeDebugAnnotations();
109
g_debugAnnotator = debugAnnotator;
110
}
111
112
void UninitializeDebugAnnotations()
113
{
114
// Pointer is not managed.
115
g_debugAnnotator = nullptr;
116
}
117
118
void InitializeDebugMutexIfNeeded()
119
{
120
if (g_debugMutex == nullptr)
121
{
122
g_debugMutex = new std::mutex();
123
}
124
}
125
126
std::mutex &GetDebugMutex()
127
{
128
ASSERT(g_debugMutex);
129
return *g_debugMutex;
130
}
131
132
ScopedPerfEventHelper::ScopedPerfEventHelper(gl::Context *context, angle::EntryPoint entryPoint)
133
: mContext(context), mEntryPoint(entryPoint), mFunctionName(nullptr), mCalledBeginEvent(false)
134
{}
135
136
ScopedPerfEventHelper::~ScopedPerfEventHelper()
137
{
138
// EGL_Initialize() and EGL_Terminate() can change g_debugAnnotator. Must check the value of
139
// g_debugAnnotator and whether ScopedPerfEventHelper::begin() initiated a begine that must be
140
// ended now.
141
if (DebugAnnotationsInitialized() && mCalledBeginEvent)
142
{
143
g_debugAnnotator->endEvent(mContext, mFunctionName, mEntryPoint);
144
}
145
}
146
147
void ScopedPerfEventHelper::begin(const char *format, ...)
148
{
149
mFunctionName = GetEntryPointName(mEntryPoint);
150
151
va_list vararg;
152
va_start(vararg, format);
153
154
std::vector<char> buffer;
155
size_t len = FormatStringIntoVector(format, vararg, buffer);
156
va_end(vararg);
157
158
ANGLE_LOG(EVENT) << std::string(&buffer[0], len);
159
if (DebugAnnotationsInitialized())
160
{
161
mCalledBeginEvent = true;
162
g_debugAnnotator->beginEvent(mContext, mEntryPoint, mFunctionName, buffer.data());
163
}
164
}
165
166
LogMessage::LogMessage(const char *file, const char *function, int line, LogSeverity severity)
167
: mFile(file), mFunction(function), mLine(line), mSeverity(severity)
168
{
169
// INFO() and EVENT() do not require additional function(line) info.
170
if (mSeverity > LOG_INFO)
171
{
172
const char *slash = std::max(strrchr(mFile, '/'), strrchr(mFile, '\\'));
173
mStream << (slash ? (slash + 1) : mFile) << ":" << mLine << " (" << mFunction << "): ";
174
}
175
}
176
177
LogMessage::~LogMessage()
178
{
179
std::unique_lock<std::mutex> lock;
180
if (g_debugMutex != nullptr)
181
{
182
lock = std::unique_lock<std::mutex>(*g_debugMutex);
183
}
184
185
if (DebugAnnotationsInitialized() && (mSeverity > LOG_INFO))
186
{
187
g_debugAnnotator->logMessage(*this);
188
}
189
else
190
{
191
Trace(getSeverity(), getMessage().c_str());
192
}
193
194
if (mSeverity == LOG_FATAL)
195
{
196
if (angle::IsDebuggerAttached())
197
{
198
angle::BreakDebugger();
199
}
200
else
201
{
202
ANGLE_CRASH();
203
}
204
}
205
}
206
207
void Trace(LogSeverity severity, const char *message)
208
{
209
if (!ShouldCreateLogMessage(severity))
210
{
211
return;
212
}
213
214
std::string str(message);
215
216
if (DebugAnnotationsActive())
217
{
218
219
switch (severity)
220
{
221
case LOG_EVENT:
222
// Debugging logging done in ScopedPerfEventHelper
223
break;
224
default:
225
g_debugAnnotator->setMarker(message);
226
break;
227
}
228
}
229
230
if (severity == LOG_FATAL || severity == LOG_ERR || severity == LOG_WARN ||
231
#if defined(ANGLE_ENABLE_TRACE_ANDROID_LOGCAT)
232
severity == LOG_EVENT ||
233
#endif
234
severity == LOG_INFO)
235
{
236
#if defined(ANGLE_PLATFORM_ANDROID)
237
android_LogPriority android_priority = ANDROID_LOG_ERROR;
238
switch (severity)
239
{
240
case LOG_INFO:
241
case LOG_EVENT:
242
android_priority = ANDROID_LOG_INFO;
243
break;
244
case LOG_WARN:
245
android_priority = ANDROID_LOG_WARN;
246
break;
247
case LOG_ERR:
248
android_priority = ANDROID_LOG_ERROR;
249
break;
250
case LOG_FATAL:
251
android_priority = ANDROID_LOG_FATAL;
252
break;
253
default:
254
UNREACHABLE();
255
}
256
__android_log_print(android_priority, "ANGLE", "%s: %s\n", LogSeverityName(severity),
257
str.c_str());
258
#elif defined(ANGLE_PLATFORM_APPLE)
259
if (__builtin_available(macOS 10.12, iOS 10.0, *))
260
{
261
os_log_type_t apple_log_type = OS_LOG_TYPE_DEFAULT;
262
switch (severity)
263
{
264
case LOG_INFO:
265
apple_log_type = OS_LOG_TYPE_INFO;
266
break;
267
case LOG_WARN:
268
apple_log_type = OS_LOG_TYPE_DEFAULT;
269
break;
270
case LOG_ERR:
271
apple_log_type = OS_LOG_TYPE_ERROR;
272
break;
273
case LOG_FATAL:
274
// OS_LOG_TYPE_FAULT is too severe - grabs the entire process tree.
275
apple_log_type = OS_LOG_TYPE_ERROR;
276
break;
277
default:
278
UNREACHABLE();
279
}
280
os_log_with_type(OS_LOG_DEFAULT, apple_log_type, "ANGLE: %s: %s\n",
281
LogSeverityName(severity), str.c_str());
282
}
283
#else
284
// Note: we use fprintf because <iostream> includes static initializers.
285
fprintf((severity >= LOG_WARN) ? stderr : stdout, "%s: %s\n", LogSeverityName(severity),
286
str.c_str());
287
#endif
288
}
289
290
#if defined(ANGLE_PLATFORM_WINDOWS) && \
291
(defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER) || !defined(NDEBUG))
292
# if !defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
293
if (severity >= LOG_ERR)
294
# endif // !defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
295
{
296
OutputDebugStringA(str.c_str());
297
OutputDebugStringA("\n");
298
}
299
#endif
300
301
#if defined(ANGLE_ENABLE_DEBUG_TRACE)
302
# if defined(NDEBUG)
303
if (severity == LOG_EVENT || severity == LOG_WARN || severity == LOG_INFO)
304
{
305
return;
306
}
307
# endif // defined(NDEBUG)
308
static angle::base::NoDestructor<std::ofstream> file(TRACE_OUTPUT_FILE, std::ofstream::app);
309
if (file->good())
310
{
311
if (severity > LOG_EVENT)
312
{
313
*file << LogSeverityName(severity) << ": ";
314
}
315
*file << str << "\n";
316
file->flush();
317
}
318
#endif // defined(ANGLE_ENABLE_DEBUG_TRACE)
319
}
320
321
LogSeverity LogMessage::getSeverity() const
322
{
323
return mSeverity;
324
}
325
326
std::string LogMessage::getMessage() const
327
{
328
return mStream.str();
329
}
330
331
#if defined(ANGLE_PLATFORM_WINDOWS)
332
priv::FmtHexHelper<HRESULT> FmtHR(HRESULT value)
333
{
334
return priv::FmtHexHelper<HRESULT>("HRESULT: ", value);
335
}
336
337
priv::FmtHexHelper<DWORD> FmtErr(DWORD value)
338
{
339
return priv::FmtHexHelper<DWORD>("error: ", value);
340
}
341
#endif // defined(ANGLE_PLATFORM_WINDOWS)
342
343
} // namespace gl
344
345