00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00033
00034 #ifndef GROOVX_RUTZ_ERROR_CC_UTC20050626084020_DEFINED
00035 #define GROOVX_RUTZ_ERROR_CC_UTC20050626084020_DEFINED
00036
00037 #include "rutz/error.h"
00038
00039 #include "rutz/backtrace.h"
00040 #include "rutz/error_context.h"
00041 #include "rutz/fstring.h"
00042 #include "rutz/mutex.h"
00043
00044 #include <cmath>
00045 #include <cstdlib>
00046 #include <new>
00047 #include <pthread.h>
00048
00049 #include "rutz/trace.h"
00050 #include "rutz/debug.h"
00051 GVX_DBG_REGISTER
00052
00053 namespace
00054 {
00055 rutz::backtrace* g_last_backtrace = 0;
00056 pthread_mutex_t g_last_backtrace_mutex = PTHREAD_MUTEX_INITIALIZER;
00057 }
00058
00059 rutz::error::error(const rutz::file_pos& pos) :
00060 std::exception(),
00061 m_msg(),
00062 m_context(rutz::error_context::current().get_text()),
00063 m_file_pos(pos),
00064 m_backtrace(new rutz::backtrace(rutz::backtrace::current()))
00065 {
00066 GVX_TRACE("rutz::error::error()");
00067
00068 dbg_dump(4, m_msg);
00069
00070 {
00071 GVX_MUTEX_LOCK(&g_last_backtrace_mutex);
00072
00073 if (g_last_backtrace == 0)
00074 g_last_backtrace = new rutz::backtrace(*m_backtrace);
00075 else
00076 *g_last_backtrace = *m_backtrace;
00077 }
00078
00079 if (GVX_DBG_LEVEL() >= 4)
00080 {
00081 m_backtrace->print();
00082 }
00083 }
00084
00085 rutz::error::error(const rutz::fstring& msg,
00086 const rutz::file_pos& pos) :
00087 std::exception(),
00088 m_msg(msg),
00089 m_context(rutz::error_context::current().get_text()),
00090 m_file_pos(pos),
00091 m_backtrace(new rutz::backtrace(rutz::backtrace::current()))
00092 {
00093 GVX_TRACE("rutz::error::error(fstring)");
00094
00095 dbg_dump(4, m_msg);
00096
00097 {
00098 GVX_MUTEX_LOCK(&g_last_backtrace_mutex);
00099
00100 if (g_last_backtrace == 0)
00101 g_last_backtrace = new rutz::backtrace(*m_backtrace);
00102 else
00103 *g_last_backtrace = *m_backtrace;
00104 }
00105
00106 if (GVX_DBG_LEVEL() >= 4)
00107 {
00108 m_backtrace->print();
00109 }
00110 }
00111
00112 rutz::error::error(const rutz::error& other) throw() :
00113 std::exception(other),
00114 m_msg(other.m_msg),
00115 m_context(other.m_context),
00116 m_file_pos(other.m_file_pos),
00117 m_backtrace(0)
00118 {
00119 GVX_TRACE("rutz::error::error(copy)");
00120
00121 dbg_dump(4, m_msg);
00122
00123 if (other.m_backtrace != 0)
00124 m_backtrace =
00125 new (std::nothrow) rutz::backtrace(*other.m_backtrace);
00126 }
00127
00128 rutz::error::~error() throw()
00129 {
00130 GVX_TRACE("rutz::error::~error");
00131 delete m_backtrace;
00132 }
00133
00134 const char* rutz::error::what() const throw()
00135 {
00136 if (m_what.length() == 0)
00137 {
00138
00139
00140
00141
00142 const size_t len =
00143 strlen(m_file_pos.m_file_name)
00144 + 2 + size_t(ceil(log10(m_file_pos.m_line_no)))
00145 + m_msg.length()
00146 + 1;
00147
00148 char buf[len];
00149
00150 if (snprintf(&buf[0], len, "at %s:%d:\n%s",
00151 m_file_pos.m_file_name,
00152 m_file_pos.m_line_no, m_msg.c_str()) < 0)
00153 {
00154 m_what = m_msg;
00155 }
00156 else
00157 {
00158 m_what = rutz::fstring(&buf[0]);
00159 }
00160 }
00161
00162 return m_what.c_str();
00163 }
00164
00165 void rutz::error::get_last_backtrace(rutz::backtrace& dst)
00166 {
00167 GVX_MUTEX_LOCK(&g_last_backtrace_mutex);
00168
00169 if (g_last_backtrace == 0)
00170 g_last_backtrace = new rutz::backtrace();
00171
00172 dst = *g_last_backtrace;
00173 }
00174
00175 static const char __attribute__((used)) vcid_groovx_rutz_error_cc_utc20050626084020[] = "$Id: error.cc 10137 2008-03-04 17:59:34Z rjpeters $ $HeadURL: file:
00176 #endif // !GROOVX_RUTZ_ERROR_CC_UTC20050626084020_DEFINED