1/*
2Copyright (c) 2012, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, 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
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON 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
25SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28/*=============================================================================
29VideoCore 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
146extern "C" {
147#endif
148
149#include "interface/vcos/vcos_types.h"
150
151#ifdef __COVERITY__
152#include "interface/vcos/user_nodefs.h"
153
154extern 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
188VCOSPRE_ int VCOSPOST_ vcos_verify_bkpts_enabled(void);
189VCOSPRE_ int VCOSPOST_ vcos_verify_bkpts_enable(int enable);
190VCOSPRE_ void VCOSPOST_ vcos_abort(void);
191
192#ifndef VCOS_ASSERT_MSG
193#ifdef LOGGING
194extern void logging_assert(const char *file, const char *func, int line, const char *format, ...);
195extern 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 */
318extern void vcos_backtrace_self(void);
319
320#ifdef __cplusplus
321}
322#endif
323
324#endif /* VCOS_ASSERT_H */
325