GraphLab: Distributed Graph-Parallel API  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
assertions.hpp
1 /**
2  * Copyright (c) 2009 Carnegie Mellon University.
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an "AS
13  * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14  * express or implied. See the License for the specific language
15  * governing permissions and limitations under the License.
16  *
17  * For more about this software visit:
18  *
19  * http://www.graphlab.ml.cmu.edu
20  *
21  */
22 
23 
24 // Copyright (c) 2005, Google Inc.
25 // All rights reserved.
26 //
27 // Redistribution and use in source and binary forms, with or without
28 // modification, are permitted provided that the following conditions are
29 // met:
30 //
31 // * Redistributions of source code must retain the above copyright
32 // notice, this list of conditions and the following disclaimer.
33 // * Redistributions in binary form must reproduce the above
34 // copyright notice, this list of conditions and the following disclaimer
35 // in the documentation and/or other materials provided with the
36 // distribution.
37 // * Neither the name of Google Inc. nor the names of its
38 // contributors may be used to endorse or promote products derived from
39 // this software without specific prior written permission.
40 //
41 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
42 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
43 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
44 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
45 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
51 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 
53 // ---
54 // This file contains #include information about logging-related stuff.
55 // Pretty much everybody needs to #include this file so that they can
56 // log various happenings.
57 //
58 #ifndef _ASSERTIONS_H_
59 #define _ASSERTIONS_H_
60 
61 #include <stdarg.h>
62 #include <stdlib.h>
63 #include <stdio.h>
64 #ifdef HAVE_UNISTD_H
65 #include <unistd.h> // for write()
66 #endif
67 #include <string.h> // for strlen(), strcmp()
68 #include <assert.h>
69 #include <errno.h> // for errno
70 #include <sstream>
71 #include <cassert>
73 
74 #include <boost/typeof/typeof.hpp>
75 
76 extern void __print_back_trace();
77 
78 // On some systems (like freebsd), we can't call write() at all in a
79 // global constructor, perhaps because errno hasn't been set up.
80 // Calling the write syscall is safer (it doesn't set errno), so we
81 // prefer that. Note we don't care about errno for logging: we just
82 // do logging on a best-effort basis.
83 #define WRITE_TO_STDERR(buf, len) (logbuf(LOG_FATAL, buf, len))
84 
85 // CHECK dies with a fatal error if condition is not true. It is *not*
86 // controlled by NDEBUG, so the check will be executed regardless of
87 // compilation mode. Therefore, it is safe to do things like:
88 // CHECK(fp->Write(x) == 4)
89 #define CHECK(condition) \
90  do { \
91  if (__builtin_expect(!(condition), 0)) { \
92  logstream(LOG_ERROR) \
93  << "Check failed: " << #condition << std::endl; \
94  __print_back_trace(); \
95  throw("assertion failure"); \
96  } \
97  } while(0)
98 
99 
100 // This prints errno as well. errno is the posix defined last error
101 // number. See errno.h
102 #define PCHECK(condition) \
103  do { \
104  if (__builtin_expect(!(condition), 0)) { \
105  const int _PCHECK_err_no_ = errno; \
106  logstream(LOG_ERROR) \
107  << "Check failed: " << #condition << ": " \
108  << strerror(err_no) << std::endl; \
109  __print_back_trace(); \
110  throw("assertion failure"); \
111  } \
112  } while(0)
113 
114 // Helper macro for binary operators; prints the two values on error
115 // Don't use this macro directly in your code, use CHECK_EQ et al below
116 
117 // WARNING: These don't compile correctly if one of the arguments is a pointer
118 // and the other is NULL. To work around this, simply static_cast NULL to the
119 // type of the desired pointer.
120 #if defined(__cplusplus) && __cplusplus >= 201103L
121 #define CHECK_OP(op, val1, val2) \
122  do { \
123  const auto _CHECK_OP_v1_ = val1; \
124  const auto _CHECK_OP_v2_ = val2; \
125  if (__builtin_expect(!((_CHECK_OP_v1_) op \
126  (decltype(val1))(_CHECK_OP_v2_)), 0)) { \
127  logstream(LOG_ERROR) \
128  << "Check failed: " \
129  << #val1 << #op << #val2 \
130  << " [" \
131  << _CHECK_OP_v1_ \
132  << ' ' << #op << ' ' \
133  << _CHECK_OP_v2_ << "]" << std::endl; \
134  __print_back_trace(); \
135  throw("assertion failure"); \
136  } \
137  } while(0)
138 #else
139 #define CHECK_OP(op, val1, val2) \
140  do { \
141  const typeof(val1) _CHECK_OP_v1_ = (typeof(val1))val1; \
142  const typeof(val2) _CHECK_OP_v2_ = (typeof(val2))val2; \
143  if (__builtin_expect(!((_CHECK_OP_v1_) op \
144  (typeof(val1))(_CHECK_OP_v2_)), 0)) { \
145  logstream(LOG_ERROR) \
146  << "Check failed: " \
147  << #val1 << #op << #val2 \
148  << " [" \
149  << _CHECK_OP_v1_ \
150  << ' ' << #op << ' ' \
151  << _CHECK_OP_v2_ << "]" << std::endl; \
152  __print_back_trace(); \
153  throw("assertion failure"); \
154  } \
155  } while(0)
156 #endif
157 
158 #define CHECK_EQ(val1, val2) CHECK_OP(==, val1, val2)
159 #define CHECK_NE(val1, val2) CHECK_OP(!=, val1, val2)
160 #define CHECK_LE(val1, val2) CHECK_OP(<=, val1, val2)
161 #define CHECK_LT(val1, val2) CHECK_OP(< , val1, val2)
162 #define CHECK_GE(val1, val2) CHECK_OP(>=, val1, val2)
163 #define CHECK_GT(val1, val2) CHECK_OP(> , val1, val2)
164 
165 // Synonyms for CHECK_* that are used in some unittests.
166 #define EXPECT_EQ(val1, val2) CHECK_EQ(val1, val2)
167 #define EXPECT_NE(val1, val2) CHECK_NE(val1, val2)
168 #define EXPECT_LE(val1, val2) CHECK_LE(val1, val2)
169 #define EXPECT_LT(val1, val2) CHECK_LT(val1, val2)
170 #define EXPECT_GE(val1, val2) CHECK_GE(val1, val2)
171 #define EXPECT_GT(val1, val2) CHECK_GT(val1, val2)
172 #define ASSERT_EQ(val1, val2) EXPECT_EQ(val1, val2)
173 #define ASSERT_NE(val1, val2) EXPECT_NE(val1, val2)
174 #define ASSERT_LE(val1, val2) EXPECT_LE(val1, val2)
175 #define ASSERT_LT(val1, val2) EXPECT_LT(val1, val2)
176 #define ASSERT_GE(val1, val2) EXPECT_GE(val1, val2)
177 #define ASSERT_GT(val1, val2) EXPECT_GT(val1, val2)
178 // As are these variants.
179 #define EXPECT_TRUE(cond) CHECK(cond)
180 #define EXPECT_FALSE(cond) CHECK(!(cond))
181 #define EXPECT_STREQ(a, b) CHECK(strcmp(a, b) == 0)
182 #define ASSERT_TRUE(cond) EXPECT_TRUE(cond)
183 #define ASSERT_FALSE(cond) EXPECT_FALSE(cond)
184 #define ASSERT_STREQ(a, b) EXPECT_STREQ(a, b)
185 
186 
187 #define ASSERT_MSG(condition, fmt, ...) \
188  do { \
189  if (__builtin_expect(!(condition), 0)) { \
190  logstream(LOG_ERROR) \
191  << "Check failed: " << #condition << ":\n"; \
192  logger(LOG_ERROR, fmt, ##__VA_ARGS__); \
193  __print_back_trace(); \
194  throw("assertion failure"); \
195  } \
196  } while(0)
197 
198 // Used for (libc) functions that return -1 and set errno
199 #define CHECK_ERR(invocation) PCHECK((invocation) != -1)
200 
201 // A few more checks that only happen in debug mode
202 #ifdef NDEBUG
203 #define DCHECK_EQ(val1, val2)
204 #define DCHECK_NE(val1, val2)
205 #define DCHECK_LE(val1, val2)
206 #define DCHECK_LT(val1, val2)
207 #define DCHECK_GE(val1, val2)
208 #define DCHECK_GT(val1, val2)
209 #define DASSERT_TRUE(cond)
210 #define DASSERT_FALSE(cond)
211 #define DASSERT_MSG(condition, fmt, ...)
212 
213 #else
214 #define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
215 #define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
216 #define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
217 #define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
218 #define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
219 #define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
220 #define DASSERT_TRUE(cond) ASSERT_TRUE(cond)
221 #define DASSERT_FALSE(cond) ASSERT_FALSE(cond)
222 #define DASSERT_MSG(condition, fmt, ...) \
223  do { \
224  if (__builtin_expect(!(condition), 0)) { \
225  logstream(LOG_ERROR) \
226  << "Check failed: " << #condition << ":\n"; \
227  logger(LOG_ERROR, fmt, ##__VA_ARGS__); \
228  __print_back_trace(); \
229  throw("assertion failure"); \
230  } \
231  } while(0)
232 
233 #endif
234 
235 
236 #ifdef ERROR
237 #undef ERROR // may conflict with ERROR macro on windows
238 #endif
239 
240 #endif // _LOGGING_H_
241