//************************************************************************** //** //** ## ## ## ## ## #### #### ### ### //** ## ## ## ## ## ## ## ## ## ## #### #### //** ## ## ## ## ## ## ## ## ## ## ## ## ## ## //** ## ## ######## ## ## ## ## ## ## ## ### ## //** ### ## ## ### ## ## ## ## ## ## //** # ## ## # #### #### ## ## //** //** $Id: exception.h 4206 2010-04-03 16:32:33Z dj_jl $ //** //** Copyright (C) 1999-2010 Jānis Legzdiņš //** //** This program is free software; you can redistribute it and/or //** modify it under the terms of the GNU General Public License //** as published by the Free Software Foundation; either version 2 //** of the License, or (at your option) any later version. //** //** This program is distributed in the hope that it will be useful, //** but WITHOUT ANY WARRANTY; without even the implied warranty of //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //** GNU General Public License for more details. //** //************************************************************************** #define DO_GUARD 1 #define DO_CHECK 1 #ifdef PARANOID #define DO_GUARD_SLOW 1 #define DO_CHECK_SLOW 1 #endif //========================================================================== // // Exceptions // //========================================================================== class VException : VInterface { public: virtual const char* What() const = 0; }; #define MAX_ERROR_TEXT_SIZE 1024 class VavoomError : public VException { public: char message[MAX_ERROR_TEXT_SIZE]; explicit VavoomError(const char *text); const char* What() const; }; class RecoverableError : public VavoomError { public: explicit RecoverableError(const char *text) : VavoomError(text) { } }; class ZoneError : public VavoomError { public: explicit ZoneError(const char* text) : VavoomError(text) { } }; //========================================================================== // // Guard macros // //========================================================================== // Turn on usage of context in guard macros on platforms where it's not // safe to throw an exception in signal handler. #if DO_GUARD && defined(__linux__) #define USE_GUARD_SIGNAL_CONTEXT #endif #ifdef USE_GUARD_SIGNAL_CONTEXT #include // Stack control. class __Context { public: __Context() { memcpy(&Last, &Env, sizeof(jmp_buf)); } ~__Context() { memcpy(&Env, &Last, sizeof(jmp_buf)); } static jmp_buf Env; static const char* ErrToThrow; protected: jmp_buf Last; }; #endif #if defined(_DEBUG) || !DO_GUARD #define guard(name) {static const char __FUNC_NAME__[] = #name; { #define unguard }} #define unguardf(msg) }} #elif defined(USE_GUARD_SIGNAL_CONTEXT) #define guard(name) {static const char __FUNC_NAME__[] = #name; \ __Context __LOCAL_CONTEXT__; try { if (setjmp(__Context::Env)) { \ throw VavoomError(__Context::ErrToThrow); } else { #define unguard }} catch (RecoverableError &e) { throw e; } \ catch (...) { Host_CoreDump(__FUNC_NAME__); throw; }} #define unguardf(msg) }} catch (RecoverableError &e) { throw e; } \ catch (...) { Host_CoreDump(__FUNC_NAME__); Host_CoreDump msg; throw; }} #else #define guard(name) {static const char __FUNC_NAME__[] = #name; try { #define unguard } catch (RecoverableError &e) { throw e; } \ catch (...) { Host_CoreDump(__FUNC_NAME__); throw; }} #define unguardf(msg) } catch (RecoverableError &e) { throw e; } \ catch (...) { Host_CoreDump(__FUNC_NAME__); Host_CoreDump msg; throw; }} #endif #if !defined(_DEBUG) && DO_GUARD_SLOW #define guardSlow(name) guard(name) #define unguardSlow unguard #define unguardfSlow(msg) unguardf(msg) #else #define guardSlow(name) { #define unguardSlow } #define unguardfSlow(msg) } #endif void Host_CoreDump(const char *fmt, ...); void __attribute__((noreturn, format(printf, 1, 2))) __declspec(noreturn) Sys_Error(const char*, ...); //========================================================================== // // Assertion macros // //========================================================================== #if DO_CHECK #define check(e) if (!(e)) throw VavoomError("Assertion failed: " #e) #define verify(e) if (!(e)) throw VavoomError("Assertion failed: " #e) #else #define check(e) #define verify(e) (e) #endif #if DO_CHECK_SLOW #define checkSlow(e) check(e) #define verifySlow(e) verify(e) #else #define checkSlow(e) #define verifySlow(e) (e) #endif