00001 #ifndef CLASSLIB_DEBUG_H
00002 # define CLASSLIB_DEBUG_H
00003
00004
00005
00006 # include "classlib/utils/Macros.h"
00007 # include "classlib/sysapi/IOTypes.h"
00008 # include <cstddef>
00009
00010 namespace lat {
00011
00012
00013 # ifdef CLASSLIB_FUNCTION
00014
00015 # define ASSERT_FUNC CLASSLIB_FUNCTION
00016 # else
00017 # define ASSERT_FUNC 0
00018 # endif
00019
00020 # undef ASSERT_ALWAYS
00021 # undef ASSERT
00022 # undef VERIFY
00023 # undef ASSERT_VALID
00024
00083 # if !NDEBUG
00084 # define ASSERT_ALWAYS(f) \
00085 ((f)?(void)0: \
00086 lat::DebugAids::failed (__FILE__,__LINE__,ASSERT_FUNC,#f))
00087 # define ASSERT(f) \
00088 ((f)?(void)0: \
00089 lat::DebugAids::failed (__FILE__,__LINE__,ASSERT_FUNC,#f))
00090 # define VERIFY(f) \
00091 ((f)?(void)0: \
00092 lat::DebugAids::failed (__FILE__,__LINE__,ASSERT_FUNC,#f))
00093 # define ASSERT_VALID(p) \
00094 (lat::ASSERT_VALIDATOR((p),__FILE__,__LINE__,ASSERT_FUNC,#p))
00095
00096 # else // NDEBUG
00097 # define ASSERT_ALWAYS(f) \
00098 ((f)?(void)0: \
00099 lat::DebugAids::failed (__FILE__,__LINE__,ASSERT_FUNC,0))
00100 # define ASSERT(f) ((void)0)
00101 # define VERIFY(f) ((void)(f))
00102 # define ASSERT_VALID(p) ((void)0)
00103 # endif // !NDEBUG
00104
00105
00106
00107
00108 class logstream;
00109
00110
00111
00112
00115 class Debuggable
00116 {
00117 public:
00118 virtual ~Debuggable (void);
00119
00120 virtual void validate (void) const;
00121 virtual void log (logstream &to) const;
00122 };
00123
00125 class DebugAids
00126 {
00127 public:
00140 typedef char (*AssertHook) (const char *message);
00141
00142
00143 static bool validate (const char *str, int length = -1);
00144 static bool validate (const void *p,
00145 STDC::size_t bytes,
00146 bool rw);
00147
00148
00149 static void failed (const char *file, int line,
00150 const char *function,
00151 const char *expr);
00152 static int failIgnore (int count = -1);
00153 static AssertHook failHook (AssertHook hook = 0);
00154 static IOFD failStdxxFd (IOFD fd = IOFD_INVALID);
00155 static char failStdxx (const char *message);
00156 # ifdef _WIN32
00157 static char failMsgBox (const char *message);
00158 # endif
00159
00160
00161 static void breakpoint (void);
00162 static IOFD stacktraceFd (IOFD fd = IOFD_INVALID);
00163 static void stacktrace (IOFD fd = IOFD_INVALID);
00164 static void coredump (int sig, ...);
00165
00166
00167 private:
00168 static AssertHook s_assertHook;
00169 static int s_assertIgnoreCount;
00170 static IOFD s_assertOutputFd;
00171 static IOFD s_stackTraceFd;
00172 };
00173
00174
00175
00189 void AssertValid (const void *address);
00190 void AssertValid (const Debuggable *object);
00191
00195 logstream & operator<< (logstream &to, const Debuggable &object);
00196
00208 template <class T>
00209 inline void
00210 ASSERT_VALIDATOR (const T *object, const char *file, int line,
00211 const char *function, const char *expr)
00212 {
00213 if (object && DebugAids::validate (object, sizeof (*object), false))
00214 lat::AssertValid (object);
00215 else
00216 DebugAids::failed (file, line, function, expr);
00217 }
00218
00219
00220
00221
00222 }
00223 #endif // CLASSLIB_DEBUG_H