GraphChi  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Macros
assertions.hpp
1 
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>
72 
73 #include "logger/logger.hpp"
74 #include <boost/typeof/typeof.hpp>
75 
76 static void __print_back_trace() {
77  logstream(LOG_ERROR) << "GraphChi does not currently have the _print_back_trace implementation!" << std::endl;
78 }
79 // On some systems (like freebsd), we can't call write() at all in a
80 // global constructor, perhaps because errno hasn't been set up.
81 // Calling the write syscall is safer (it doesn't set errno), so we
82 // prefer that. Note we don't care about errno for logging: we just
83 // do logging on a best-effort basis.
84 #define WRITE_TO_STDERR(buf, len) (logbuf(LOG_FATAL, buf, len))
85 
86 // CHECK dies with a fatal error if condition is not true. It is *not*
87 // controlled by NDEBUG, so the check will be executed regardless of
88 // compilation mode. Therefore, it is safe to do things like:
89 // CHECK(fp->Write(x) == 4)
90 #define CHECK(condition) \
91  do { \
92  if (__builtin_expect(!(condition), 0)) { \
93  logstream(LOG_ERROR) \
94  << "Check failed: " << #condition << std::endl; \
95  __print_back_trace(); \
96  throw("assertion failure"); \
97  } \
98  } while(0)
99 
100 
101 // This prints errno as well. errno is the posix defined last error
102 // number. See errno.h
103 #define PCHECK(condition) \
104  do { \
105  if (__builtin_expect(!(condition), 0)) { \
106  const int _PCHECK_err_no_ = errno; \
107  logstream(LOG_ERROR) \
108  << "Check failed: " << #condition << ": " \
109  << strerror(err_no) << std::endl; \
110  __print_back_trace(); \
111  throw("assertion failure"); \
112  } \
113  } while(0)
114 
115 // Helper macro for binary operators; prints the two values on error
116 // Don't use this macro directly in your code, use CHECK_EQ et al below
117 
118 // WARNING: These don't compile correctly if one of the arguments is a pointer
119 // and the other is NULL. To work around this, simply static_cast NULL to the
120 // type of the desired pointer.
121 #define CHECK_OP(op, val1, val2) \
122  do { \
123  const typeof(val1) _CHECK_OP_v1_ = val1; \
124  const typeof(val2) _CHECK_OP_v2_ = (typeof(val2))val2; \
125  if (__builtin_expect(!((_CHECK_OP_v1_) op \
126  (typeof(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 
139 #define CHECK_EQ(val1, val2) CHECK_OP(==, val1, val2)
140 #define CHECK_NE(val1, val2) CHECK_OP(!=, val1, val2)
141 #define CHECK_LE(val1, val2) CHECK_OP(<=, val1, val2)
142 #define CHECK_LT(val1, val2) CHECK_OP(< , val1, val2)
143 #define CHECK_GE(val1, val2) CHECK_OP(>=, val1, val2)
144 #define CHECK_GT(val1, val2) CHECK_OP(> , val1, val2)
145 
146 // Synonyms for CHECK_* that are used in some unittests.
147 #define EXPECT_EQ(val1, val2) CHECK_EQ(val1, val2)
148 #define EXPECT_NE(val1, val2) CHECK_NE(val1, val2)
149 #define EXPECT_LE(val1, val2) CHECK_LE(val1, val2)
150 #define EXPECT_LT(val1, val2) CHECK_LT(val1, val2)
151 #define EXPECT_GE(val1, val2) CHECK_GE(val1, val2)
152 #define EXPECT_GT(val1, val2) CHECK_GT(val1, val2)
153 #define ASSERT_EQ(val1, val2) EXPECT_EQ(val1, val2)
154 #define ASSERT_NE(val1, val2) EXPECT_NE(val1, val2)
155 #define ASSERT_LE(val1, val2) EXPECT_LE(val1, val2)
156 #define ASSERT_LT(val1, val2) EXPECT_LT(val1, val2)
157 #define ASSERT_GE(val1, val2) EXPECT_GE(val1, val2)
158 #define ASSERT_GT(val1, val2) EXPECT_GT(val1, val2)
159 // As are these variants.
160 #define EXPECT_TRUE(cond) CHECK(cond)
161 #define EXPECT_FALSE(cond) CHECK(!(cond))
162 #define EXPECT_STREQ(a, b) CHECK(strcmp(a, b) == 0)
163 #define ASSERT_TRUE(cond) EXPECT_TRUE(cond)
164 #define ASSERT_FALSE(cond) EXPECT_FALSE(cond)
165 #define ASSERT_STREQ(a, b) EXPECT_STREQ(a, b)
166 
167 
168 #define ASSERT_MSG(condition, fmt, ...) \
169  do { \
170  if (__builtin_expect(!(condition), 0)) { \
171  logstream(LOG_ERROR) \
172  << "Check failed: " << #condition << ":\n"; \
173  logger(LOG_ERROR, fmt, ##__VA_ARGS__); \
174  __print_back_trace(); \
175  throw("assertion failure"); \
176  } \
177  } while(0)
178 
179 // Used for (libc) functions that return -1 and set errno
180 #define CHECK_ERR(invocation) PCHECK((invocation) != -1)
181 
182 // A few more checks that only happen in debug mode
183 #ifdef NDEBUG
184 #define DCHECK_EQ(val1, val2)
185 #define DCHECK_NE(val1, val2)
186 #define DCHECK_LE(val1, val2)
187 #define DCHECK_LT(val1, val2)
188 #define DCHECK_GE(val1, val2)
189 #define DCHECK_GT(val1, val2)
190 #define DASSERT_TRUE(cond)
191 #define DASSERT_FALSE(cond)
192 #define DASSERT_MSG(condition, fmt, ...)
193 
194 #else
195 #define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
196 #define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
197 #define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
198 #define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
199 #define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
200 #define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
201 #define DASSERT_TRUE(cond) ASSERT_TRUE(cond)
202 #define DASSERT_FALSE(cond) ASSERT_FALSE(cond)
203 #define DASSERT_MSG(condition, fmt, ...) \
204  do { \
205  if (__builtin_expect(!(condition), 0)) { \
206  logstream(LOG_ERROR) \
207  << "Check failed: " << #condition << ":\n"; \
208  logger(LOG_ERROR, fmt, ##__VA_ARGS__); \
209  __print_back_trace(); \
210  throw("assertion failure"); \
211  } \
212  } while(0)
213 
214 #endif
215 
216 
217 #ifdef ERROR
218 #undef ERROR // may conflict with ERROR macro on windows
219 #endif
220 
221 #endif // _LOGGING_H_
222