debug.cc

Go to the documentation of this file.
00001 /** @file rutz/debug.cc debugging facilities, assertions,
00002     preconditions, postconditions, invariants */
00003 ///////////////////////////////////////////////////////////////////////
00004 //
00005 // Copyright (c) 2000-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: Mon Oct  9 18:48:38 2000
00010 // commit: $Id: debug.cc 12074 2009-11-24 07:51:51Z itti $
00011 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/debug.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_DEBUG_CC_UTC20050626084020_DEFINED
00035 #define GROOVX_RUTZ_DEBUG_CC_UTC20050626084020_DEFINED
00036 
00037 #include "rutz/debug.h"
00038 GVX_DBG_REGISTER
00039 
00040 #include "rutz/backtrace.h"
00041 #include "rutz/mutex.h"
00042 
00043 #include <cstdlib>
00044 #include <cstring>
00045 #include <iomanip>
00046 #include <iostream>
00047 
00048 #include <cstdio>
00049 #include <cerrno>
00050 
00051 namespace
00052 {
00053   const int MAX_KEYS = 1024;
00054 
00055   // output-related variables and guard mutex
00056   bool            g_debug_line_complete = true;
00057   pthread_mutex_t g_debug_output_mutex = PTHREAD_MUTEX_INITIALIZER;
00058 
00059   // debug keys and guard mutex
00060   int             g_debug_next_key = 0;
00061   unsigned char   g_key_levels[MAX_KEYS];
00062   const char*     g_key_filenames[MAX_KEYS];
00063   pthread_mutex_t g_debug_keys_mutex = PTHREAD_MUTEX_INITIALIZER;
00064 
00065   void show_position(int level, const char* where, int line_no) throw()
00066   {
00067     std::cerr << "[" << std::setw(2) << level << "] "
00068               << std::setw(20) << where << ":"
00069               << line_no << ": ";
00070   }
00071 }
00072 
00073 #define EVAL_IMPL(T)                                    \
00074 void rutz::debug::eval(const char* what, int level,     \
00075                        const char* where, int line_no,  \
00076                        bool nl, T expr) throw()         \
00077 {                                                       \
00078   GVX_MUTEX_LOCK(&g_debug_output_mutex);                \
00079   using std::cerr;                                      \
00080   cerr.exceptions(std::ios::goodbit);                   \
00081   if (g_debug_line_complete)                            \
00082     {                                                   \
00083       show_position(level, where, line_no);             \
00084     }                                                   \
00085   if (what)                                             \
00086     {                                                   \
00087       cerr << "(" << #T << ") " << what << " = ";       \
00088     }                                                   \
00089   cerr << expr;                                         \
00090   if (nl)                                               \
00091     {                                                   \
00092       cerr << "\n";                                     \
00093       g_debug_line_complete = true;                     \
00094     }                                                   \
00095   else                                                  \
00096     {                                                   \
00097       cerr << ", ";                                     \
00098       g_debug_line_complete = false;                    \
00099     }                                                   \
00100 }
00101 
00102 EVAL_IMPL(bool);
00103 EVAL_IMPL(char);
00104 EVAL_IMPL(unsigned char);
00105 EVAL_IMPL(short);
00106 EVAL_IMPL(unsigned short);
00107 EVAL_IMPL(int);
00108 EVAL_IMPL(unsigned int);
00109 EVAL_IMPL(long);
00110 EVAL_IMPL(unsigned long);
00111 EVAL_IMPL(float);
00112 EVAL_IMPL(double);
00113 EVAL_IMPL(const char*);
00114 EVAL_IMPL(void*);
00115 
00116 void rutz::debug::dump(const char* what, int level, const char* where, int line_no) throw()
00117 {
00118   GVX_MUTEX_LOCK(&g_debug_output_mutex);
00119   std::cerr.exceptions(std::ios::goodbit);
00120   show_position(level, where, line_no);
00121   std::cerr << std::setw(15) << what << " := ";
00122   g_debug_line_complete = false;
00123 }
00124 
00125 void rutz::debug::start_newline() throw()
00126 {
00127   GVX_MUTEX_LOCK(&g_debug_output_mutex);
00128   std::cerr.exceptions(std::ios::goodbit);
00129   if (!g_debug_line_complete)
00130     {
00131       std::cerr << '\n';
00132       g_debug_line_complete = true;
00133     }
00134 }
00135 
00136 void rutz::debug::panic_aux(const char* what, const char* where,
00137                             int line_no) throw()
00138 {
00139   fprintf(stderr, "Panic (%s:%d):\n\t%s\n\n",
00140           where, line_no, what);
00141   rutz::backtrace::current().print();
00142   abort();
00143 }
00144 
00145 void rutz::debug::assert_aux(const char* what, const char* where,
00146                              int line_no) throw()
00147 {
00148   fprintf(stderr, "Assertion failed (%s:%d):\n\texpected '%s'\n\n",
00149           where, line_no, what);
00150   rutz::backtrace::current().print();
00151   abort();
00152 }
00153 
00154 void rutz::debug::precondition_aux(const char* what, const char* where,
00155                                    int line_no) throw()
00156 {
00157   fprintf(stderr, "Precondition failed (%s:%d):\n\texpected '%s'\n\n",
00158           where, line_no, what);
00159   rutz::backtrace::current().print();
00160   abort();
00161 }
00162 
00163 void rutz::debug::postcondition_aux(const char* what, const char* where,
00164                                     int line_no) throw()
00165 {
00166   fprintf(stderr, "Postcondition failed (%s:%d):\n\texpected '%s'\n\n",
00167           where, line_no, what);
00168   rutz::backtrace::current().print();
00169   abort();
00170 }
00171 
00172 void rutz::debug::invariant_aux(const char* what, const char* where,
00173                                 int line_no) throw()
00174 {
00175   fprintf(stderr, "Invariant failed (%s:%d):\n\texpected '%s'\n\n",
00176           where, line_no, what);
00177   rutz::backtrace::current().print();
00178   abort();
00179 }
00180 
00181 int rutz::debug::create_key(const char* filename)
00182 {
00183   GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00184   const int key = g_debug_next_key;
00185   g_key_filenames[key] = filename;
00186   if (g_debug_next_key < (MAX_KEYS-1))
00187     ++g_debug_next_key;
00188   return key;
00189 }
00190 
00191 bool rutz::debug::is_valid_key(int key)
00192 {
00193   return key >= 0 && key < MAX_KEYS;
00194 }
00195 
00196 int rutz::debug::lookup_key(const char* filename)
00197 {
00198   GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00199   for (int i = 0; i < g_debug_next_key; ++i)
00200     {
00201       if (strcmp(g_key_filenames[i], filename) == 0)
00202         return i;
00203     }
00204   return -1;
00205 }
00206 
00207 int rutz::debug::get_level_for_key(int key)
00208 {
00209   GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00210   if (key < MAX_KEYS)
00211     return g_key_levels[key];
00212   return 0;
00213 }
00214 
00215 void rutz::debug::set_level_for_key(int key, int level)
00216 {
00217   GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00218   if (key <MAX_KEYS)
00219     g_key_levels[key] = level;
00220 }
00221 
00222 const char* rutz::debug::get_filename_for_key(int key)
00223 {
00224   GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00225   return g_key_filenames[key];
00226 }
00227 
00228 void rutz::debug::set_global_level(int lev)
00229 {
00230   GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00231   for (int i = 0; i < MAX_KEYS; ++i)
00232     g_key_levels[i] = (unsigned char) lev;
00233 }
00234 
00235 static const char __attribute__((used)) vcid_groovx_rutz_debug_cc_utc20050626084020[] = "$Id: debug.cc 12074 2009-11-24 07:51:51Z itti $ $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/debug.cc $";
00236 #endif // !GROOVX_RUTZ_DEBUG_CC_UTC20050626084020_DEFINED
Generated on Sun May 8 08:42:09 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3