Path: blob/main_old/util/windows/win32/test_utils_win32.cpp
1693 views
//1// Copyright 2014 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// test_utils_win32.cpp: Implementation of OS-specific functions for Win32 (Windows)78#include "util/test_utils.h"910#include <windows.h>11#include <array>1213#include "util/windows/third_party/StackWalker/src/StackWalker.h"1415namespace angle16{17namespace18{19static const struct20{21const char *name;22const DWORD code;23} kExceptions[] = {24#define _(E) \25{ \26# E, E \27}28_(EXCEPTION_ACCESS_VIOLATION),29_(EXCEPTION_BREAKPOINT),30_(EXCEPTION_INT_DIVIDE_BY_ZERO),31_(EXCEPTION_STACK_OVERFLOW),32#undef _33};3435class CustomStackWalker : public StackWalker36{37public:38CustomStackWalker() {}39~CustomStackWalker() override {}4041void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) override42{43char buffer[STACKWALK_MAX_NAMELEN];44size_t maxLen = _TRUNCATE;45if ((eType != lastEntry) && (entry.offset != 0))46{47if (entry.name[0] == 0)48strncpy_s(entry.name, STACKWALK_MAX_NAMELEN, "(function-name not available)",49_TRUNCATE);50if (entry.undName[0] != 0)51strncpy_s(entry.name, STACKWALK_MAX_NAMELEN, entry.undName, _TRUNCATE);52if (entry.undFullName[0] != 0)53strncpy_s(entry.name, STACKWALK_MAX_NAMELEN, entry.undFullName, _TRUNCATE);54if (entry.lineFileName[0] == 0)55{56strncpy_s(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)",57_TRUNCATE);58if (entry.moduleName[0] == 0)59strncpy_s(entry.moduleName, STACKWALK_MAX_NAMELEN,60"(module-name not available)", _TRUNCATE);61_snprintf_s(buffer, maxLen, " %s - %p (%s): %s\n", entry.name,62reinterpret_cast<void *>(entry.offset), entry.moduleName,63entry.lineFileName);64}65else66_snprintf_s(buffer, maxLen, " %s (%s:%d)\n", entry.name, entry.lineFileName,67entry.lineNumber);68buffer[STACKWALK_MAX_NAMELEN - 1] = 0;69printf("%s", buffer);70OutputDebugStringA(buffer);71}72}73};7475void PrintBacktrace(CONTEXT *c)76{77printf("Backtrace:\n");78OutputDebugStringA("Backtrace:\n");7980CustomStackWalker sw;81sw.ShowCallstack(GetCurrentThread(), c);82}8384LONG WINAPI StackTraceCrashHandler(EXCEPTION_POINTERS *e)85{86const DWORD code = e->ExceptionRecord->ExceptionCode;87printf("\nCaught exception %lu", code);88for (size_t i = 0; i < ArraySize(kExceptions); i++)89{90if (kExceptions[i].code == code)91{92printf(" %s", kExceptions[i].name);93}94}95printf("\n");9697PrintBacktrace(e->ContextRecord);9899// Exit NOW. Don't notify other threads, don't call anything registered with atexit().100_exit(1);101102// The compiler wants us to return something. This is what we'd do if we didn't _exit().103return EXCEPTION_EXECUTE_HANDLER;104}105106CrashCallback *gCrashHandlerCallback;107108LONG WINAPI CrashHandler(EXCEPTION_POINTERS *e)109{110if (gCrashHandlerCallback)111{112(*gCrashHandlerCallback)();113}114return StackTraceCrashHandler(e);115}116} // namespace117118void SetLowPriorityProcess()119{120::SetPriorityClass(::GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);121}122123bool StabilizeCPUForBenchmarking()124{125if (::SetThreadAffinityMask(::GetCurrentThread(), 1) == 0)126{127return false;128}129if (::SetPriorityClass(::GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == FALSE)130{131return false;132}133if (::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) == FALSE)134{135return false;136}137138return true;139}140141void PrintStackBacktrace()142{143CONTEXT context;144ZeroMemory(&context, sizeof(CONTEXT));145RtlCaptureContext(&context);146PrintBacktrace(&context);147}148149void InitCrashHandler(CrashCallback *callback)150{151if (callback)152{153gCrashHandlerCallback = callback;154}155SetUnhandledExceptionFilter(CrashHandler);156}157158void TerminateCrashHandler()159{160gCrashHandlerCallback = nullptr;161SetUnhandledExceptionFilter(nullptr);162}163164int NumberOfProcessors()165{166// A portable implementation could probably use GetLogicalProcessorInformation167return ::GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);168}169} // namespace angle170171172