1 | /* |
2 | Copyright (c) 2012, Broadcom Europe Ltd |
3 | All rights reserved. |
4 | |
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the following conditions are met: |
7 | * Redistributions of source code must retain the above copyright |
8 | notice, this list of conditions and the following disclaimer. |
9 | * Redistributions in binary form must reproduce the above copyright |
10 | notice, this list of conditions and the following disclaimer in the |
11 | documentation and/or other materials provided with the distribution. |
12 | * Neither the name of the copyright holder nor the |
13 | names of its contributors may be used to endorse or promote products |
14 | derived from this software without specific prior written permission. |
15 | |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | /*============================================================================= |
29 | VideoCore OS Abstraction Layer - Assertion and error-handling macros. |
30 | =============================================================================*/ |
31 | |
32 | |
33 | #ifndef VCOS_ASSERT_H |
34 | #define VCOS_ASSERT_H |
35 | |
36 | /* |
37 | * Macro: |
38 | * vcos_assert(cond) |
39 | * vcos_assert_msg(cond, fmt, ...) |
40 | * Use: |
41 | * Detecting programming errors by ensuring that assumptions are correct. |
42 | * On failure: |
43 | * Performs a platform-dependent "breakpoint", usually with an assert-style |
44 | * message. The '_msg' variant expects a printf-style format string and |
45 | * parameters. |
46 | * If a failure is detected, the code should be fixed and rebuilt. |
47 | * In release builds: |
48 | * Generates no code, i.e. does not evaluate 'cond'. |
49 | * Returns: |
50 | * Nothing. |
51 | * |
52 | * Macro: |
53 | * vcos_demand(cond) |
54 | * vcos_demand_msg(cond, fmt, ...) |
55 | * Use: |
56 | * Detecting fatal system errors that require a reboot. |
57 | * On failure: |
58 | * Performs a platform-dependent "breakpoint", usually with an assert-style |
59 | * message, then calls vcos_abort (see below). |
60 | * In release builds: |
61 | * Calls vcos_abort() if 'cond' is false. |
62 | * Returns: |
63 | * Nothing (never, on failure). |
64 | * |
65 | * Macro: |
66 | * vcos_verify(cond) |
67 | * vcos_verify_msg(cond, fmt, ...) |
68 | * Use: |
69 | * Detecting run-time errors and interesting conditions, normally within an |
70 | * 'if' statement to catch the failures, i.e. |
71 | * if (!vcos_verify(cond)) handle_error(); |
72 | * On failure: |
73 | * Generates a message and optionally stops at a platform-dependent |
74 | * "breakpoint" (usually disabled). See vcos_verify_bkpts_enable below. |
75 | * In release builds: |
76 | * Just evaluates and returns 'cond'. |
77 | * Returns: |
78 | * Non-zero if 'cond' is true, otherwise zero. |
79 | * |
80 | * Macro: |
81 | * vcos_static_assert(cond) |
82 | * Use: |
83 | * Detecting compile-time errors. |
84 | * On failure: |
85 | * Generates a compiler error. |
86 | * In release builds: |
87 | * Generates a compiler error. |
88 | * |
89 | * Function: |
90 | * void vcos_abort(void) |
91 | * Use: |
92 | * Invokes the fatal error handling mechanism, alerting the host where |
93 | * applicable. |
94 | * Returns: |
95 | * Never. |
96 | * |
97 | * Macro: |
98 | * VCOS_VERIFY_BKPTS |
99 | * Use: |
100 | * Define in a module (before including vcos.h) to specify an alternative |
101 | * flag to control breakpoints on vcos_verify() failures. |
102 | * Returns: |
103 | * Non-zero values enable breakpoints. |
104 | * |
105 | * Function: |
106 | * int vcos_verify_bkpts_enable(int enable); |
107 | * Use: |
108 | * Sets the global flag controlling breakpoints on vcos_verify failures, |
109 | * enabling the breakpoints iff 'enable' is non-zero. |
110 | * Returns: |
111 | * The previous state of the flag. |
112 | * |
113 | * Function: |
114 | * int vcos_verify_bkpts_enabled(void); |
115 | * Use: |
116 | * Queries the state of the global flag enabling breakpoints on vcos_verify |
117 | * failures. |
118 | * Returns: |
119 | * The current state of the flag. |
120 | * |
121 | * Examples: |
122 | * |
123 | * int my_breakpoint_enable_flag = 1; |
124 | * |
125 | * #define VCOS_VERIFY_BKPTS my_breakpoint_enable_flag |
126 | * |
127 | * #include "interface/vcos/vcos.h" |
128 | * |
129 | * vcos_static_assert((sizeof(object) % 32) == 0); |
130 | * |
131 | * // ... |
132 | * |
133 | * vcos_assert_msg(postcondition_is_true, "Coding error"); |
134 | * |
135 | * if (!vcos_verify_msg(buf, "Buffer allocation failed (%d bytes)", size)) |
136 | * { |
137 | * // Tidy up |
138 | * // ... |
139 | * return OUT_OF_MEMORY; |
140 | * } |
141 | * |
142 | * vcos_demand(*p++==GUARDWORDHEAP); |
143 | */ |
144 | |
145 | #ifdef __cplusplus |
146 | extern "C" { |
147 | #endif |
148 | |
149 | #include "interface/vcos/vcos_types.h" |
150 | |
151 | #ifdef __COVERITY__ |
152 | #include "interface/vcos/user_nodefs.h" |
153 | |
154 | extern void __coverity_panic__(void); |
155 | #undef VCOS_ASSERT_BKPT |
156 | #define VCOS_ASSERT_BKPT __coverity_panic__() |
157 | #endif |
158 | |
159 | /* |
160 | * ANDROID should NOT be defined for files built for Videocore, but currently it |
161 | * is. FIXME When that's fixed, remove the __VIDEOCORE__ band-aid. |
162 | */ |
163 | #if (defined(ANDROID) && !defined(__VIDEOCORE__)) |
164 | # include "assert.h" |
165 | # define vcos_assert assert |
166 | #endif |
167 | |
168 | #ifndef VCOS_VERIFY_BKPTS |
169 | #define VCOS_VERIFY_BKPTS vcos_verify_bkpts_enabled() |
170 | #endif |
171 | |
172 | #ifndef VCOS_BKPT |
173 | #if defined(__VIDEOCORE__) && !defined(VCOS_ASSERT_NO_BKPTS) |
174 | #define VCOS_BKPT _bkpt() |
175 | #else |
176 | #define VCOS_BKPT (void )0 |
177 | #endif |
178 | #endif |
179 | |
180 | #ifndef VCOS_ASSERT_BKPT |
181 | #define VCOS_ASSERT_BKPT VCOS_BKPT |
182 | #endif |
183 | |
184 | #ifndef VCOS_VERIFY_BKPT |
185 | #define VCOS_VERIFY_BKPT (VCOS_VERIFY_BKPTS ? VCOS_BKPT : (void)0) |
186 | #endif |
187 | |
188 | VCOSPRE_ int VCOSPOST_ vcos_verify_bkpts_enabled(void); |
189 | VCOSPRE_ int VCOSPOST_ vcos_verify_bkpts_enable(int enable); |
190 | VCOSPRE_ void VCOSPOST_ vcos_abort(void); |
191 | |
192 | #ifndef VCOS_ASSERT_MSG |
193 | #ifdef LOGGING |
194 | extern void logging_assert(const char *file, const char *func, int line, const char *format, ...); |
195 | extern void logging_assert_dump(void); |
196 | #define VCOS_ASSERT_MSG(...) ((VCOS_ASSERT_LOGGING && !VCOS_ASSERT_LOGGING_DISABLE) ? logging_assert_dump(), logging_assert(__FILE__, __func__, __LINE__, __VA_ARGS__) : (void)0) |
197 | #else |
198 | #define VCOS_ASSERT_MSG(...) ((void)0) |
199 | #endif |
200 | #endif |
201 | |
202 | #ifndef VCOS_VERIFY_MSG |
203 | #define VCOS_VERIFY_MSG(...) VCOS_ASSERT_MSG(__VA_ARGS__) |
204 | #endif |
205 | |
206 | #ifndef VCOS_ASSERT_LOGGING |
207 | #define VCOS_ASSERT_LOGGING 0 |
208 | #endif |
209 | |
210 | #ifndef VCOS_ASSERT_LOGGING_DISABLE |
211 | #define VCOS_ASSERT_LOGGING_DISABLE 0 |
212 | #endif |
213 | |
214 | #if !defined(NDEBUG) || defined(VCOS_RELEASE_ASSERTS) |
215 | #define VCOS_ASSERT_ENABLED 1 |
216 | #define VCOS_VERIFY_ENABLED 1 |
217 | #else |
218 | #define VCOS_ASSERT_ENABLED 0 |
219 | #define VCOS_VERIFY_ENABLED 0 |
220 | #endif |
221 | |
222 | #define VCOS_DEMAND_ENABLED 1 |
223 | |
224 | #if VCOS_ASSERT_ENABLED |
225 | |
226 | #ifndef vcos_assert |
227 | #define vcos_assert(cond) \ |
228 | ( (cond) ? (void)0 : (VCOS_ASSERT_BKPT, VCOS_ASSERT_MSG("%s", #cond)) ) |
229 | #endif |
230 | |
231 | #ifndef vcos_assert_msg |
232 | #define vcos_assert_msg(cond, ...) \ |
233 | ( (cond) ? (void)0 : (VCOS_ASSERT_BKPT, VCOS_ASSERT_MSG(__VA_ARGS__)) ) |
234 | #endif |
235 | |
236 | #else /* VCOS_ASSERT_ENABLED */ |
237 | |
238 | #ifndef vcos_assert |
239 | #define vcos_assert(cond) (void)0 |
240 | #endif |
241 | |
242 | #ifndef vcos_assert_msg |
243 | #define vcos_assert_msg(cond, ...) (void)0 |
244 | #endif |
245 | |
246 | #endif /* VCOS_ASSERT_ENABLED */ |
247 | |
248 | |
249 | #if VCOS_DEMAND_ENABLED |
250 | |
251 | #ifndef vcos_demand |
252 | #define vcos_demand(cond) \ |
253 | ( (cond) ? (void)0 : (VCOS_ASSERT_BKPT, VCOS_ASSERT_MSG("%s", #cond), vcos_abort()) ) |
254 | #endif |
255 | |
256 | #ifndef vcos_demand_msg |
257 | #define vcos_demand_msg(cond, ...) \ |
258 | ( (cond) ? (void)0 : (VCOS_ASSERT_BKPT, VCOS_ASSERT_MSG(__VA_ARGS__), vcos_abort()) ) |
259 | #endif |
260 | |
261 | #else /* VCOS_DEMAND_ENABLED */ |
262 | |
263 | #ifndef vcos_demand |
264 | #define vcos_demand(cond) \ |
265 | ( (cond) ? (void)0 : vcos_abort() ) |
266 | #endif |
267 | |
268 | #ifndef vcos_demand_msg |
269 | #define vcos_demand_msg(cond, ...) \ |
270 | ( (cond) ? (void)0 : vcos_abort() ) |
271 | #endif |
272 | |
273 | #endif /* VCOS_DEMAND_ENABLED */ |
274 | |
275 | |
276 | #if VCOS_VERIFY_ENABLED |
277 | |
278 | #ifndef vcos_verify |
279 | #define vcos_verify(cond) \ |
280 | ( (cond) ? 1 : (VCOS_VERIFY_MSG("%s", #cond), VCOS_VERIFY_BKPT, 0) ) |
281 | #endif |
282 | |
283 | #ifndef vcos_verify_msg |
284 | #define vcos_verify_msg(cond, ...) \ |
285 | ( (cond) ? 1 : (VCOS_VERIFY_MSG(__VA_ARGS__), VCOS_VERIFY_BKPT, 0) ) |
286 | #endif |
287 | |
288 | #else /* VCOS_VERIFY_ENABLED */ |
289 | |
290 | #ifndef vcos_verify |
291 | #define vcos_verify(cond) (cond) |
292 | #endif |
293 | |
294 | #ifndef vcos_verify_msg |
295 | #define vcos_verify_msg(cond, ...) (cond) |
296 | #endif |
297 | |
298 | #endif /* VCOS_VERIFY_ENABLED */ |
299 | |
300 | |
301 | #ifndef vcos_static_assert |
302 | #if defined(__GNUC__) |
303 | #define vcos_static_assert(cond) __attribute__((unused)) extern int vcos_static_assert[(cond)?1:-1] |
304 | #else |
305 | #define vcos_static_assert(cond) extern int vcos_static_assert[(cond)?1:-1] |
306 | #endif |
307 | #endif |
308 | |
309 | #ifndef vc_assert |
310 | #define vc_assert(cond) vcos_assert(cond) |
311 | #endif |
312 | |
313 | #define vcos_unreachable() vcos_assert(0) |
314 | #define vcos_not_impl() vcos_assert(0) |
315 | |
316 | /** Print out a backtrace, on supported platforms. |
317 | */ |
318 | extern void vcos_backtrace_self(void); |
319 | |
320 | #ifdef __cplusplus |
321 | } |
322 | #endif |
323 | |
324 | #endif /* VCOS_ASSERT_H */ |
325 | |