| 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 | |