]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #ifndef CEPH_ASSERT_H |
2 | #define CEPH_ASSERT_H | |
3 | ||
4 | #include <stdlib.h> | |
5 | ||
6 | #if defined(__linux__) | |
7 | #include <features.h> | |
8 | ||
9 | #ifndef __STRING | |
10 | # define __STRING(x) #x | |
11 | #endif | |
12 | ||
13 | #elif defined(__FreeBSD__) | |
14 | #include <sys/cdefs.h> | |
15 | #define __GNUC_PREREQ(minor, major) __GNUC_PREREQ__(minor, major) | |
16 | #elif defined(__sun) || defined(_AIX) | |
17 | #include "include/compat.h" | |
18 | #include <assert.h> | |
19 | #endif | |
20 | ||
21 | #ifdef __CEPH__ | |
22 | # include "acconfig.h" | |
23 | #endif | |
24 | ||
25 | class CephContext; | |
26 | ||
27 | #ifdef __cplusplus | |
28 | namespace ceph { | |
29 | ||
30 | struct BackTrace; | |
31 | #endif | |
32 | ||
33 | /* | |
34 | * For GNU, test specific version features. Otherwise (e.g. LLVM) we'll use | |
35 | * the defaults selected below. | |
36 | */ | |
37 | #ifdef __GNUC_PREREQ | |
38 | ||
39 | /* | |
40 | * Version 2.4 and later of GCC define a magical variable | |
41 | * `__PRETTY_FUNCTION__' which contains the name of the function currently | |
42 | * being defined. This is broken in G++ before version 2.6. C9x has a | |
43 | * similar variable called __func__, but prefer the GCC one since it demangles | |
44 | * C++ function names. We define __CEPH_NO_PRETTY_FUNC if we want to avoid | |
45 | * broken versions of G++. | |
46 | */ | |
47 | # if defined __cplusplus ? !__GNUC_PREREQ (2, 6) : !__GNUC_PREREQ (2, 4) | |
48 | # define __CEPH_NO_PRETTY_FUNC | |
49 | # endif | |
50 | ||
51 | #endif | |
52 | ||
53 | /* | |
54 | * Select a function-name variable based on compiler tests, and any compiler | |
55 | * specific overrides. | |
56 | */ | |
57 | #if defined(HAVE_PRETTY_FUNC) && !defined(__CEPH_NO_PRETTY_FUNC) | |
58 | # define __CEPH_ASSERT_FUNCTION __PRETTY_FUNCTION__ | |
59 | #elif defined(HAVE_FUNC) | |
60 | # define __CEPH_ASSERT_FUNCTION __func__ | |
61 | #else | |
62 | # define __CEPH_ASSERT_FUNCTION ((__const char *) 0) | |
63 | #endif | |
64 | ||
65 | extern void register_assert_context(CephContext *cct); | |
66 | extern void __ceph_assert_fail(const char *assertion, const char *file, int line, const char *function) | |
67 | __attribute__ ((__noreturn__)); | |
68 | extern void __ceph_assertf_fail(const char *assertion, const char *file, int line, const char *function, const char* msg, ...) | |
69 | __attribute__ ((__noreturn__)); | |
70 | extern void __ceph_assert_warn(const char *assertion, const char *file, int line, const char *function); | |
71 | ||
72 | ||
73 | #define assert_warn(expr) \ | |
74 | ((expr) \ | |
75 | ? static_cast<void> (0) \ | |
76 | : __ceph_assert_warn (__STRING(expr), __FILE__, __LINE__, __CEPH_ASSERT_FUNCTION)) | |
77 | ||
78 | #ifdef __cplusplus | |
79 | } | |
80 | ||
81 | using namespace ceph; | |
82 | ||
83 | #endif | |
84 | ||
85 | /* | |
86 | * ceph_abort aborts the program with a nice backtrace. | |
87 | * | |
88 | * Currently, it's the same as assert(0), but we may one day make assert a | |
89 | * debug-only thing, like it is in many projects. | |
90 | */ | |
91 | #define ceph_abort() abort() | |
92 | ||
93 | #define ceph_abort_msg(cct, msg) { \ | |
94 | lgeneric_derr(cct) << "abort: " << msg << dendl; \ | |
95 | abort(); \ | |
96 | } | |
97 | ||
98 | #endif | |
99 | ||
100 | // wipe any prior assert definition | |
101 | #ifdef assert | |
102 | # undef assert | |
103 | #endif | |
104 | ||
105 | // make _ASSERT_H something that *must* have a value other than what | |
106 | // /usr/include/assert.h gives it (nothing!), so that we detect when | |
107 | // our assert is clobbered. | |
108 | #undef _ASSERT_H | |
109 | #define _ASSERT_H _dout_cct | |
110 | ||
111 | // make __ASSERT_FUNCTION empty (/usr/include/assert.h makes it a function) | |
112 | // and make our encoding macros break if it non-empty. | |
113 | #undef __ASSERT_FUNCTION | |
114 | #define __ASSERT_FUNCTION | |
115 | ||
116 | #define assert(expr) \ | |
117 | ((expr) \ | |
118 | ? static_cast<void> (0) \ | |
119 | : __ceph_assert_fail (__STRING(expr), __FILE__, __LINE__, __CEPH_ASSERT_FUNCTION)) | |
120 | #define ceph_assert(expr) \ | |
121 | ((expr) \ | |
122 | ? static_cast<void> (0) \ | |
123 | : __ceph_assert_fail (__STRING(expr), __FILE__, __LINE__, __CEPH_ASSERT_FUNCTION)) | |
124 | ||
125 | // this variant will *never* get compiled out to NDEBUG in the future. | |
126 | // (ceph_assert currently doesn't either, but in the future it might.) | |
127 | #define ceph_assert_always(expr) \ | |
128 | ((expr) \ | |
129 | ? static_cast<void> (0) \ | |
130 | : __ceph_assert_fail (__STRING(expr), __FILE__, __LINE__, __CEPH_ASSERT_FUNCTION)) | |
131 | ||
132 | // Named by analogy with printf. Along with an expression, takes a format | |
133 | // string and parameters which are printed if the assertion fails. | |
134 | #define assertf(expr, ...) \ | |
135 | ((expr) \ | |
136 | ? static_cast<void> (0) \ | |
137 | : __ceph_assertf_fail (__STRING(expr), __FILE__, __LINE__, __CEPH_ASSERT_FUNCTION, __VA_ARGS__)) | |
138 | #define ceph_assertf(expr, ...) \ | |
139 | ((expr) \ | |
140 | ? static_cast<void> (0) \ | |
141 | : __ceph_assertf_fail (__STRING(expr), __FILE__, __LINE__, __CEPH_ASSERT_FUNCTION, __VA_ARGS__)) | |
142 | ||
143 | // this variant will *never* get compiled out to NDEBUG in the future. | |
144 | // (ceph_assertf currently doesn't either, but in the future it might.) | |
145 | #define ceph_assertf_always(expr, ...) \ | |
146 | ((expr) \ | |
147 | ? static_cast<void> (0) \ | |
148 | : __ceph_assertf_fail (__STRING(expr), __FILE__, __LINE__, __CEPH_ASSERT_FUNCTION, __VA_ARGS__)) |