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.19 2010/05/26 01:20:23 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 **** DUMP(x) prints x (along with line & file) 00090 * if "x" is found in debug environment variable 00091 * 00092 **** FUNC(fname) DUMPs the function name. 00093 **** RETURN prints that the function named by __func__ is returning 00094 * This macro MUST appear within braces if used after "if", 00095 * "else", "while", etc. 00096 * 00097 **** DBG(arg) prints line & file and the message arg if __func__ 00098 * appears in the debug environment variable. 00099 * The argument must be the innermost part of legit C++ 00100 * print statement, and it works ONLY in C++ sources. 00101 * 00102 * Example : 00103 * 00104 * \code 00105 * returntype 00106 * proc(args) 00107 * { 00108 * FUNC(proc); 00109 * ....body... 00110 * 00111 * DBG( 00112 * << "message" << value 00113 * << "more message"; 00114 * if(test) { 00115 * cerr << "xyz"; 00116 * } 00117 * cerr 00118 * ) 00119 * 00120 * ....more body... 00121 * if(predicate) { 00122 * RETURN value; 00123 * } 00124 * } 00125 * \endcode 00126 * 00127 * DUMP, FUNC, and RETURN macros' definitions depend on how 00128 * the storage manager is configured. 00129 * They don't do a lot unless configured with --enable-trace 00130 */ 00131 #include <cassert> 00132 00133 #undef USE_REGEX 00134 00135 #ifdef USE_REGEX 00136 #include "regex_posix.h" 00137 #endif /* USE_REGEX */ 00138 00139 /* XXX missing type in vc++, hack around it here too, don't pollute 00140 global namespace too badly. */ 00141 typedef ios::fmtflags w_dbg_fmtflags; 00142 00143 00144 #ifdef W_TRACE 00145 00146 #define _strip_filename(f) f 00147 00148 #define DUMP()\ 00149 do { \ 00150 if(_w_debug.flag_on(__func__,__FILE__)) {\ 00151 _w_debug.clog << __LINE__ << " " << _strip_filename(__FILE__) << ": " << __func__\ 00152 << flushl; } } while(0) 00153 00154 #define FUNC(fn)\ 00155 DUMP() 00156 00157 #define RETURN \ 00158 do { \ 00159 if(_w_debug.flag_on(__func__,__FILE__)) {\ 00160 w_dbg_fmtflags old = _w_debug.clog.setf(ios::dec, ios::basefield); \ 00161 _w_debug.clog << __LINE__ << " " << _strip_filename(__FILE__) << ":" ; \ 00162 _w_debug.clog.setf(old, ios::basefield); \ 00163 _w_debug.clog << "return from " << __func__ << flushl; } } while(0); \ 00164 return 00165 00166 #else /* -UW_TRACE */ 00167 # define DUMP(str) 00168 # define FUNC(fn) 00169 # undef RETURN 00170 # define RETURN return 00171 #endif /* W_TRACE*/ 00172 00173 /* ************************************************************************ */ 00174 00175 /* ************************************************************************ 00176 * 00177 * Class w_debug, macros DBG, DBG_NONL, DBG1, DBG1_NONL: 00178 */ 00179 00180 00181 /**\brief An ErrLog used for tracing (configure --enable-trace) 00182 * 00183 * For tracing to be used, you must set the environment variable 00184 * DEBUG_FLAGS to a string containing the names of the files you 00185 * want traced, and 00186 * 00187 * DEBUG_FILE to the name of the output file to which the output 00188 * should be sent. If DEBUG_FILE is not set, the output goes to 00189 * stderr. 00190 */ 00191 class w_debug : public ErrLog { 00192 private: 00193 char *_flags; 00194 enum { _all = 0x1, _none = 0x2 }; 00195 unsigned int mask; 00196 int _trace_level; 00197 00198 #ifdef USE_REGEX 00199 static regex_t re_posix_re; 00200 static bool re_ready; 00201 static char* re_error_str; 00202 static char* re_comp_debug(const char* pattern); 00203 static int re_exec_debug(const char* string); 00204 #endif /* USE_REGEX */ 00205 00206 int all(void) { return (mask & _all) ? 1 : 0; } 00207 int none(void) { return (mask & _none) ? 1 : 0; } 00208 00209 public: 00210 w_debug(const char *n, const char *f); 00211 ~w_debug(); 00212 int flag_on(const char *fn, const char *file); 00213 const char *flags() { return _flags; } 00214 void setflags(const char *newflags); 00215 void memdump(void *p, int len); // hex dump of memory 00216 int trace_level() { return _trace_level; } 00217 }; 00218 extern w_debug _w_debug; 00219 00220 #if defined(W_TRACE) 00221 00222 # define DBG1(a) do {\ 00223 if(_w_debug.flag_on(__func__,__FILE__)) { \ 00224 w_dbg_fmtflags old = _w_debug.clog.setf(ios::dec, ios::basefield); \ 00225 _w_debug.clog << _strip_filename(__FILE__) << ":" << __LINE__ << ":" ; \ 00226 _w_debug.clog.setf(old, ios::basefield); \ 00227 _w_debug.clog a << flushl; \ 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>*/