Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/util/windows/win32/test_utils_win32.cpp
1693 views
1
//
2
// Copyright 2014 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
// test_utils_win32.cpp: Implementation of OS-specific functions for Win32 (Windows)
8
9
#include "util/test_utils.h"
10
11
#include <windows.h>
12
#include <array>
13
14
#include "util/windows/third_party/StackWalker/src/StackWalker.h"
15
16
namespace angle
17
{
18
namespace
19
{
20
static const struct
21
{
22
const char *name;
23
const DWORD code;
24
} kExceptions[] = {
25
#define _(E) \
26
{ \
27
# E, E \
28
}
29
_(EXCEPTION_ACCESS_VIOLATION),
30
_(EXCEPTION_BREAKPOINT),
31
_(EXCEPTION_INT_DIVIDE_BY_ZERO),
32
_(EXCEPTION_STACK_OVERFLOW),
33
#undef _
34
};
35
36
class CustomStackWalker : public StackWalker
37
{
38
public:
39
CustomStackWalker() {}
40
~CustomStackWalker() override {}
41
42
void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) override
43
{
44
char buffer[STACKWALK_MAX_NAMELEN];
45
size_t maxLen = _TRUNCATE;
46
if ((eType != lastEntry) && (entry.offset != 0))
47
{
48
if (entry.name[0] == 0)
49
strncpy_s(entry.name, STACKWALK_MAX_NAMELEN, "(function-name not available)",
50
_TRUNCATE);
51
if (entry.undName[0] != 0)
52
strncpy_s(entry.name, STACKWALK_MAX_NAMELEN, entry.undName, _TRUNCATE);
53
if (entry.undFullName[0] != 0)
54
strncpy_s(entry.name, STACKWALK_MAX_NAMELEN, entry.undFullName, _TRUNCATE);
55
if (entry.lineFileName[0] == 0)
56
{
57
strncpy_s(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)",
58
_TRUNCATE);
59
if (entry.moduleName[0] == 0)
60
strncpy_s(entry.moduleName, STACKWALK_MAX_NAMELEN,
61
"(module-name not available)", _TRUNCATE);
62
_snprintf_s(buffer, maxLen, " %s - %p (%s): %s\n", entry.name,
63
reinterpret_cast<void *>(entry.offset), entry.moduleName,
64
entry.lineFileName);
65
}
66
else
67
_snprintf_s(buffer, maxLen, " %s (%s:%d)\n", entry.name, entry.lineFileName,
68
entry.lineNumber);
69
buffer[STACKWALK_MAX_NAMELEN - 1] = 0;
70
printf("%s", buffer);
71
OutputDebugStringA(buffer);
72
}
73
}
74
};
75
76
void PrintBacktrace(CONTEXT *c)
77
{
78
printf("Backtrace:\n");
79
OutputDebugStringA("Backtrace:\n");
80
81
CustomStackWalker sw;
82
sw.ShowCallstack(GetCurrentThread(), c);
83
}
84
85
LONG WINAPI StackTraceCrashHandler(EXCEPTION_POINTERS *e)
86
{
87
const DWORD code = e->ExceptionRecord->ExceptionCode;
88
printf("\nCaught exception %lu", code);
89
for (size_t i = 0; i < ArraySize(kExceptions); i++)
90
{
91
if (kExceptions[i].code == code)
92
{
93
printf(" %s", kExceptions[i].name);
94
}
95
}
96
printf("\n");
97
98
PrintBacktrace(e->ContextRecord);
99
100
// Exit NOW. Don't notify other threads, don't call anything registered with atexit().
101
_exit(1);
102
103
// The compiler wants us to return something. This is what we'd do if we didn't _exit().
104
return EXCEPTION_EXECUTE_HANDLER;
105
}
106
107
CrashCallback *gCrashHandlerCallback;
108
109
LONG WINAPI CrashHandler(EXCEPTION_POINTERS *e)
110
{
111
if (gCrashHandlerCallback)
112
{
113
(*gCrashHandlerCallback)();
114
}
115
return StackTraceCrashHandler(e);
116
}
117
} // namespace
118
119
void SetLowPriorityProcess()
120
{
121
::SetPriorityClass(::GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
122
}
123
124
bool StabilizeCPUForBenchmarking()
125
{
126
if (::SetThreadAffinityMask(::GetCurrentThread(), 1) == 0)
127
{
128
return false;
129
}
130
if (::SetPriorityClass(::GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == FALSE)
131
{
132
return false;
133
}
134
if (::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) == FALSE)
135
{
136
return false;
137
}
138
139
return true;
140
}
141
142
void PrintStackBacktrace()
143
{
144
CONTEXT context;
145
ZeroMemory(&context, sizeof(CONTEXT));
146
RtlCaptureContext(&context);
147
PrintBacktrace(&context);
148
}
149
150
void InitCrashHandler(CrashCallback *callback)
151
{
152
if (callback)
153
{
154
gCrashHandlerCallback = callback;
155
}
156
SetUnhandledExceptionFilter(CrashHandler);
157
}
158
159
void TerminateCrashHandler()
160
{
161
gCrashHandlerCallback = nullptr;
162
SetUnhandledExceptionFilter(nullptr);
163
}
164
165
int NumberOfProcessors()
166
{
167
// A portable implementation could probably use GetLogicalProcessorInformation
168
return ::GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
169
}
170
} // namespace angle
171
172