error.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 1999-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Tue Jun 22 14:59:48 1999
00010 // commit: $Id: error.cc 10137 2008-03-04 17:59:34Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/rutz/error.cc $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX.
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
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       // we don't use rutz::sfmt() here to generate the fstring,
00139       // because then we'd have a cyclic dependency between
00140       // rutz/sfmt.cc and rutz/error.cc
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

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:40 2008 by Doxygen version 1.5.5.