00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00029
00030 #ifndef UTIL_PVEXCEPTION_H
00031 #define UTIL_PVEXCEPTION_H
00032
00033 #include <PVLE/Export.h>
00034 #include <PVLE/Config.h>
00035
00036
00190 #include <exception>
00191 #include <stdexcept>
00192 #include <string>
00193 #include <PVLE/Util/Log.h>
00194
00195
00196
00197
00198 #include <boost/format.hpp>
00199
00200
00201
00202
00203
00204
00205
00206 #if defined(_MSC_VER) && (_MSC_VER<1400)
00207 #pragma warning(push)
00208 #pragma warning(disable : 4520)
00209 #endif
00210
00211
00212
00213
00214
00215
00216 #ifdef WIN32
00217 #ifndef MINGW
00218 #define TRACED_EXCEPTION_USES_SEH
00219 #endif //MINGW
00220 #endif //WIN32
00221
00222
00223
00224 #ifdef TRACED_EXCEPTION_USES_SEH
00225
00226
00227 #include <eh.h>
00228
00229
00230
00231
00232
00233 #define INIT_TRACED_EXCEPTIONS _set_se_translator(TracedException::SE_Translator)
00234
00235 #else
00236
00237 #include <signal.h>
00238
00240
00241 #define INIT_TRACED_EXCEPTIONS signal(SIGSEGV,TracedException::SignalHandler); \
00242 signal(SIGILL,TracedException::SignalHandler); \
00243 signal(SIGFPE,TracedException::SignalHandler);
00244 #endif //TRACED_EXCEPTION_USES_SEH
00245
00246
00248 #define THROW_TRACED_EXCEPTION(Reason) throw TracedException(Reason, __PVLE_METHOD__)
00249
00251 #define THROW_TRACED_FMT_EXCEPTION(Reason, Args) throw TracedException( boost::format(Reason) % Args, __PVLE_METHOD__)
00252
00254 #define THROW_TRACED_EXCEPTION_FROM(Reason, FunctionName) throw TracedException(Reason, FunctionName)
00255
00257 #define THROW_TRACED_FMT_EXCEPTION_FROM(Reason, FunctionName, Args) throw TracedException( boost::format(Reason) % Args, FunctionName)
00258
00259
00261 #define CATCH_TRACED_EXCEPTION_FROM(FunctionName) catch( TracedException &e ) { e.UpdateFunctionStack(FunctionName); throw e; } \
00262 catch( std::exception &e ) { throw TracedException(e.what(), FunctionName); } \
00263 catch( std::string &e ) { throw TracedException(e , FunctionName); } \
00264 catch( char * e ) { throw TracedException(e , FunctionName); } \
00265 catch(...) { throw TracedException("Undefined Exception", FunctionName); }
00266
00268 #define CATCH_TRACED_EXCEPTION CATCH_TRACED_EXCEPTION_FROM(__PVLE_METHOD__)
00269
00270
00272 #define TRY_BLOCK_START try {
00273 #define CATCH_CUSTOM_EXCEPTION(FilterName) } catch(FilterName) {
00274 #define TRY_BLOCK_END } CATCH_TRACED_EXCEPTION
00275 #define TRY_BLOCK_END_FROM(FunctionName) } CATCH_TRACED_EXCEPTION(FunctionName)
00276
00277
00278
00279 #if ENABLE_DEBUG_EXCEPTION_TRACE
00280 #define DBG_TRY_BLOCK_START TRY_BLOCK_START
00281 #define DBG_CATCH_CUSTOM_EXCEPTION(FilterName) CATCH_CUSTOM_EXCEPTION(FilterName)
00282 #define DBG_TRY_BLOCK_END TRY_BLOCK_END
00283 #define DBG_TRY_BLOCK_END_FROM(FunctionName) TRY_BLOCK_END_FROM(FunctionName)
00284 #else
00285 #define DBG_TRY_BLOCK_START ((void)0);
00286 #define DBG_CATCH_CUSTOM_EXCEPTION(FilterName) ((void)0);
00287 #define DBG_TRY_BLOCK_END ((void)0);
00288 #define DBG_TRY_BLOCK_END_FROM(FunctionName) ((void)0);
00289 #endif
00290
00291
00299 class PVLE_EXPORT TracedException : public std::runtime_error
00300 {
00301
00302 public:
00303
00304
00305 TracedException( const std::string& strReason = "Unknown Exception",
00306 const std::string& strFuncName = "");
00307 TracedException( const boost::format& fmtReason,
00308 const std::string& strFuncName = "");
00309 virtual ~TracedException() throw();
00310
00311
00312
00313 const std::string& GetReason() const;
00314 const std::string GetClassStack() const;
00315
00316
00317
00318 void UpdateFunctionStack( const std::string& strFuncName );
00319
00320
00321 #ifdef TRACED_EXCEPTION_USES_SEH
00322
00323 static void SE_Translator(unsigned int SE_e, _EXCEPTION_POINTERS* pExp );
00324 #else
00325
00326 static void SignalHandler(int sigint);
00327 #endif //TRACED_EXCEPTION_USES_SEH
00328
00329 private:
00330
00331 std::string m_Reason;
00332 std::vector<std::string> m_FuncStack;
00333
00334 };
00335
00336
00337
00338 #if defined(_MSC_VER) && (_MSC_VER<1400)
00339 #pragma warning(pop)
00340 #endif
00341
00342
00343 #endif // UTIL_PVEXCEPTION_H