1 /****************************************************************************
2 * Copyright (C) 2006-2008 by Jason Ansel *
3 * jansel@csail.mit.edu *
4 * *
5 * This file is part of the JALIB module of DMTCP (DMTCP:dmtcp/jalib). *
6 * *
7 * DMTCP:dmtcp/jalib is free software: you can redistribute it and/or *
8 * modify it under the terms of the GNU Lesser General Public License as *
9 * published by the Free Software Foundation, either version 3 of the *
10 * License, or (at your option) any later version. *
11 * *
12 * DMTCP:dmtcp/src is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU Lesser General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with DMTCP:dmtcp/src. If not, see *
19 * <http://www.gnu.org/licenses/>. *
20 ****************************************************************************/
21
22 #ifndef JASSERT_H
23 #define JASSERT_H
24
25
26 #include "stlwrapper.h"
27 #include <string>
28 #include <iostream>
29 #include <sstream>
30 #include <string.h>
31 #include <unistd.h>
32 #include <errno.h>
33 #include <execinfo.h> /* For backtrace() */
34 #define BT_SIZE 50 /* Maximum size backtrace of stack */
35
36 #ifdef HAVE_CONFIG_H
37 # include "config.h"
38 #endif
39 #include "jalloc.h"
40
41 extern int jassert_quiet;
42
43 /** USAGE EXAMPLE:
44 *
45 * int a=1,b=2,c=3,d=4;
46 *
47 * code:
48 * JASSERT(a==b)(a)(b)(c).Text("Error a!=b program will exit");
49 * outputs:
50 * ERROR at main.cpp:15 in main
51 * Reason: JASSERT(a=b) failed
52 * a = 1
53 * b = 2
54 * c = 3
55 * Message: Error a!=b program will exit
56 * Terminating...
57 *
58 *
59 * code:
60 * JWARNING(a==b)(a)(b)(d).Text("Warning a!=b program will continue");
61 * outputs:
62 * WARNING at main.cpp:15 in main
63 * Reason: JWARNING(a=b) failed
64 * a = 1
65 * b = 2
66 * d = 4
67 * Message: Warning a!=b program will continue
68 *
69 *
70 * code:
71 * JNOTE("Values of abcd (in the form 'a=1') will be printed below this text.")(a)(b)(c)(d);
72 * outputs:
73 * JNOTE at main.cpp:15 in main
74 * Reason: Values of abcd (in the form 'a=1') will be printed below this text.
75 * a = 1
76 * b = 2
77 * c = 3
78 * d = 4
79 *
80 *
81 * It has the ability to output any variable understood by std::ostream.
82 *
83 */
84
85 namespace jassert_internal
86 {
87
88 class JAssert
89 {
90 public:
91 #ifdef JALIB_ALLOCATOR
92 static void* operator new(size_t nbytes, void* p) { return p; }
93 static void* operator new(size_t nbytes) { JALLOC_HELPER_NEW(nbytes); }
94 static void operator delete(void* p) { JALLOC_HELPER_DELETE(p); }
95 #endif
96 ///
97 /// print a value of any type
98 template < typename T > JAssert& Print ( const T& t );
99 ///
100 /// print out a string in format "Message: msg"
101 JAssert& Text ( const char* msg );
102 ///
103 /// prints stack backtrace and always returns true
104 JAssert& jbacktrace ();
105 ///
106 /// constructor: sets members
107 JAssert ( bool exitWhenDone );
108 ///
109 /// destructor: exits program if exitWhenDone is set
110 ~JAssert();
111 ///
112 /// termination point for crazy macros
113 JAssert& JASSERT_CONT_A;
114 ///
115 /// termination point for crazy macros
116 JAssert& JASSERT_CONT_B;
117
118 template < typename T > JAssert& operator << ( const T& t )
119 { Print ( t ); return *this; }
120 private:
121 ///
122 /// if set true (on construction) call exit() on destruction
123 bool _exitWhenDone;
124 bool _logLockAcquired;
125 dmtcp::ostringstream ss;
126 };
127
128
129 const char* jassert_basename ( const char* str );
130 dmtcp::ostream& jassert_output_stream();
131 void jassert_safe_print ( const char* );
132 void jassert_init ( const jalib::string& f );
133 bool lockLog();
134 void unlockLog();
135
136 template < typename T >
137 inline JAssert& JAssert::Print ( const T& t )
138 {
139 #ifdef JASSERT_FAST
140 jassert_output_stream() << t;
141 #else
142 //dmtcp::ostringstream ss;
|
Event deref_parm_in_call: |
Function "std::basic_ostream<char, std::char_traits<char> > &std::operator << <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> > &, char const *)" dereferences parameter "t". |
143 ss << t;
144 //jassert_safe_print ( ss.str().c_str() );
145 #endif
146 return *this;
147 }
148
149 void set_log_file ( const jalib::string& path );
150 void reset_on_fork ( );
151
152 int jassert_console_fd();
153
154 }//jassert_internal
155
156 #define JASSERT_INIT(p) (jassert_internal::jassert_init(p));
157
158 #define JASSERT_SET_LOGFILE(p) (jassert_internal::set_log_file(p));
159 #define JASSERT_RESET_ON_FORK() (jassert_internal::reset_on_fork());
160
161 #define JASSERT_CKPT_LOCK() (jassert_internal::lockLog());
162 #define JASSERT_CKPT_UNLOCK() (jassert_internal::unlockLog());
163
164 #define JASSERT_ERRNO (strerror(errno))
165
166 #define JASSERT_PRINT(str) jassert_internal::JAssert(false).Print(str)
167 #define JASSERT_STDERR jassert_internal::JAssert(false)
168 #define JASSERT_STDERR_FD (jassert_internal::jassert_console_fd())
169
170 #define JASSERT_CONT(AB,term) Print(" " #term " = ").Print(term).Print("\n").JASSERT_CONT_##AB
171 #define JASSERT_CONT_A(term) JASSERT_CONT(B,term)
172 #define JASSERT_CONT_B(term) JASSERT_CONT(A,term)
173
174 #define JASSERT_STRINGIFY_(x) #x
175 #define JASSERT_STRINGIFY(x) JASSERT_STRINGIFY_(x)
176 #define JASSERT_FUNC __FUNCTION__
177 #define JASSERT_LINE JASSERT_STRINGIFY(__LINE__)
178 #define JASSERT_FILE jassert_internal::jassert_basename(__FILE__)
179 #define JASSERT_CONTEXT(type,reason) Print('[').Print(getpid()).Print("] " type " at ").Print(JASSERT_FILE).Print(":" JASSERT_LINE " in ").Print(JASSERT_FUNC).Print("; REASON='" reason "'\n")
180
181 #ifdef DEBUG
182 #define JTRACE(msg) jassert_internal::JAssert(false).JASSERT_CONTEXT("TRACE",msg).JASSERT_CONT_A
183 #else
184 #define JTRACE(msg) if(true){}else jassert_internal::JAssert(false).JASSERT_CONTEXT("NOTE",msg).JASSERT_CONT_A
185 #endif
186
187 #ifdef QUIET
188 #define JNOTE(msg) if(true){}else jassert_internal::JAssert(false).JASSERT_CONTEXT("NOTE",msg).JASSERT_CONT_A
189 #else
190 #define JNOTE(msg) if(jassert_quiet >= 1){}else \
191 jassert_internal::JAssert(false).JASSERT_CONTEXT("NOTE",msg).JASSERT_CONT_A
192 #endif
193
194 #ifdef QUIET
195 #define JWARNING(term) if(true){}else \
196 jassert_internal::JAssert(false).JASSERT_CONTEXT("WARNING","JWARNING(" #term ") failed").JASSERT_CONT_A
197 #else
198 #define JWARNING(term) if((term) || jassert_quiet >= 2){}else \
199 jassert_internal::JAssert(false).JASSERT_CONTEXT("WARNING","JWARNING(" #term ") failed").JASSERT_CONT_A
200 #endif
201
202 #ifndef DEBUG
203 # define JASSERT(term) if((term)){}else \
204 jassert_internal::JAssert(true) \
205 .JASSERT_CONTEXT("ERROR","JASSERT(" #term ") failed").JASSERT_CONT_A
206 #else
207 # define JASSERT(term) \
208 if ((term)) {} else \
209 jassert_internal::JAssert(true) \
210 .JASSERT_CONTEXT("ERROR","JASSERT(" #term ") failed").JASSERT_CONT_A
211 #endif
212
213 #define JALIB_CKPT_LOCK() do{\
214 JASSERT_CKPT_LOCK();\
215 JALLOC_HELPER_LOCK();\
216 } while(0)
217
218 #define JALIB_CKPT_UNLOCK() do{\
219 JALLOC_HELPER_UNLOCK();\
220 JASSERT_CKPT_UNLOCK();\
221 } while(0)
222
223 #define JALIB_RESET_ON_FORK() do{\
224 JASSERT_RESET_ON_FORK();\
225 JALLOC_HELPER_RESET_ON_FORK();\
226 } while(0)
227
228 #endif