error.cc

Go to the documentation of this file.
00001 /** @file rutz/error.cc exception base class, derives from
00002     std::exception */
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 12074 2009-11-24 07:51:51Z itti $
00011 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/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 //
00032 ///////////////////////////////////////////////////////////////////////
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 #include <cstdio>
00049 
00050 #include "rutz/trace.h"
00051 #include "rutz/debug.h"
00052 GVX_DBG_REGISTER
00053 
00054 namespace
00055 {
00056   rutz::backtrace* g_last_backtrace = 0;
00057   pthread_mutex_t  g_last_backtrace_mutex = PTHREAD_MUTEX_INITIALIZER;
00058 }
00059 
00060 rutz::error::error(const rutz::file_pos& pos) :
00061   std::exception(),
00062   m_msg(),
00063   m_context(rutz::error_context::current().get_text()),
00064   m_file_pos(pos),
00065   m_backtrace(new rutz::backtrace(rutz::backtrace::current()))
00066 {
00067 GVX_TRACE("rutz::error::error()");
00068 
00069   dbg_dump(4, m_msg);
00070 
00071   {
00072     GVX_MUTEX_LOCK(&g_last_backtrace_mutex);
00073 
00074     if (g_last_backtrace == 0)
00075       g_last_backtrace = new rutz::backtrace(*m_backtrace);
00076     else
00077       *g_last_backtrace = *m_backtrace;
00078   }
00079 
00080   if (GVX_DBG_LEVEL() >= 4)
00081     {
00082       m_backtrace->print();
00083     }
00084 }
00085 
00086 rutz::error::error(const rutz::fstring& msg,
00087                    const rutz::file_pos& pos) :
00088   std::exception(),
00089   m_msg(msg),
00090   m_context(rutz::error_context::current().get_text()),
00091   m_file_pos(pos),
00092   m_backtrace(new rutz::backtrace(rutz::backtrace::current()))
00093 {
00094 GVX_TRACE("rutz::error::error(fstring)");
00095 
00096   dbg_dump(4, m_msg);
00097 
00098   {
00099     GVX_MUTEX_LOCK(&g_last_backtrace_mutex);
00100 
00101     if (g_last_backtrace == 0)
00102       g_last_backtrace = new rutz::backtrace(*m_backtrace);
00103     else
00104       *g_last_backtrace = *m_backtrace;
00105   }
00106 
00107   if (GVX_DBG_LEVEL() >= 4)
00108     {
00109       m_backtrace->print();
00110     }
00111 }
00112 
00113 rutz::error::error(const rutz::error& other) throw() :
00114   std::exception(other),
00115   m_msg(other.m_msg),
00116   m_context(other.m_context),
00117   m_file_pos(other.m_file_pos),
00118   m_backtrace(0)
00119 {
00120 GVX_TRACE("rutz::error::error(copy)");
00121 
00122   dbg_dump(4, m_msg);
00123 
00124   if (other.m_backtrace != 0)
00125     m_backtrace =
00126       new (std::nothrow) rutz::backtrace(*other.m_backtrace);
00127 }
00128 
00129 rutz::error::~error() throw()
00130 {
00131 GVX_TRACE("rutz::error::~error");
00132   delete m_backtrace;
00133 }
00134 
00135 const char* rutz::error::what() const throw()
00136 {
00137   if (m_what.length() == 0)
00138     {
00139       // we don't use rutz::sfmt() here to generate the fstring,
00140       // because then we'd have a cyclic dependency between
00141       // rutz/sfmt.cc and rutz/error.cc
00142 
00143       const size_t len =
00144         strlen(m_file_pos.m_file_name)
00145         + 2 + size_t(ceil(log10(m_file_pos.m_line_no)))
00146         + m_msg.length()
00147         + 1;
00148 
00149       char buf[len];
00150 
00151       if (snprintf(&buf[0], len, "at %s:%d:\n%s",
00152                    m_file_pos.m_file_name,
00153                    m_file_pos.m_line_no, m_msg.c_str()) < 0)
00154         {
00155           m_what = m_msg;
00156         }
00157       else
00158         {
00159           m_what = rutz::fstring(&buf[0]);
00160         }
00161     }
00162 
00163   return m_what.c_str();
00164 }
00165 
00166 void rutz::error::get_last_backtrace(rutz::backtrace& dst)
00167 {
00168   GVX_MUTEX_LOCK(&g_last_backtrace_mutex);
00169 
00170   if (g_last_backtrace == 0)
00171     g_last_backtrace = new rutz::backtrace();
00172 
00173   dst = *g_last_backtrace;
00174 }
00175 
00176 static const char __attribute__((used)) vcid_groovx_rutz_error_cc_utc20050626084020[] = "$Id: error.cc 12074 2009-11-24 07:51:51Z itti $ $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/error.cc $";
00177 #endif // !GROOVX_RUTZ_ERROR_CC_UTC20050626084020_DEFINED
Generated on Sun May 8 08:06:39 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3