1 //************************************************************************** 2 //** 3 //** ## ## ## ## ## #### #### ### ### 4 //** ## ## ## ## ## ## ## ## ## ## #### #### 5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ## 6 //** ## ## ######## ## ## ## ## ## ## ## ### ## 7 //** ### ## ## ### ## ## ## ## ## ## 8 //** # ## ## # #### #### ## ## 9 //** 10 //** $Id: exception.h 4206 2010-04-03 16:32:33Z dj_jl $ 11 //** 12 //** Copyright (C) 1999-2010 Jānis Legzdiņš 13 //** 14 //** This program is free software; you can redistribute it and/or 15 //** modify it under the terms of the GNU General Public License 16 //** as published by the Free Software Foundation; either version 2 17 //** of the License, or (at your option) any later version. 18 //** 19 //** This program is distributed in the hope that it will be useful, 20 //** but WITHOUT ANY WARRANTY; without even the implied warranty of 21 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 //** GNU General Public License for more details. 23 //** 24 //************************************************************************** 25 26 #define DO_GUARD 1 27 #define DO_CHECK 1 28 29 #ifdef PARANOID 30 #define DO_GUARD_SLOW 1 31 #define DO_CHECK_SLOW 1 32 #endif 33 34 //========================================================================== 35 // 36 // Exceptions 37 // 38 //========================================================================== 39 40 class VException : VInterface 41 { 42 public: 43 virtual const char* What() const = 0; 44 }; 45 46 #define MAX_ERROR_TEXT_SIZE 1024 47 48 class VavoomError : public VException 49 { 50 public: 51 char message[MAX_ERROR_TEXT_SIZE]; 52 53 explicit VavoomError(const char *text); 54 const char* What() const; 55 }; 56 57 class RecoverableError : public VavoomError 58 { 59 public: RecoverableError(const char * text)60 explicit RecoverableError(const char *text) : VavoomError(text) { } 61 }; 62 63 class ZoneError : public VavoomError 64 { 65 public: ZoneError(const char * text)66 explicit ZoneError(const char* text) : VavoomError(text) { } 67 }; 68 69 //========================================================================== 70 // 71 // Guard macros 72 // 73 //========================================================================== 74 75 // Turn on usage of context in guard macros on platforms where it's not 76 // safe to throw an exception in signal handler. 77 #if DO_GUARD && defined(__linux__) 78 #define USE_GUARD_SIGNAL_CONTEXT 79 #endif 80 81 #ifdef USE_GUARD_SIGNAL_CONTEXT 82 #include <setjmp.h> 83 // Stack control. 84 class __Context 85 { 86 public: __Context()87 __Context() { memcpy(&Last, &Env, sizeof(jmp_buf)); } ~__Context()88 ~__Context() { memcpy(&Env, &Last, sizeof(jmp_buf)); } 89 static jmp_buf Env; 90 static const char* ErrToThrow; 91 92 protected: 93 jmp_buf Last; 94 }; 95 #endif 96 97 #if defined(_DEBUG) || !DO_GUARD 98 #define guard(name) {static const char __FUNC_NAME__[] = #name; { 99 #define unguard }} 100 #define unguardf(msg) }} 101 #elif defined(USE_GUARD_SIGNAL_CONTEXT) 102 #define guard(name) {static const char __FUNC_NAME__[] = #name; \ 103 __Context __LOCAL_CONTEXT__; try { if (setjmp(__Context::Env)) { \ 104 throw VavoomError(__Context::ErrToThrow); } else { 105 #define unguard }} catch (RecoverableError &e) { throw e; } \ 106 catch (...) { Host_CoreDump(__FUNC_NAME__); throw; }} 107 #define unguardf(msg) }} catch (RecoverableError &e) { throw e; } \ 108 catch (...) { Host_CoreDump(__FUNC_NAME__); Host_CoreDump msg; throw; }} 109 #else 110 #define guard(name) {static const char __FUNC_NAME__[] = #name; try { 111 #define unguard } catch (RecoverableError &e) { throw e; } \ 112 catch (...) { Host_CoreDump(__FUNC_NAME__); throw; }} 113 #define unguardf(msg) } catch (RecoverableError &e) { throw e; } \ 114 catch (...) { Host_CoreDump(__FUNC_NAME__); Host_CoreDump msg; throw; }} 115 #endif 116 117 #if !defined(_DEBUG) && DO_GUARD_SLOW 118 #define guardSlow(name) guard(name) 119 #define unguardSlow unguard 120 #define unguardfSlow(msg) unguardf(msg) 121 #else 122 #define guardSlow(name) { 123 #define unguardSlow } 124 #define unguardfSlow(msg) } 125 #endif 126 127 void Host_CoreDump(const char *fmt, ...); 128 void __attribute__((noreturn, format(printf, 1, 2))) __declspec(noreturn) 129 Sys_Error(const char*, ...); 130 131 //========================================================================== 132 // 133 // Assertion macros 134 // 135 //========================================================================== 136 137 #if DO_CHECK 138 #define check(e) if (!(e)) throw VavoomError("Assertion failed: " #e) 139 #define verify(e) if (!(e)) throw VavoomError("Assertion failed: " #e) 140 #else 141 #define check(e) 142 #define verify(e) (e) 143 #endif 144 145 #if DO_CHECK_SLOW 146 #define checkSlow(e) check(e) 147 #define verifySlow(e) verify(e) 148 #else 149 #define checkSlow(e) 150 #define verifySlow(e) (e) 151 #endif 152