56
56
/*
57
57
* Common DEBUG functionality.
58
58
*/
59
+ #define __printflike (a , b ) __printf(a, b)
60
+
61
+ #ifndef __maybe_unused
62
+ #define __maybe_unused __attribute__((unused))
63
+ #endif
64
+
65
+ /*
66
+ * Without this, we see warnings from objtool during normal Linux builds when
67
+ * the kernel is built with CONFIG_STACK_VALIDATION=y:
68
+ *
69
+ * warning: objtool: tsd_create() falls through to next function __list_add()
70
+ * warning: objtool: .text: unexpected end of section
71
+ *
72
+ * Until the toolchain stops doing this, we must only define this attribute on
73
+ * spl_panic() when doing static analysis.
74
+ */
59
75
#if defined(__COVERITY__ ) || defined(__clang_analyzer__ )
60
76
__attribute__((__noreturn__ ))
61
77
#endif
62
78
extern void spl_panic (const char * file , const char * func , int line ,
63
- const char * fmt , ...) __attribute__(( __noreturn__ )) ;
79
+ const char * fmt , ...);
64
80
extern void spl_dumpstack (void );
65
81
66
82
static inline int
@@ -73,8 +89,10 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
73
89
#ifndef expect
74
90
#define expect (expr , value ) (__builtin_expect((expr), (value)))
75
91
#endif
92
+ #ifndef __linux__
76
93
#define likely (expr ) expect((expr) != 0, 1)
77
94
#define unlikely (expr ) expect((expr) != 0, 0)
95
+ #endif
78
96
79
97
#define PANIC (fmt , a ...) \
80
98
spl_panic(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
@@ -84,6 +102,11 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
84
102
spl_assert("VERIFY(" #cond ") failed\n", \
85
103
__FILE__, __FUNCTION__, __LINE__))
86
104
105
+ #define VERIFYF (cond , str , ...) \
106
+ (void) (unlikely(!(cond)) && \
107
+ spl_panic(__FILE__, __FUNCTION__, __LINE__, \
108
+ "VERIFY(" #cond ") failed " str "\n", __VA_ARGS__))
109
+
87
110
#define VERIFY3B (LEFT , OP , RIGHT ) do { \
88
111
const boolean_t _verify3_left = (boolean_t)(LEFT); \
89
112
const boolean_t _verify3_right = (boolean_t)(RIGHT); \
@@ -123,7 +146,7 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
123
146
if (unlikely(!(_verify3_left OP _verify3_right))) \
124
147
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
125
148
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
126
- "failed (%p " #OP " %p )\n", \
149
+ "failed (%px " #OP " %px )\n", \
127
150
(void *)_verify3_left, \
128
151
(void *)_verify3_right); \
129
152
} while (0)
@@ -142,10 +165,98 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
142
165
if (unlikely(!(0 == _verify0_right))) \
143
166
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
144
167
"VERIFY0P(" #RIGHT ") " \
145
- "failed (NULL == %p )\n", \
168
+ "failed (NULL == %px )\n", \
146
169
(void *)_verify0_right); \
147
170
} while (0)
148
171
172
+ /*
173
+ * Note that you should not put any operations you want to always happen
174
+ * in the print section for ASSERTs unless you only want them to run on
175
+ * debug builds!
176
+ * e.g. ASSERT3UF(2, <, 3, "%s", foo(x)), foo(x) won't run on non-debug
177
+ * builds.
178
+ */
179
+
180
+ #define VERIFY3BF (LEFT , OP , RIGHT , STR , ...) do { \
181
+ const boolean_t _verify3_left = (boolean_t)(LEFT); \
182
+ const boolean_t _verify3_right = (boolean_t)(RIGHT); \
183
+ if (unlikely(!(_verify3_left OP _verify3_right))) \
184
+ spl_panic(__FILE__, __FUNCTION__, __LINE__, \
185
+ "VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
186
+ "failed (%d " #OP " %d) " STR "\n", \
187
+ (boolean_t)(_verify3_left), \
188
+ (boolean_t)(_verify3_right), \
189
+ __VA_ARGS__); \
190
+ } while (0)
191
+
192
+ #define VERIFY3SF (LEFT , OP , RIGHT , STR , ...) do { \
193
+ const int64_t _verify3_left = (int64_t)(LEFT); \
194
+ const int64_t _verify3_right = (int64_t)(RIGHT); \
195
+ if (unlikely(!(_verify3_left OP _verify3_right))) \
196
+ spl_panic(__FILE__, __FUNCTION__, __LINE__, \
197
+ "VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
198
+ "failed (%lld " #OP " %lld) " STR "\n", \
199
+ (long long)(_verify3_left), \
200
+ (long long)(_verify3_right), \
201
+ __VA_ARGS); \
202
+ } while (0)
203
+
204
+ #define VERIFY3UF (LEFT , OP , RIGHT , STR , ...) do { \
205
+ const uint64_t _verify3_left = (uint64_t)(LEFT); \
206
+ const uint64_t _verify3_right = (uint64_t)(RIGHT); \
207
+ if (unlikely(!(_verify3_left OP _verify3_right))) \
208
+ spl_panic(__FILE__, __FUNCTION__, __LINE__, \
209
+ "VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
210
+ "failed (%llu " #OP " %llu) " STR "\n", \
211
+ (unsigned long long)(_verify3_left), \
212
+ (unsigned long long)(_verify3_right), \
213
+ __VA_ARGS); \
214
+ } while (0)
215
+
216
+ #define VERIFY3PF (LEFT , OP , RIGHT , STR , ...) do { \
217
+ const uintptr_t _verify3_left = (uintptr_t)(LEFT); \
218
+ const uintptr_t _verify3_right = (uintptr_t)(RIGHT); \
219
+ if (unlikely(!(_verify3_left OP _verify3_right))) \
220
+ spl_panic(__FILE__, __FUNCTION__, __LINE__, \
221
+ "VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
222
+ "failed (%px " #OP " %px) " STR "\n", \
223
+ (void *) (_verify3_left), \
224
+ (void *) (_verify3_right), \
225
+ __VA_ARGS__); \
226
+ } while (0)
227
+
228
+ #define VERIFY0PF (RIGHT , STR , ...) do { \
229
+ const uintptr_t _verify3_left = (uintptr_t)(0); \
230
+ const uintptr_t _verify3_right = (uintptr_t)(RIGHT); \
231
+ if (unlikely(!(_verify3_left == _verify3_right))) \
232
+ spl_panic(__FILE__, __FUNCTION__, __LINE__, \
233
+ "VERIFY0(0 == " #RIGHT ") " \
234
+ "failed (0 == %px) " STR "\n", \
235
+ (long long) (_verify3_right), \
236
+ __VA_ARGS__); \
237
+ } while (0)
238
+
239
+ #define VERIFY0F (RIGHT , STR , ...) do { \
240
+ const int64_t _verify3_left = (int64_t)(0); \
241
+ const int64_t _verify3_right = (int64_t)(RIGHT); \
242
+ if (unlikely(!(_verify3_left == _verify3_right))) \
243
+ spl_panic(__FILE__, __FUNCTION__, __LINE__, \
244
+ "VERIFY0(0 == " #RIGHT ") " \
245
+ "failed (0 == %lld) " STR "\n", \
246
+ (long long) (_verify3_right), \
247
+ __VA_ARGS__); \
248
+ } while (0)
249
+
250
+ #define VERIFY_IMPLY (A , B ) \
251
+ ((void)(likely((!(A)) || (B)) || \
252
+ spl_assert("(" #A ") implies (" #B ")", \
253
+ __FILE__, __FUNCTION__, __LINE__)))
254
+
255
+ #define VERIFY_EQUIV (A , B ) \
256
+ ((void)(likely(!!(A) == !!(B)) || \
257
+ spl_assert("(" #A ") is equivalent to (" #B ")", \
258
+ __FILE__, __FUNCTION__, __LINE__)))
259
+
149
260
/*
150
261
* Debugging disabled (--disable-debug)
151
262
*/
@@ -162,6 +273,13 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
162
273
((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))
163
274
#define ASSERT0 (x ) ((void) sizeof ((uintptr_t)(x)))
164
275
#define ASSERT0P (x ) ((void) sizeof ((uintptr_t)(x)))
276
+ #define ASSERT3BF (x , y , z , str , ...) ASSERT3B(x,y,z)
277
+ #define ASSERT3SF (x , y , z , str , ...) ASSERT3S(x,y,z)
278
+ #define ASSERT3UF (x , y , z , str , ...) ASSERT3U(x,y,z)
279
+ #define ASSERT3PF (x , y , z , str , ...) ASSERT3P(x,y,z)
280
+ #define ASSERT0PF (x , str , ...) ASSERT0P(x)
281
+ #define ASSERT0F (x , str , ...) ASSERT0(x)
282
+ #define ASSERTF (x , str , ...) ASSERT(x)
165
283
#define IMPLY (A , B ) \
166
284
((void) sizeof ((uintptr_t)(A)), (void) sizeof ((uintptr_t)(B)))
167
285
#define EQUIV (A , B ) \
@@ -178,16 +296,16 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
178
296
#define ASSERT3P VERIFY3P
179
297
#define ASSERT0 VERIFY0
180
298
#define ASSERT0P VERIFY0P
299
+ #define ASSERT3BF VERIFY3BF
300
+ #define ASSERT3SF VERIFY3SF
301
+ #define ASSERT3UF VERIFY3UF
302
+ #define ASSERT3PF VERIFY3PF
303
+ #define ASSERT0PF VERIFY0PF
304
+ #define ASSERT0F VERIFY0F
305
+ #define ASSERTF VERIFYF
181
306
#define ASSERT VERIFY
182
- #define IMPLY (A , B ) \
183
- ((void)(likely((!(A)) || (B)) || \
184
- spl_assert("(" #A ") implies (" #B ")", \
185
- __FILE__, __FUNCTION__, __LINE__)))
186
- #define EQUIV (A , B ) \
187
- ((void)(likely(!!(A) == !!(B)) || \
188
- spl_assert("(" #A ") is equivalent to (" #B ")", \
189
- __FILE__, __FUNCTION__, __LINE__)))
190
-
307
+ #define IMPLY VERIFY_IMPLY
308
+ #define EQUIV VERIFY_EQUIV
191
309
192
310
#endif /* NDEBUG */
193
311
0 commit comments