~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/ThirdParty/ANGLE/util/windows/win32/test_utils_win32.cpp

  • Committer: mmach
  • Date: 2023-06-16 17:21:37 UTC
  • Revision ID: netbit73@gmail.com-20230616172137-2rqx6yr96ga9g3kp
1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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