ovr_sdk
diff LibOVR/Src/Kernel/OVR_DebugHelp.h @ 0:1b39a1b46319
initial 0.4.4
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 14 Jan 2015 06:51:16 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/LibOVR/Src/Kernel/OVR_DebugHelp.h Wed Jan 14 06:51:16 2015 +0200 1.3 @@ -0,0 +1,461 @@ 1.4 +/************************************************************************************ 1.5 + 1.6 +Filename : OVR_DebugHelp.h 1.7 +Content : Platform-independent exception handling interface 1.8 +Created : October 6, 2014 1.9 + 1.10 +Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved. 1.11 + 1.12 +Licensed under the Apache License, Version 2.0 (the "License"); 1.13 +you may not use this file except in compliance with the License. 1.14 +You may obtain a copy of the License at 1.15 + 1.16 +http://www.apache.org/licenses/LICENSE-2.0 1.17 + 1.18 +Unless required by applicable law or agreed to in writing, software 1.19 +distributed under the License is distributed on an "AS IS" BASIS, 1.20 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.21 +See the License for the specific language governing permissions and 1.22 +limitations under the License. 1.23 + 1.24 +************************************************************************************/ 1.25 + 1.26 +#ifndef OVR_ExceptionHandler_h 1.27 +#define OVR_ExceptionHandler_h 1.28 + 1.29 + 1.30 +#include "OVR_Types.h" 1.31 +#include "OVR_String.h" 1.32 +#include "OVR_Threads.h" 1.33 +#include "OVR_Atomic.h" 1.34 +#include "OVR_Nullptr.h" 1.35 +#include <stdio.h> 1.36 +#include <time.h> 1.37 + 1.38 +#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) 1.39 + #include <Windows.h> 1.40 + 1.41 +#elif defined(OVR_OS_APPLE) 1.42 + #include <pthread.h> 1.43 + #include <mach/thread_status.h> 1.44 + #include <mach/mach_types.h> 1.45 + 1.46 + extern "C" void* MachHandlerThreadFunctionStatic(void*); 1.47 + extern "C" int catch_mach_exception_raise_state_identity_OVR(mach_port_t, mach_port_t, mach_port_t, exception_type_t, mach_exception_data_type_t*, 1.48 + mach_msg_type_number_t, int*, thread_state_t, mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t*); 1.49 +#elif defined(OVR_OS_LINUX) 1.50 + #include <pthread.h> 1.51 +#endif 1.52 + 1.53 + 1.54 +OVR_DISABLE_MSVC_WARNING(4351) // new behavior: elements of array will be default initialized 1.55 + 1.56 + 1.57 +namespace OVR { 1.58 + 1.59 + // Thread identifiers 1.60 + //typedef void* ThreadHandle; // Already defined by OVR Threads. Same as Windows thread handle, Unix pthread_t. 1.61 + //typedef void* ThreadId; // Already defined by OVR Threads. Used by Windows as DWORD thread id, by Unix as pthread_t. 1.62 + typedef uintptr_t ThreadSysId; // System thread identifier. Used by Windows the same as ThreadId (DWORD), thread_act_t on Mac/BSD, lwp id on Linux. 1.63 + 1.64 + // Thread constants 1.65 + // To do: Move to OVR Threads 1.66 + #define OVR_THREADHANDLE_INVALID ((ThreadHandle*)nullptr) 1.67 + #define OVR_THREADID_INVALID ((ThreadId*)nullptr) 1.68 + #define OVR_THREADSYSID_INVALID ((uintptr_t)0) 1.69 + 1.70 + OVR::ThreadSysId ConvertThreadHandleToThreadSysId(OVR::ThreadHandle threadHandle); 1.71 + OVR::ThreadHandle ConvertThreadSysIdToThreadHandle(OVR::ThreadSysId threadSysId); // The returned handle must be freed with FreeThreadHandle. 1.72 + void FreeThreadHandle(OVR::ThreadHandle threadHandle); // Frees the handle returned by ConvertThreadSysIdToThreadHandle. 1.73 + OVR::ThreadSysId GetCurrentThreadSysId(); 1.74 + 1.75 + // CPUContext 1.76 + #if defined(OVR_OS_MS) 1.77 + typedef CONTEXT CPUContext; 1.78 + #elif defined(OVR_OS_MAC) 1.79 + struct CPUContext 1.80 + { 1.81 + x86_thread_state_t threadState; // This works for both x86 and x64. 1.82 + x86_float_state_t floatState; 1.83 + x86_debug_state_t debugState; 1.84 + x86_avx_state_t avxState; 1.85 + x86_exception_state exceptionState; 1.86 + 1.87 + CPUContext() { memset(this, 0, sizeof(CPUContext)); } 1.88 + }; 1.89 + #elif defined(OVR_OS_LINUX) 1.90 + typedef int CPUContext; // To do. 1.91 + #endif 1.92 + 1.93 + 1.94 + // Tells if the current process appears to be running under a debugger. Does not attempt to 1.95 + // detect the case of sleath debuggers (malware-related for example). 1.96 + bool OVRIsDebuggerPresent(); 1.97 + 1.98 + // Exits the process with the given exit code. 1.99 + #if !defined(OVR_NORETURN) 1.100 + #if defined(OVR_CC_MSVC) 1.101 + #define OVR_NORETURN __declspec(noreturn) 1.102 + #else 1.103 + #define OVR_NORETURN __attribute__((noreturn)) 1.104 + #endif 1.105 + #endif 1.106 + OVR_NORETURN void ExitProcess(intptr_t processReturnValue); 1.107 + 1.108 + // Returns the instruction pointer of the caller for the position right after the call. 1.109 + OVR_NO_INLINE void GetInstructionPointer(void*& pInstruction); 1.110 + 1.111 + // Returns the stack base and limit addresses for the given thread, or for the current thread if the threadHandle is default. 1.112 + // The stack limit is a value less than the stack base on most platforms, as stacks usually grow downward. 1.113 + // Some platforms (e.g. Microsoft) have dynamically resizing stacks, in which case the stack limit reflects the current limit. 1.114 + void GetThreadStackBounds(void*& pStackBase, void*& pStackLimit, ThreadHandle threadHandle = OVR_THREADHANDLE_INVALID); 1.115 + 1.116 + 1.117 + // Equates to VirtualAlloc/VirtualFree on Windows, mmap/munmap on Unix. 1.118 + // These are useful for when you need system-supplied memory pages. 1.119 + // These are also useful for when you need to allocate memory in a way 1.120 + // that doesn't affect the application heap. 1.121 + void* SafeMMapAlloc(size_t size); 1.122 + void SafeMMapFree(const void* memory, size_t size); 1.123 + 1.124 + 1.125 + // OVR_MAX_PATH 1.126 + // Max file path length (for most uses). 1.127 + // To do: move this to OVR_File. 1.128 + #if defined(OVR_OS_MS) // http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx 1.129 + #define OVR_MAX_PATH 260 // Windows can use paths longer than this in some cases (network paths, UNC paths). 1.130 + #else 1.131 + #define OVR_MAX_PATH 1024 // This isn't a strict limit on all Unix-based platforms. 1.132 + #endif 1.133 + 1.134 + 1.135 + // ModuleHandle 1.136 + #if defined(OVR_OS_MS) 1.137 + typedef void* ModuleHandle; // from LoadLibrary() 1.138 + #elif defined(OVR_OS_APPLE) || defined(OVR_OS_UNIX) 1.139 + typedef void* ModuleHandle; // from dlopen() 1.140 + #endif 1.141 + 1.142 + #define OVR_MODULEHANDLE_INVALID ((ModuleHandle*)nullptr) 1.143 + 1.144 + 1.145 + 1.146 + // Module info constants 1.147 + static const ModuleHandle kMIHandleInvalid = OVR_MODULEHANDLE_INVALID; 1.148 + static const uint64_t kMIAddressInvalid = 0xffffffffffffffffull; 1.149 + static const uint64_t kMISizeInvalid = 0xffffffffffffffffull; 1.150 + static const int32_t kMILineNumberInvalid = -1; 1.151 + static const int32_t kMIFunctionOffsetInvalid = -1; 1.152 + static const uint64_t kMIBaseAddressInvalid = 0xffffffffffffffffull; 1.153 + static const uint64_t kMIBaseAddressUnspecified = 0xffffffffffffffffull; 1.154 + 1.155 + struct ModuleInfo 1.156 + { 1.157 + ModuleHandle handle; 1.158 + uint64_t baseAddress; // The actual runtime base address of the module. May be different from the base address specified in the debug symbol file. 1.159 + uint64_t size; 1.160 + char filePath[OVR_MAX_PATH]; 1.161 + char name[32]; 1.162 + char type[8]; // Unix-specific. e.g. __TEXT 1.163 + char permissions[8]; // Unix specific. e.g. "drwxr-xr-x" 1.164 + 1.165 + ModuleInfo() : handle(kMIHandleInvalid), baseAddress(kMIBaseAddressInvalid), size(0), filePath(), name(){} 1.166 + }; 1.167 + 1.168 + 1.169 + // Refers to symbol info for an instruction address. 1.170 + // Info includes function name, source code file/line, and source code itself. 1.171 + struct SymbolInfo 1.172 + { 1.173 + uint64_t address; 1.174 + uint64_t size; 1.175 + const ModuleInfo* pModuleInfo; 1.176 + char filePath[OVR_MAX_PATH]; 1.177 + int32_t fileLineNumber; 1.178 + char function[128]; // This is a fixed size because we need to use it during application exceptions. 1.179 + int32_t functionOffset; 1.180 + char sourceCode[1024]; // This is a string representing the code itself and not a file path to the code. 1.181 + 1.182 + SymbolInfo() : address(kMIAddressInvalid), size(kMISizeInvalid), pModuleInfo(nullptr), filePath(), 1.183 + fileLineNumber(kMILineNumberInvalid), function(), functionOffset(kMIFunctionOffsetInvalid), sourceCode() {} 1.184 + }; 1.185 + 1.186 + 1.187 + // Implements support for reading thread lists, module lists, backtraces, and backtrace symbols. 1.188 + class SymbolLookup 1.189 + { 1.190 + public: 1.191 + SymbolLookup(); 1.192 + ~SymbolLookup(); 1.193 + 1.194 + void AddSourceCodeDirectory(const char* pDirectory); 1.195 + 1.196 + bool Initialize(); 1.197 + void Shutdown(); 1.198 + 1.199 + // Should be disabled when within an exception handler. 1.200 + void EnableMemoryAllocation(bool enabled); 1.201 + 1.202 + // Retrieves the backtrace (call stack) of the given thread. There may be some per-platform restrictions on this. 1.203 + // Returns the number written, which will be <= addressArrayCapacity. 1.204 + // This may not work on some platforms unless stack frames are enabled. 1.205 + // For Microsoft platforms the platformThreadContext is CONTEXT*. 1.206 + // For Apple platforms the platformThreadContext is x86_thread_state_t* or arm_thread_state_t*. 1.207 + // If threadSysIdHelp is non-zero, it may be used by the implementation to help produce a better backtrace. 1.208 + size_t GetBacktrace(void* addressArray[], size_t addressArrayCapacity, size_t skipCount = 0, void* platformThreadContext = nullptr, OVR::ThreadSysId threadSysIdHelp = OVR_THREADSYSID_INVALID); 1.209 + 1.210 + // Retrieves the backtrace for the given ThreadHandle. 1.211 + // Returns the number written, which will be <= addressArrayCapacity. 1.212 + size_t GetBacktraceFromThreadHandle(void* addressArray[], size_t addressArrayCapacity, size_t skipCount = 0, OVR::ThreadHandle threadHandle = OVR_THREADHANDLE_INVALID); 1.213 + 1.214 + // Retrieves the backtrace for the given ThreadSysId. 1.215 + // Returns the number written, which will be <= addressArrayCapacity. 1.216 + size_t GetBacktraceFromThreadSysId(void* addressArray[], size_t addressArrayCapacity, size_t skipCount = 0, OVR::ThreadSysId threadSysId = OVR_THREADSYSID_INVALID); 1.217 + 1.218 + // Gets a list of the modules (e.g. DLLs) present in the current process. 1.219 + // Writes as many ModuleInfos as possible to pModuleInfoArray. 1.220 + // Returns the required count of ModuleInfos, which will be > moduleInfoArrayCapacity if the capacity needs to be larger. 1.221 + size_t GetModuleInfoArray(ModuleInfo* pModuleInfoArray, size_t moduleInfoArrayCapacity); 1.222 + 1.223 + // Retrieves a list of the current threads. Unless the process is paused the list is volatile. 1.224 + // Returns the required capacity, which may be larger than threadArrayCapacity. 1.225 + // Either array can be NULL to specify that it's not written to. 1.226 + // For Windows the caller needs to CloseHandle the returned ThreadHandles. This can be done by calling DoneThreadList. 1.227 + size_t GetThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCapacity); 1.228 + 1.229 + // Frees any references to thread handles or ids returned by GetThreadList; 1.230 + void DoneThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCount); 1.231 + 1.232 + // Writes a given thread's callstack with symbols to the given output. 1.233 + // It may not be safe to call this from an exception handler, as sOutput allocates memory. 1.234 + bool ReportThreadCallstack(OVR::String& sOutput, size_t skipCount = 0, ThreadSysId threadSysId = OVR_THREADSYSID_INVALID); 1.235 + 1.236 + // Writes all thread's callstacks with symbols to the given output. 1.237 + // It may not be safe to call this from an exception handler, as sOutput allocates memory. 1.238 + bool ReportThreadCallstacks(OVR::String& sOutput, size_t skipCount = 0); 1.239 + 1.240 + // Retrieves symbol info for the given address. 1.241 + bool LookupSymbol(uint64_t address, SymbolInfo& symbolInfo); 1.242 + bool LookupSymbols(uint64_t* addressArray, SymbolInfo* pSymbolInfoArray, size_t arraySize); 1.243 + 1.244 + const ModuleInfo* GetModuleInfoForAddress(uint64_t address); // The returned ModuleInfo points to an internal structure. 1.245 + 1.246 + protected: 1.247 + bool RefreshModuleList(); 1.248 + 1.249 + protected: 1.250 + bool initialized; 1.251 + bool allowMemoryAllocation; // True by default. If true then we allow allocating memory (and as a result provide less information). This is useful for when in an exception handler. 1.252 + bool moduleListUpdated; 1.253 + ModuleInfo moduleInfoArray[96]; // Cached list of modules we use. This is a fixed size because we need to use it during application exceptions. 1.254 + size_t moduleInfoArraySize; 1.255 + }; 1.256 + 1.257 + 1.258 + 1.259 + // ExceptionInfo 1.260 + // We need to be careful to avoid data types that can allocate memory while we are 1.261 + // handling an exception, as the memory system may be corrupted at that point in time. 1.262 + struct ExceptionInfo 1.263 + { 1.264 + tm time; // GM time. 1.265 + time_t timeVal; // GM time_t (seconds since 1970). 1.266 + void* backtrace[64]; 1.267 + size_t backtraceCount; 1.268 + ThreadHandle threadHandle; // 1.269 + ThreadSysId threadSysId; // 1.270 + char threadName[32]; // Cannot be an allocating String object. 1.271 + void* pExceptionInstructionAddress; 1.272 + void* pExceptionMemoryAddress; 1.273 + CPUContext cpuContext; 1.274 + char exceptionDescription[1024]; // Cannot be an allocating String object. 1.275 + SymbolInfo symbolInfo; // SymbolInfo for the exception location. 1.276 + 1.277 + #if defined(OVR_OS_MS) 1.278 + EXCEPTION_RECORD exceptionRecord; // This is a Windows SDK struct. 1.279 + #elif defined(OVR_OS_APPLE) 1.280 + uint64_t exceptionType; // e.g. EXC_BAD_INSTRUCTION, EXC_BAD_ACCESS, etc. 1.281 + uint32_t cpuExceptionId; // The x86/x64 CPU trap id. 1.282 + uint32_t cpuExceptionIdError; // The x86/x64 CPU trap id extra info. 1.283 + int64_t machExceptionDetail[4]; // Kernel exception code info. 1.284 + int machExceptionDetailCount; // Count of valid entries. 1.285 + #endif 1.286 + 1.287 + ExceptionInfo(); 1.288 + }; 1.289 + 1.290 + 1.291 + // Implments support for asynchronous exception handling and basic exception report generation. 1.292 + // If you are implementing exception handling for a commercial application and want auto-uploading 1.293 + // functionality you may want to consider using something like Google Breakpad. This exception handler 1.294 + // is for in-application debug/diagnostic services, though it can write a report that has similar 1.295 + // information to Breakpad or OS-provided reports such as Apple .crash files. 1.296 + // 1.297 + // Example usage: 1.298 + // ExceptionHandler exceptionHandler; 1.299 + // 1.300 + // int main(int, char**) 1.301 + // { 1.302 + // exceptionHandler.Enable(true); 1.303 + // exceptionHandler.SetExceptionListener(pSomeListener, 0); // Optional listener hook. 1.304 + // } 1.305 + // 1.306 + class ExceptionHandler 1.307 + { 1.308 + public: 1.309 + ExceptionHandler(); 1.310 + ~ExceptionHandler(); 1.311 + 1.312 + bool Enable(bool enable); 1.313 + 1.314 + // Some report info can be considered private information of the user, such as the current process list, 1.315 + // computer name, IP address or other identifying info, etc. We should not report this information for 1.316 + // external users unless they agree to this. 1.317 + void EnableReportPrivacy(bool enable); 1.318 + 1.319 + struct ExceptionListener 1.320 + { 1.321 + virtual ~ExceptionListener(){} 1.322 + virtual int HandleException(uintptr_t userValue, ExceptionHandler* pExceptionHandler, ExceptionInfo* pExceptionInfo, const char* reportFilePath) = 0; 1.323 + }; 1.324 + 1.325 + void SetExceptionListener(ExceptionListener* pExceptionListener, uintptr_t userValue); 1.326 + 1.327 + // What we do after handling the exception. 1.328 + enum ExceptionResponse 1.329 + { 1.330 + kERContinue, // Continue execution. Will result in the exception being re-generated unless the application has fixed the cause. Similar to Windows EXCEPTION_CONTINUE_EXECUTION. 1.331 + kERHandle, // Causes the OS to handle the exception as it normally would. Similar to Windows EXCEPTION_EXECUTE_HANDLER. 1.332 + kERTerminate, // Exit the application. 1.333 + kERThrow, // Re-throw the exception. Other handlers may catch it. Similar to Windows EXCEPTION_CONTINUE_SEARCH. 1.334 + kERDefault // Usually set to kERTerminate. 1.335 + }; 1.336 + 1.337 + void SetExceptionResponse(ExceptionResponse er) 1.338 + { exceptionResponse = er; } 1.339 + 1.340 + // Allws you to add an arbitrary description of the current application, which will be added to exception reports. 1.341 + void SetAppDescription(const char* appDescription); 1.342 + 1.343 + // If the report path has a "%s" in its name, then assume the path is a sprintf format and write it 1.344 + // with the %s specified as a date/time string. 1.345 + // The report path can be "default" to signify that you want to use the default user location. 1.346 + // Example usage: 1.347 + // handler.SetExceptionPaths("/Users/Current/Exceptions/Exception %s.txt"); 1.348 + void SetExceptionPaths(const char* exceptionReportPath, const char* exceptionMinidumpPath = nullptr); 1.349 + 1.350 + // Allows you to specify base directories for code paths, which can be used to associate exception addresses to lines 1.351 + // of code as opposed to just file names and line numbers, or function names plus binary offsets. 1.352 + void SetCodeBaseDirectoryPaths(const char* codeBaseDirectoryPathArray[], size_t codeBaseDirectoryPathCount); 1.353 + 1.354 + // Given an exception report at a given file path, returns a string suitable for displaying in a message 1.355 + // box or similar user interface during the handling of an exception. The returned string must be passed 1.356 + // to FreeMessageBoxText when complete. 1.357 + static const char* GetExceptionUIText(const char* exceptionReportPath); 1.358 + static void FreeExceptionUIText(const char* messageBoxText); 1.359 + 1.360 + protected: 1.361 + void WriteExceptionDescription(); 1.362 + void WriteReport(); 1.363 + void WriteReportLine(const char* pLine); 1.364 + void WriteReportLineF(const char* format, ...); 1.365 + void WriteThreadCallstack(ThreadHandle threadHandle, ThreadSysId threadSysId, const char* additionalInfo); 1.366 + void WriteMiniDump(); 1.367 + 1.368 + // Runtime constants 1.369 + bool enabled; 1.370 + bool reportPrivacyEnabled; // Defaults to true. 1.371 + ExceptionResponse exceptionResponse; // Defaults to kERHandle 1.372 + ExceptionListener* exceptionListener; 1.373 + uintptr_t exceptionListenerUserValue; 1.374 + String appDescription; 1.375 + String codeBasePathArray[6]; // 6 is arbitrary. 1.376 + char reportFilePath[OVR_MAX_PATH];// May be an encoded path, in that it has "%s" in it or is named "default". See reporFiletPathActual for the runtime actual report path. 1.377 + int miniDumpFlags; 1.378 + char miniDumpFilePath[OVR_MAX_PATH]; 1.379 + FILE* file; // Can/should we use OVR Files for this? 1.380 + char scratchBuffer[4096]; 1.381 + SymbolLookup symbolLookup; 1.382 + 1.383 + // Runtime variables 1.384 + bool exceptionOccurred; 1.385 + OVR::AtomicInt<uint32_t> handlingBusy; 1.386 + char reportFilePathActual[OVR_MAX_PATH]; 1.387 + char minidumpFilePathActual[OVR_MAX_PATH]; 1.388 + int terminateReturnValue; 1.389 + ExceptionInfo exceptionInfo; 1.390 + 1.391 + #if defined(OVR_OS_MS) 1.392 + void* vectoredHandle; 1.393 + LPTOP_LEVEL_EXCEPTION_FILTER previousFilter; 1.394 + LPEXCEPTION_POINTERS pExceptionPointers; 1.395 + 1.396 + friend LONG WINAPI Win32ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers); 1.397 + LONG ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers); 1.398 + 1.399 + #elif defined(OVR_OS_APPLE) 1.400 + struct SavedExceptionPorts 1.401 + { 1.402 + SavedExceptionPorts() : count(0) { memset(this, 0, sizeof(SavedExceptionPorts)); } 1.403 + 1.404 + mach_msg_type_number_t count; 1.405 + exception_mask_t masks[6]; 1.406 + exception_handler_t ports[6]; 1.407 + exception_behavior_t behaviors[6]; 1.408 + thread_state_flavor_t flavors[6]; 1.409 + }; 1.410 + 1.411 + friend void* ::MachHandlerThreadFunctionStatic(void*); 1.412 + friend int ::catch_mach_exception_raise_state_identity_OVR(mach_port_t, mach_port_t, mach_port_t, exception_type_t, 1.413 + mach_exception_data_type_t*, mach_msg_type_number_t, int*, thread_state_t, 1.414 + mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t*); 1.415 + 1.416 + bool InitMachExceptionHandler(); 1.417 + void ShutdownMachExceptionHandler(); 1.418 + void* MachHandlerThreadFunction(); 1.419 + kern_return_t HandleMachException(mach_port_t port, mach_port_t thread, mach_port_t task, exception_type_t exceptionType, 1.420 + mach_exception_data_type_t* pExceptionDetail, mach_msg_type_number_t exceptionDetailCount, 1.421 + int* pFlavor, thread_state_t pOldState, mach_msg_type_number_t oldStateCount, thread_state_t pNewState, 1.422 + mach_msg_type_number_t* pNewStateCount); 1.423 + kern_return_t ForwardMachException(mach_port_t thread, mach_port_t task, exception_type_t exceptionType, 1.424 + mach_exception_data_t pExceptionDetail, mach_msg_type_number_t exceptionDetailCount); 1.425 + 1.426 + bool machHandlerInitialized; 1.427 + mach_port_t machExceptionPort; 1.428 + SavedExceptionPorts machExceptionPortsSaved; 1.429 + volatile bool machThreadShouldContinue; 1.430 + volatile bool machThreadExecuting; 1.431 + pthread_t machThread; 1.432 + 1.433 + #elif defined(OVR_OS_LINUX) 1.434 + // To do. 1.435 + #endif 1.436 + }; 1.437 + 1.438 + 1.439 + // Identifies basic exception types for the CreateException function. 1.440 + enum CreateExceptionType 1.441 + { 1.442 + kCETAccessViolation, // Read or write to inaccessable memory. 1.443 + kCETAlignment, // Misaligned read or write. 1.444 + kCETDivideByZero, // Integer divide by zero. 1.445 + kCETFPU, // Floating point / VPU exception. 1.446 + kCETIllegalInstruction, // Illegal opcode. 1.447 + kCETStackCorruption, // Stack frame was corrupted. 1.448 + kCETStackOverflow, // Stack ran out of space, often due to infinite recursion. 1.449 + kCETTrap // System/OS trap (system call). 1.450 + }; 1.451 + 1.452 + 1.453 + // Creates an exception of the given type, primarily for testing. 1.454 + void CreateException(CreateExceptionType exceptionType); 1.455 + 1.456 + 1.457 + 1.458 +} // namespace OVR 1.459 + 1.460 + 1.461 +OVR_RESTORE_MSVC_WARNING() 1.462 + 1.463 + 1.464 +#endif // Header include guard