00001 /* -*- mode:C++; c-basic-offset:4 -*- 00002 Shore-MT -- Multi-threaded port of the SHORE storage manager 00003 00004 Copyright (c) 2007-2009 00005 Data Intensive Applications and Systems Labaratory (DIAS) 00006 Ecole Polytechnique Federale de Lausanne 00007 00008 All Rights Reserved. 00009 00010 Permission to use, copy, modify and distribute this software and 00011 its documentation is hereby granted, provided that both the 00012 copyright notice and this permission notice appear in all copies of 00013 the software, derivative works or modified versions, and any 00014 portions thereof, and that both notices appear in supporting 00015 documentation. 00016 00017 This code is distributed in the hope that it will be useful, but 00018 WITHOUT ANY WARRANTY; without even the implied warranty of 00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS 00020 DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER 00021 RESULTING FROM THE USE OF THIS SOFTWARE. 00022 */ 00023 00024 /*<std-header orig-src='shore' incl-file-exclusion='W_DEBUG_H'> 00025 00026 $Id: w_debug.h,v 1.1 2010/12/09 15:29:05 nhall Exp $ 00027 00028 SHORE -- Scalable Heterogeneous Object REpository 00029 00030 Copyright (c) 1994-99 Computer Sciences Department, University of 00031 Wisconsin -- Madison 00032 All Rights Reserved. 00033 00034 Permission to use, copy, modify and distribute this software and its 00035 documentation is hereby granted, provided that both the copyright 00036 notice and this permission notice appear in all copies of the 00037 software, derivative works or modified versions, and any portions 00038 thereof, and that both notices appear in supporting documentation. 00039 00040 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY 00041 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS 00042 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND 00043 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 00044 00045 This software was developed with support by the Advanced Research 00046 Project Agency, ARPA order number 018 (formerly 8230), monitored by 00047 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518. 00048 Further funding for this work was provided by DARPA through 00049 Rome Research Laboratory Contract No. F30602-97-2-0247. 00050 00051 */ 00052 00053 #ifndef W_DEBUG_H 00054 #define W_DEBUG_H 00055 00056 #include "w_defines.h" 00057 00058 /* -- do not edit anything above this line -- </std-header>*/ 00059 00060 #ifdef __GNUG__ 00061 #pragma interface 00062 #endif 00063 00064 #ifndef W_BASE_H 00065 /* NB: DO NOT make this include w.h -- not yet */ 00066 #include <w_base.h> 00067 #endif /* W_BASE_H */ 00068 00069 #include <w_stream.h> 00070 00071 #ifndef ERRLOG_H 00072 #include <errlog.h> 00073 #endif /* ERRLOG_H */ 00074 00075 /**\file w_debug.h 00076 *\ingroup MACROS 00077 * 00078 * This is a set of macros for use with C or C++. They give various 00079 * levels of debugging printing when compiled with --enable-trace. 00080 * With tracing, message printing is under the control of an environment 00081 * variable DEBUG_FLAGS (see debug.cpp). 00082 * If that variable is set, its value must 00083 * be a string. The string is searched for __FILE__ and the function name 00084 * in which the debugging message occurs. If either one appears in the 00085 * string (value of the env variable), or if the string contains the 00086 * word "all", the message is printed. 00087 * 00088 * 00089 **** FUNC(fname) dumps the function name. 00090 **** RETURN prints that the function named by __func__ is returning 00091 * This macro MUST appear within braces if used after "if", 00092 * "else", "while", etc. 00093 * 00094 **** DBG(arg) prints line & file and the message arg if __func__ 00095 * appears in the debug environment variable. 00096 * The argument must be the innermost part of legit C++ 00097 * print statement, and it works ONLY in C++ sources. 00098 * 00099 * Example : 00100 * 00101 * \code 00102 * returntype 00103 * proc(args) 00104 * { 00105 * FUNC(proc); 00106 * ....body... 00107 * 00108 * DBG( 00109 * << "message" << value 00110 * << "more message"; 00111 * if(test) { 00112 * cerr << "xyz"; 00113 * } 00114 * cerr 00115 * ) 00116 * 00117 * ....more body... 00118 * if(predicate) { 00119 * RETURN value; 00120 * } 00121 * } 00122 * \endcode 00123 * 00124 * FUNC, and RETURN macros' definitions depend on how 00125 * the storage manager is configured. 00126 * They don't do a lot unless configured with --enable-trace 00127 */ 00128 #include <cassert> 00129 00130 #undef USE_REGEX 00131 00132 #ifdef USE_REGEX 00133 #include "regex_posix.h" 00134 #endif /* USE_REGEX */ 00135 00136 /* XXX missing type in vc++, hack around it here too, don't pollute 00137 global namespace too badly. */ 00138 typedef ios::fmtflags w_dbg_fmtflags; 00139 00140 00141 #ifdef W_TRACE 00142 00143 #define _strip_filename(f) f 00144 00145 00146 #define FUNC(fn)\ 00147 do { \ 00148 if(_w_debug.flag_on(__func__,__FILE__)) { \ 00149 _w_debug.clog << __LINE__ << " " \ 00150 << _strip_filename(__FILE__) << ": " << __func__ \ 00151 << flushl; \ 00152 } \ 00153 } while(0) 00154 00155 #define RETURN \ 00156 do { \ 00157 if(_w_debug.flag_on(__func__,__FILE__)) {\ 00158 w_dbg_fmtflags old = _w_debug.clog.setf(ios::dec, ios::basefield); \ 00159 _w_debug.clog << __LINE__ << " " << _strip_filename(__FILE__) << ":" ; \ 00160 _w_debug.clog.setf(old, ios::basefield); \ 00161 _w_debug.clog << "return from " << __func__ << flushl; } } while(0); \ 00162 return 00163 00164 #else /* -UW_TRACE */ 00165 # define FUNC(fn) 00166 # undef RETURN 00167 # define RETURN return 00168 #endif /* W_TRACE*/ 00169 00170 /* ************************************************************************ */ 00171 00172 /* ************************************************************************ 00173 * 00174 * Class w_debug, macros DBG, DBG_NONL, DBG1, DBG1_NONL: 00175 */ 00176 00177 00178 /**\brief An ErrLog used for tracing (configure --enable-trace) 00179 * 00180 * For tracing to be used, you must set the environment variable 00181 * DEBUG_FLAGS to a string containing the names of the files you 00182 * want traced, and 00183 * 00184 * DEBUG_FILE to the name of the output file to which the output 00185 * should be sent. If DEBUG_FILE is not set, the output goes to 00186 * stderr. 00187 */ 00188 class w_debug : public ErrLog { 00189 private: 00190 char *_flags; 00191 enum { _all = 0x1, _none = 0x2 }; 00192 unsigned int mask; 00193 int _trace_level; 00194 00195 #ifdef USE_REGEX 00196 static regex_t re_posix_re; 00197 static bool re_ready; 00198 static char* re_error_str; 00199 static char* re_comp_debug(const char* pattern); 00200 static int re_exec_debug(const char* string); 00201 #endif /* USE_REGEX */ 00202 00203 int all(void) { return (mask & _all) ? 1 : 0; } 00204 int none(void) { return (mask & _none) ? 1 : 0; } 00205 00206 public: 00207 w_debug(const char *n, const char *f); 00208 ~w_debug(); 00209 int flag_on(const char *fn, const char *file); 00210 const char *flags() { return _flags; } 00211 void setflags(const char *newflags); 00212 void memdump(void *p, int len); // hex dump of memory 00213 int trace_level() { return _trace_level; } 00214 }; 00215 extern w_debug _w_debug; 00216 00217 #if defined(W_TRACE) 00218 00219 # define DBG2(a,file,line) \ 00220 w_dbg_fmtflags old = _w_debug.clog.setf(ios::dec, ios::basefield); \ 00221 _w_debug.clog << _strip_filename(file) << ":" << line << ":" ; \ 00222 _w_debug.clog.setf(old, ios::basefield); \ 00223 _w_debug.clog a << flushl; 00224 00225 # define DBG1(a) do {\ 00226 if(_w_debug.flag_on(__func__,__FILE__)) { \ 00227 DBG2(a,__FILE__,__LINE__) \ 00228 } } while(0) 00229 00230 # define DBG(a) DBG1(a) 00231 00232 #else 00233 # define DBG(a) 00234 #endif /* defined(W_TRACE) */ 00235 /* ************************************************************************ */ 00236 00237 00238 #define DBGTHRD(arg) DBG(<<" th."<<sthread_t::me()->id << " " arg) 00239 00240 /*<std-footer incl-file-exclusion='W_DEBUG_H'> -- do not edit anything below this line -- */ 00241 00242 #endif /*</std-footer>*/