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 #include <PVLE/Util/TracedException.h>
00031 #include <PVLE/Util/Util.h>
00032
00033
00034
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 TracedException::TracedException( const std::string& strReason, const std::string& strFuncName ) :
00065 m_Reason(strReason), runtime_error(strReason)
00066 {
00067 UpdateFunctionStack(strFuncName);
00068 }
00069
00070
00071 TracedException::TracedException( const boost::format& fmtReason, const std::string& strFuncName) :
00072 m_Reason(fmtReason.str()), runtime_error(fmtReason.str())
00073 {
00074 UpdateFunctionStack(strFuncName);
00075 }
00076
00077
00078
00079 TracedException::~TracedException() throw()
00080 {
00081 }
00082
00083
00084
00085
00086
00087
00088
00089 const std::string& TracedException::GetReason() const
00090 {
00091 return m_Reason;
00092 }
00093
00094 const std::string TracedException::GetClassStack() const
00095 {
00096 std::string strStack;
00097 std::vector<std::string>::const_reverse_iterator cit;
00098
00099
00100 strStack.reserve(4000);
00101
00102
00103 for( cit = m_FuncStack.rbegin(); cit != m_FuncStack.rend(); ++cit)
00104 {
00105 strStack += *(cit);
00106 if ( *(cit) != m_FuncStack.front() ) strStack += "->";
00107 }
00108
00109
00110
00111 return strStack;
00112 }
00113
00114
00115
00116 #ifdef TRACED_EXCEPTION_USES_SEH
00117
00118 #ifdef WIN32
00119 #ifndef WIN32_LEAN_AND_MEAN
00120 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
00121 #endif
00122 #include <windows.h>
00123 #endif
00124
00125
00126 void TracedException::SE_Translator(unsigned int SE_e, _EXCEPTION_POINTERS* pExp )
00127 {
00128
00129 std::string strExcept("Asynchroneous exception ");
00130 std::string strAddress("(0x????????)");
00131
00133 switch(SE_e)
00134 {
00135 case EXCEPTION_DATATYPE_MISALIGNMENT:
00136 strExcept += "EXCEPTION_DATATYPE_MISALIGNMENT";
00137 break;
00138 case EXCEPTION_ACCESS_VIOLATION:
00139 strExcept += "EXCEPTION_ACCESS_VIOLATION";
00140 break;
00141 case EXCEPTION_IN_PAGE_ERROR:
00142 strExcept += "EXCEPTION_IN_PAGE_ERROR";
00143 break;
00144 case EXCEPTION_INVALID_HANDLE:
00145 strExcept += "EXCEPTION_INVALID_HANDLE";
00146 break;
00147 case EXCEPTION_ILLEGAL_INSTRUCTION:
00148 strExcept += "EXCEPTION_ILLEGAL_INSTRUCTION";
00149 break;
00150 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
00151 strExcept += "EXCEPTION_NONCONTINUABLE_EXCEPTION";
00152 break;
00153 case EXCEPTION_INVALID_DISPOSITION:
00154 strExcept += "EXCEPTION_INVALID_DISPOSITION";
00155 break;
00156 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
00157 strExcept += "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
00158 break;
00159 case EXCEPTION_FLT_DENORMAL_OPERAND:
00160 strExcept += "EXCEPTION_FLT_DENORMAL_OPERAND";
00161 break;
00162 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
00163 strExcept += "EXCEPTION_FLT_DIVIDE_BY_ZERO";
00164 break;
00165 case EXCEPTION_FLT_INEXACT_RESULT:
00166 strExcept += "EXCEPTION_FLT_INEXACT_RESULT";
00167 break;
00168 case EXCEPTION_FLT_INVALID_OPERATION:
00169 strExcept += "EXCEPTION_FLT_INVALID_OPERATION";
00170 break;
00171 case EXCEPTION_FLT_OVERFLOW:
00172 strExcept += "EXCEPTION_FLT_OVERFLOW";
00173 break;
00174 case EXCEPTION_FLT_STACK_CHECK:
00175 strExcept += "EXCEPTION_FLT_STACK_CHECK";
00176 break;
00177 case EXCEPTION_FLT_UNDERFLOW:
00178 strExcept += "EXCEPTION_FLT_UNDERFLOW";
00179 break;
00180 case EXCEPTION_INT_DIVIDE_BY_ZERO:
00181 strExcept += "EXCEPTION_INT_DIVIDE_BY_ZERO";
00182 break;
00183 case EXCEPTION_INT_OVERFLOW:
00184 strExcept += "EXCEPTION_INT_OVERFLOW";
00185 break;
00186 case EXCEPTION_PRIV_INSTRUCTION:
00187 strExcept += "EXCEPTION_PRIV_INSTRUCTION";
00188 break;
00189 case EXCEPTION_STACK_OVERFLOW:
00190 strExcept += "EXCEPTION_STACK_OVERFLOW";
00191 break;
00192 default:
00193
00195 strExcept += "EXCEPTION_UNKNOWN";
00196 return;
00197 }
00198
00199
00200 if (pExp)
00201 {
00202 strAddress = str(boost::format("(0x%08X)") % pExp->ContextRecord->Eip);
00203 }
00204
00205
00206
00207 throw TracedException( strExcept, strAddress);
00208 }
00209
00210
00211 #else
00212
00213 void TracedException::SignalHandler(int sigint)
00214 {
00215
00216 std::string strExcept("Asynchroneous exception ");
00217 std::string strAddress("(0x????????)");
00218
00219 switch(sigint)
00220 {
00221 case SIGSEGV:
00222 strExcept += "SIGSEGV";
00223 break;
00224 case SIGILL:
00225 strExcept += "SIGILL";
00226 break;
00227 case SIGFPE:
00228 strExcept += "SIGFPE";
00229 break;
00230 default:
00231 strExcept += "EXCEPTION_UNKNOWN";
00232 return;
00233 }
00234
00236
00237
00238 throw TracedException( strExcept, strAddress);
00239 }
00240
00241 #endif //TRACED_EXCEPTION_USES_SEH
00242
00243
00244 void TracedException::UpdateFunctionStack( const std::string& strFuncName )
00245 {
00246 m_FuncStack.push_back(strFuncName);
00247 }