VirtualBox

root/trunk/include/iprt/assert.h

Revision 13931, 64.9 kB (checked in by vboxsync, 2 weeks ago)

iprt/assert.h: Added AssertGCPtr32.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /** @file
2  * IPRT - Assertions.
3  */
4
5 /*
6  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
7  *
8  * This file is part of VirtualBox Open Source Edition (OSE), as
9  * available from http://www.virtualbox.org. This file is free software;
10  * you can redistribute it and/or modify it under the terms of the GNU
11  * General Public License (GPL) as published by the Free Software
12  * Foundation, in version 2 as it comes in the "COPYING" file of the
13  * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15  *
16  * The contents of this file may alternatively be used under the terms
17  * of the Common Development and Distribution License Version 1.0
18  * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19  * VirtualBox OSE distribution, in which case the provisions of the
20  * CDDL are applicable instead of those of the GPL.
21  *
22  * You may elect to license modified versions of this file under the
23  * terms and conditions of either the GPL or the CDDL or both.
24  *
25  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
26  * Clara, CA 95054 USA or visit http://www.sun.com if you need
27  * additional information or have any questions.
28  */
29
30 #ifndef ___iprt_assert_h
31 #define ___iprt_assert_h
32
33 #include <iprt/cdefs.h>
34 #include <iprt/types.h>
35
36 /** @defgroup grp_rt_assert     Assert - Assertions
37  * @ingroup grp_rt
38  *
39  * Assertions are generally used to check precoditions and other
40  * assumptions. Sometimes it is also used to catch odd errors or errors
41  * that one would like to inspect in the debugger. They should not be
42  * used for errors that happen frequently.
43  *
44  * IPRT provides a host of assertion macros, so many that it can be a bit
45  * overwhelming at first. Don't despair, there is a system (surprise).
46  *
47  * First there are four families of assertions:
48  *      - Assert        - The normal strict build only assertions.
49  *      - AssertLogRel  - Calls LogRel() in non-strict builds, otherwise like Assert.
50  *      - AssertRelease - Triggers in all builds.
51  *      - AssertFatal   - Triggers in all builds and cannot be continued.
52  *
53  * Then there are variations wrt to argument list and behavior on failure:
54  *      - Msg           - Custom RTStrPrintf-like message with the assertion message.
55  *      - Return        - Return the specific rc on failure.
56  *      - ReturnVoid    - Return (void) on failure.
57  *      - Break         - Break (out of switch/loop) on failure.
58  *      - Stmt          - Execute the specified statment(s) on failure.
59  *      - RC            - Assert RT_SUCCESS.
60  *      - RCSuccess     - Assert VINF_SUCCESS.
61  *
62  * In additions there is a very special familiy AssertCompile that can be
63  * used for some limited compile checking. Like structure sizes and member
64  * alignment. This family doesn't have the same variations.
65  *
66  *
67  * @remarks As you might've noticed, the macros doesn't follow the
68  * coding guidelines wrt to macros supposedly being all uppercase
69  * and  underscored. For various  reasons they don't, and it nobody
70  * has complained yet. Wonder why... :-)
71  *
72  * @remarks Each project has its own specific guidelines on how to use
73  * assertions, so the above is just trying to give you the general idea
74  * from the IPRT point of view.
75  *
76  * @{
77  */
78
79 __BEGIN_DECLS
80
81 /**
82  * The 1st part of an assert message.
83  *
84  * @param   pszExpr     Expression. Can be NULL.
85  * @param   uLine       Location line number.
86  * @param   pszFile     Location file name.
87  * @param   pszFunction Location function name.
88  * @remark  This API exists in HC Ring-3 and GC.
89  */
90 RTDECL(void) AssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction);
91
92 /**
93  * The 2nd (optional) part of an assert message.
94  * @param   pszFormat   Printf like format string.
95  * @param   ...         Arguments to that string.
96  * @remark  This API exists in HC Ring-3 and GC.
97  */
98 RTDECL(void) AssertMsg2(const char *pszFormat, ...);
99
100 #ifdef IN_RING0
101 /**
102  * Panics the system as the result of a fail assertion.
103  */
104 RTR0DECL(void)  RTR0AssertPanicSystem(void);
105 #endif /* IN_RING0 */
106
107 /**
108  * Overridable function that decides whether assertions executes the panic
109  * (breakpoint) or not.
110  *
111  * The generic implementation will return true.
112  *
113  * @returns true if the breakpoint should be hit, false if it should be ignored.
114  *
115  * @remark  The RTDECL() makes this a bit difficult to override on Windows. So,
116  *          you'll have ot use RTASSERT_HAVE_SHOULD_PANIC or
117  *          RTASSERT_HAVE_SHOULD_PANIC_PRIVATE there to control the kind of
118  *          prototype.
119  */
120 #if !defined(RTASSERT_HAVE_SHOULD_PANIC) && !defined(RTASSERT_HAVE_SHOULD_PANIC_PRIVATE)
121 RTDECL(bool)    RTAssertShouldPanic(void);
122 #elif defined(RTASSERT_HAVE_SHOULD_PANIC_PRIVATE)
123 bool            RTAssertShouldPanic(void);
124 #else
125 DECLEXPORT(bool) RTCALL RTAssertShouldPanic(void);
126 #endif
127
128 /** @name Globals for crash analysis
129  * @remarks     This is the full potential set, it
130  * @{
131  */
132 /** The last assert message, 1st part. */
133 extern RTDATADECL(char)                     g_szRTAssertMsg1[1024];
134 /** The last assert message, 2nd part. */
135 extern RTDATADECL(char)                     g_szRTAssertMsg2[2048];
136 /** The last assert message, expression. */
137 extern RTDATADECL(const char * volatile)    g_pszRTAssertExpr;
138 /** The last assert message, file name. */
139 extern RTDATADECL(const char * volatile)    g_pszRTAssertFile;
140 /** The last assert message, line number. */
141 extern RTDATADECL(uint32_t volatile)        g_u32RTAssertLine;
142 /** The last assert message, function name. */
143 extern RTDATADECL(const char * volatile)    g_pszRTAssertFunction;
144 /** @} */
145
146 __END_DECLS
147
148 /** @def RTAssertDebugBreak()
149  * Debugger breakpoint instruction.
150  *
151  * @remarks In the gnu world we add a nop instruction after the int3 to
152  *          force gdb to remain at the int3 source line.
153  * @remarks The L4 kernel will try make sense of the breakpoint, thus the jmp.
154  * @remarks This macro does not depend on RT_STRICT.
155  */
156 #ifdef __GNUC__
157 # ifndef __L4ENV__
158 define RTAssertDebugBreak()  do { __asm__ __volatile__ ("int3\n\tnop"); } while (0)
159 # else
160 define RTAssertDebugBreak()  do { __asm__ __volatile__ ("int3; jmp 1f; 1:"); } while (0)
161 # endif
162 #elif defined(_MSC_VER) || defined(DOXYGEN_RUNNING)
163 # define RTAssertDebugBreak()   do { __debugbreak(); } while (0)
164 #else
165 # error "Unknown compiler"
166 #endif
167
168
169
170 /** @name Compile time assertions.
171  *
172  * These assertions are used to check structure sizes, memember/size alignments
173  * and similar compile time expressions.
174  *
175  * @{
176  */
177
178 /**
179  * RTASSERTTYPE is the type the AssertCompile() macro redefines.
180  * It has no other function and shouldn't be used.
181  * Visual C++ uses this.
182  */
183 typedef int RTASSERTTYPE[1];
184
185 /**
186  * RTASSERTVAR is the type the AssertCompile() macro redefines.
187  * It has no other function and shouldn't be used.
188  * GCC uses this.
189  */
190 #ifdef __GNUC__
191 __BEGIN_DECLS
192 #endif
193 extern int RTASSERTVAR[1];
194 #ifdef __GNUC__
195 __END_DECLS
196 #endif
197
198 /** @def AssertCompile
199  * Asserts that a compile-time expression is true. If it's not break the build.
200  * @param   expr    Expression which should be true.
201  */
202 #ifdef __GNUC__
203 # define AssertCompile(expr)    extern int RTASSERTVAR[1] __attribute__((unused)), RTASSERTVAR[(expr) ? 1 : 0] __attribute__((unused))
204 #else
205 # define AssertCompile(expr)    typedef int RTASSERTTYPE[(expr) ? 1 : 0]
206 #endif
207
208 /** @def AssertCompileSize
209  * Asserts a size at compile.
210  * @param   type    The type.
211  * @param   size    The expected type size.
212  */
213 #define AssertCompileSize(type, size) \
214     AssertCompile(sizeof(type) == (size))
215
216 /** @def AssertCompileSizeAlignment
217  * Asserts a size alignment at compile.
218  * @param   type    The type.
219  * @param   align   The size alignment to assert.
220  */
221 #define AssertCompileSizeAlignment(type, align) \
222     AssertCompile(!(sizeof(type) & ((align) - 1)))
223
224 /** @def AssertCompileMemberSize
225  * Asserts a member offset alignment at compile.
226  * @param   type    The type.
227  * @param   member  The member.
228  * @param   size    The member size to assert.
229  */
230 #define AssertCompileMemberSize(type, member, size) \
231     AssertCompile(RT_SIZEOFMEMB(type, member) == (size))
232
233 /** @def AssertCompileMemberSizeAlignment
234  * Asserts a member size alignment at compile.
235  * @param   type    The type.
236  * @param   member  The member.
237  * @param   align   The member size alignment to assert.
238  */
239 #define AssertCompileMemberSizeAlignment(type, member, align) \
240     AssertCompile(!(RT_SIZEOFMEMB(type, member) & ((align) - 1)))
241
242 /** @def AssertCompileMemberAlignment
243  * Asserts a member offset alignment at compile.
244  * @param   type    The type.
245  * @param   member  The member.
246  * @param   align   The member offset alignment to assert.
247  */
248 #if defined(__GNUC__) && defined(__cplusplus)
249 # if __GNUC__ >= 4
250 define AssertCompileMemberAlignment(type, member, align) \
251     AssertCompile(!(__builtin_offsetof(type, member) & ((align) - 1)))
252 # else
253 define AssertCompileMemberAlignment(type, member, align) \
254     AssertCompile(!(RT_OFFSETOF(type, member) & ((align) - 1)))
255 # endif
256 #else
257 # define AssertCompileMemberAlignment(type, member, align) \
258     AssertCompile(!(RT_OFFSETOF(type, member) & ((align) - 1)))
259 #endif
260
261 /** @def AssertCompileMemberOffset
262  * Asserts a offset of a structure member at compile.
263  * @param   type    The type.
264  * @param   member  The member.
265  * @param   off     The expected offset.
266  */
267 #if defined(__GNUC__) && defined(__cplusplus)
268 # if __GNUC__ >= 4
269 define AssertCompileMemberOffset(type, member, off) \
270     AssertCompile(__builtin_offsetof(type, member) == (off))
271 # else
272 define AssertCompileMemberOffset(type, member, off) \
273     AssertCompile(RT_OFFSETOF(type, member) == (off))
274 # endif
275 #else
276 # define AssertCompileMemberOffset(type, member, off) \
277     AssertCompile(RT_OFFSETOF(type, member) == (off))
278 #endif
279
280 /** @} */
281
282
283
284 /** @name Assertions
285  *
286  * These assertions will only trigger when RT_STRICT is defined. When it is
287  * undefined they will all be noops and generate no code.
288  *
289  * @{
290  */
291
292 /** @def RTAssertDoPanic
293  * Raises an assertion panic appropriate to the current context.
294  * @remarks This macro does not depend on RT_STRICT.
295  */
296 #if (defined(IN_RING0) && !defined(IN_RING0_AGNOSTIC)) \
297  && (defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS))
298 # define RTAssertDoPanic()      RTR0AssertPanicSystem()
299 #else
300 # define RTAssertDoPanic()      RTAssertDebugBreak()
301 #endif
302
303 /** @def AssertBreakpoint()
304  * Assertion Breakpoint.
305  * @deprecated Use RTAssertPanic or RTAssertDebugBreak instead.
306  */
307 #ifdef RT_STRICT
308 # define AssertBreakpoint()     RTAssertDebugBreak()
309 #else
310 # define AssertBreakpoint()     do { } while (0)
311 #endif
312
313 /** @def rtAssertPanic()
314  * If RT_STRICT is defined this macro will invoke RTAssertDoPanic if
315  * RTAssertShouldPanic returns true. If RT_STRICT isn't defined it won't do any
316  * thing.
317  */
318 #ifdef RT_STRICT
319 # define RTAssertPanic()        do { if (RTAssertShouldPanic()) RTAssertDoPanic(); } while (0)
320 #else
321 # define RTAssertPanic()        do { } while (0)
322 #endif
323
324 /** @def Assert
325  * Assert that an expression is true. If it's not hit breakpoint.
326  * @param   expr    Expression which should be true.
327  */
328 #ifdef RT_STRICT
329 # define Assert(expr)  \
330     do { \
331         if (RT_UNLIKELY(!(expr))) \
332         { \
333             AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
334             RTAssertPanic(); \
335         } \
336     } while (0)
337 #else
338 # define Assert(expr)     do { } while (0)
339 #endif
340
341
342 /** @def AssertReturn
343  * Assert that an expression is true and returns if it isn't.
344  * In RT_STRICT mode it will hit a breakpoint before returning.
345  *
346  * @param   expr    Expression which should be true.
347  * @param   rc      What is to be presented to return.
348  */
349 #ifdef RT_STRICT
350 # define AssertReturn(expr, rc) \
351     do { \
352         if (RT_UNLIKELY(!(expr))) \
353         { \
354             AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
355             RTAssertPanic(); \
356             return (rc); \
357         } \
358     } while (0)
359 #else
360 # define AssertReturn(expr, rc) \
361     do { \
362         if (RT_UNLIKELY(!(expr))) \
363             return (rc); \
364     } while (0)
365 #endif
366
367 /** @def AssertReturnVoid
368  * Assert that an expression is true and returns if it isn't.
369  * In RT_STRICT mode it will hit a breakpoint before returning.
370  *
371  * @param   expr    Expression which should be true.
372  */
373 #ifdef RT_STRICT
374 # define AssertReturnVoid(expr) \
375     do { \
376         if (RT_UNLIKELY(!(expr))) \
377         { \
378             AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
379             RTAssertPanic(); \
380             return; \
381         } \
382     } while (0)
383 #else
384 # define AssertReturnVoid(expr) \
385     do { \
386         if (RT_UNLIKELY(!(expr))) \
387             return; \
388     } while (0)
389 #endif
390
391
392 /** @def AssertBreak
393  * Assert that an expression is true and breaks if it isn't.
394  * In RT_STRICT mode it will hit a breakpoint before returning.
395  *
396  * @param   expr    Expression which should be true.
397  */
398 #ifdef RT_STRICT
399 # define AssertBreak(expr) \
400     if (RT_UNLIKELY(!(expr))) \
401     { \
402         AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
403         RTAssertPanic(); \
404         break; \
405     } else do {} while (0)
406 #else
407 # define AssertBreak(expr) \
408     if (RT_UNLIKELY(!(expr))) \
409         break; \
410     else do {} while (0)
411 #endif
412
413 /** @def AssertBreakStmt
414  * Assert that an expression is true and breaks if it isn't.
415  * In RT_STRICT mode it will hit a breakpoint before doing break.
416  *
417  * @param   expr    Expression which should be true.
418  * @param   stmt    Statement to execute before break in case of a failed assertion.
419  */
420 #ifdef RT_STRICT
421 # define AssertBreakStmt(expr, stmt) \
422     if (RT_UNLIKELY(!(expr))) { \
423         AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
424         RTAssertPanic(); \
425         stmt; \
426         break; \
427     } else do {} while (0)
428 #else
429 # define AssertBreakStmt(expr, stmt) \
430     if (RT_UNLIKELY(!(expr))) { \
431         stmt; \
432         break; \
433     } else do {} while (0)
434 #endif
435
436
437 /** @def AssertMsg
438  * Assert that an expression is true. If it's not print message and hit breakpoint.
439  * @param   expr    Expression which should be true.
440  * @param   a       printf argument list (in parenthesis).
441  */
442 #ifdef RT_STRICT
443 # define AssertMsg(expr, a)  \
444     do { \
445         if (RT_UNLIKELY(!(expr))) \
446         { \
447             AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
448             AssertMsg2 a; \
449             RTAssertPanic(); \
450         } \
451     } while (0)
452 #else
453 # define AssertMsg(expr, a)  do { } while (0)
454 #endif
455
456 /** @def AssertMsgReturn
457  * Assert that an expression is true and returns if it isn't.
458  * In RT_STRICT mode it will hit a breakpoint before returning.
459  *
460  * @param   expr    Expression which should be true.
461  * @param   a       printf argument list (in parenthesis).
462  * @param   rc      What is to be presented to return.
463  */
464 #ifdef RT_STRICT
465 # define AssertMsgReturn(expr, a, rc)  \
466     do { \
467         if (RT_UNLIKELY(!(expr))) \
468         { \
469             AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
470             AssertMsg2 a; \
471             RTAssertPanic(); \
472             return (rc); \
473         } \
474     } while (0)
475 #else
476 # define AssertMsgReturn(expr, a, rc) \
477     do { \
478         if (RT_UNLIKELY(!(expr))) \
479             return (rc); \
480     } while (0)
481 #endif
482
483 /** @def AssertMsgReturnVoid
484  * Assert that an expression is true and returns if it isn't.
485  * In RT_STRICT mode it will hit a breakpoint before returning.
486  *
487  * @param   expr    Expression which should be true.
488  * @param   a       printf argument list (in parenthesis).
489  */
490 #ifdef RT_STRICT
491 # define AssertMsgReturnVoid(expr, a)  \
492     do { \
493         if (RT_UNLIKELY(!(expr))) \
494         { \
495             AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
496             AssertMsg2 a; \
497             RTAssertPanic(); \
498             return; \
499         } \
500     } while (0)
501 #else
502 # define AssertMsgReturnVoid(expr, a) \
503     do { \
504         if (RT_UNLIKELY(!(expr))) \
505             return; \
506     } while (0)
507 #endif
508
509
510 /** @def AssertMsgBreak
511  * Assert that an expression is true and breaks if it isn't.
512  * In RT_STRICT mode it will hit a breakpoint before returning.
513  *
514  * @param   expr    Expression which should be true.
515  * @param   a       printf argument list (in parenthesis).
516  */
517 #ifdef RT_STRICT
518 # define AssertMsgBreak(expr, a)  \
519     if (RT_UNLIKELY(!(expr))) \
520     { \
521         AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
522         AssertMsg2 a; \
523         RTAssertPanic(); \
524         break; \
525     } else do {} while (0)
526 #else
527 # define AssertMsgBreak(expr, a) \
528     if (RT_UNLIKELY(!(expr))) \
529         break; \
530     else do {} while (0)
531 #endif
532
533 /** @def AssertMsgBreakStmt
534  * Assert that an expression is true and breaks if it isn't.
535  * In RT_STRICT mode it will hit a breakpoint before doing break.
536  *
537  * @param   expr    Expression which should be true.
538  * @param   a       printf argument list (in parenthesis).
539  * @param   stmt    Statement to execute before break in case of a failed assertion.
540  */
541 #ifdef RT_STRICT
542 # define AssertMsgBreakStmt(expr, a, stmt) \
543     if (RT_UNLIKELY(!(expr))) { \
544         AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
545         AssertMsg2 a; \
546         RTAssertPanic(); \
547         stmt; \
548         break; \
549     } else do {} while (0)
550 #else
551 # define AssertMsgBreakStmt(expr, a, stmt) \
552     if (RT_UNLIKELY(!(expr))) { \
553         stmt; \
554         break; \
555     } else do {} while (0)
556 #endif
557
558 /** @def AssertFailed
559  * An assertion failed hit breakpoint.
560  */
561 #ifdef RT_STRICT
562 # define AssertFailed()  \
563     do { \
564         AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
565         RTAssertPanic(); \
566     } while (0)
567 #else
568 # define AssertFailed()         do { } while (0)
569 #endif
570
571 /** @def AssertFailedReturn
572  * An assertion failed, hit breakpoint (RT_STRICT mode only) and return.
573  *
574  * @param   rc      The rc to return.
575  */
576 #ifdef RT_STRICT
577 # define AssertFailedReturn(rc)  \
578     do { \
579         AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
580         RTAssertPanic(); \
581         return (rc); \
582     } while (0)
583 #else
584 # define AssertFailedReturn(rc)  \
585     do { \
586         return (rc); \
587     } while (0)
588 #endif
589
590 /** @def AssertFailedReturnVoid
591  * An assertion failed, hit breakpoint (RT_STRICT mode only) and return.
592  */
593 #ifdef RT_STRICT
594 # define AssertFailedReturnVoid()  \
595     do { \
596         AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
597         RTAssertPanic(); \
598         return; \
599     } while (0)
600 #else
601 # define AssertFailedReturnVoid()  \
602     do { \
603         return; \
604     } while (0)
605 #endif
606
607
608 /** @def AssertFailedBreak
609  * An assertion failed, hit breakpoint (RT_STRICT mode only) and break.
610  */
611 #ifdef RT_STRICT
612 # define AssertFailedBreak()  \
613     if (1) { \
614         AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
615         RTAssertPanic(); \
616         break; \
617     } else do {} while (0)
618 #else
619 # define AssertFailedBreak()  \
620     if (1) \
621         break; \
622     else do {} while (0)
623 #endif
624
625 /** @def AssertFailedBreakStmt
626  * An assertion failed, hit breakpoint (RT_STRICT mode only), execute
627  * the given statement and break.
628  *
629  * @param   stmt    Statement to execute before break.
630  */
631 #ifdef RT_STRICT
632 # define AssertFailedBreakStmt(stmt) \
633     if (1) { \
634         AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
635         RTAssertPanic(); \
636         stmt; \
637         break; \
638     } else do {} while (0)
639 #else
640 # define AssertFailedBreakStmt(stmt) \
641     if (1) { \
642         stmt; \
643         break; \
644     } else do {} while (0)
645 #endif
646
647
648 /** @def AssertMsgFailed
649  * An assertion failed print a message and a hit breakpoint.
650  *
651  * @param   a   printf argument list (in parenthesis).
652  */
653 #ifdef RT_STRICT
654 # define AssertMsgFailed(a)  \
655     do { \
656         AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
657         AssertMsg2 a; \
658         RTAssertPanic(); \
659     } while (0)
660 #else
661 # define AssertMsgFailed(a)     do { } while (0)
662 #endif
663
664 /** @def AssertMsgFailedReturn
665  * An assertion failed, hit breakpoint with message (RT_STRICT mode only) and return.
666  *
667  * @param   a       printf argument list (in parenthesis).
668  * @param   rc      What is to be presented to return.
669  */
670 #ifdef RT_STRICT
671 # define AssertMsgFailedReturn(a, rc)  \
672     do { \
673         AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
674         AssertMsg2 a; \
675         RTAssertPanic(); \
676         return (rc); \
677     } while (0)
678 #else
679 # define AssertMsgFailedReturn(a, rc)  \
680     do { \
681         return (rc); \
682     } while (0)
683 #endif
684
685 /** @def AssertMsgFailedReturnVoid
686  * An assertion failed, hit breakpoint with message (RT_STRICT mode only) and return.
687  *
688  * @param   a       printf argument list (in parenthesis).
689  */
690 #ifdef RT_STRICT
691 # define AssertMsgFailedReturnVoid(a)  \
692     do { \
693         AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
694         AssertMsg2 a; \
695         RTAssertPanic(); \
696         return; \
697     } while (0)
698 #else
699 # define AssertMsgFailedReturnVoid(a)  \
700     do { \
701         return; \
702     } while (0)
703 #endif
704
705
706 /** @def AssertMsgFailedBreak
707  * An assertion failed, hit breakpoint with message (RT_STRICT mode only) and break.
708  *
709  * @param   a       printf argument list (in parenthesis).
710  */
711 #ifdef RT_STRICT
712 # define AssertMsgFailedBreak(a)  \
713     if (1) { \
714         AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
715         AssertMsg2 a; \
716         RTAssertPanic(); \
717         break; \
718     } else do {} while (0)
719 #else
720 # define AssertMsgFailedBreak(a)  \
721     if (1) \
722         break; \
723     else do {} while (0)
724 #endif
725
726 /** @def AssertMsgFailedBreakStmt
727  * An assertion failed, hit breakpoint (RT_STRICT mode only), execute
728  * the given statement and break.
729  *
730  * @param   a       printf argument list (in parenthesis).
731  * @param   stmt    Statement to execute before break.
732  */
733 #ifdef RT_STRICT
734 # define AssertMsgFailedBreakStmt(a, stmt) \
735     if (1) { \
736         AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
737         AssertMsg2 a; \
738         RTAssertPanic(); \
739         stmt; \
740         break; \
741     } else do {} while (0)
742 #else
743 # define AssertMsgFailedBreakStmt(a, stmt) \
744     if (1) { \
745         stmt; \
746         break; \
747     } else do {} while (0)
748 #endif
749
750 /** @} */
751
752
753
754 /** @name Release Log Assertions
755  *
756  * These assertions will work like normal strict assertion when RT_STRICT is
757  * defined and LogRel statements when RT_STRICT is undefined. Typically used for
758  * things which shouldn't go wrong, but when it does you'd like to know one way
759  * or ther other.
760  *
761  * @{
762  */
763
764 /** @def RTAssertLogRelMsg1
765  * AssertMsg1 (strict builds) / LogRel wrapper (non-strict).
766  */
767 #ifdef RT_STRICT
768 # define RTAssertLogRelMsg1(pszExpr, iLine, pszFile, pszFunction) \
769     AssertMsg1(pszExpr, iLine, pszFile, pszFunction)
770 #else
771 # define RTAssertLogRelMsg1(pszExpr, iLine, pszFile, pszFunction) \
772     LogRel(("AssertLogRel %s(%d) %s: %s\n",\
773             (pszFile), (iLine), (pszFunction), (pszExpr) ))
774 #endif
775
776 /** @def RTAssertLogRelMsg2
777  * AssertMsg2 (strict builds) / LogRel wrapper (non-strict).
778  */
779 #ifdef RT_STRICT
780 # define RTAssertLogRelMsg2(a)  AssertMsg2 a
781 #else
782 # define RTAssertLogRelMsg2(a)  LogRel(a)
783 #endif
784
785 /** @def AssertLogRel
786  * Assert that an expression is true.
787  * Strict builds will hit a breakpoint, non-strict will only do LogRel.
788  *
789  * @param   expr    Expression which should be true.
790  */
791 #define AssertLogRel(expr) \
792     do { \
793         if (RT_UNLIKELY(!(expr))) \
794         { \
795             RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
796             RTAssertPanic(); \
797         } \
798     } while (0)
799
800 /** @def AssertLogRelReturn
801  * Assert that an expression is true, return \a rc if it isn't.
802  * Strict builds will hit a breakpoint, non-strict will only do LogRel.
803  *
804  * @param   expr    Expression which should be true.
805  * @param   rc      What is to be presented to return.
806  */
807 #define AssertLogRelReturn(expr, rc) \
808     do { \
809         if (RT_UNLIKELY(!(expr))) \
810         { \
811             RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
812             RTAssertPanic(); \
813             return (rc); \
814         } \
815     } while (0)
816
817 /** @def AssertLogRelReturnVoid
818  * Assert that an expression is true, return void if it isn't.
819  * Strict builds will hit a breakpoint, non-strict will only do LogRel.
820  *
821  * @param   expr    Expression which should be true.
822  */
823 #define AssertLogRelReturnVoid(expr) \
824     do { \
825         if (RT_UNLIKELY(!(expr))) \
826         { \
827             RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
828             RTAssertPanic(); \
829             return; \
830         } \
831     } while (0)
832
833 /** @def AssertLogRelBreak
834  * Assert that an expression is true, break if it isn't.
835  * Strict builds will hit a breakpoint, non-strict will only do LogRel.
836  *
837  * @param   expr    Expression which should be true.
838  */
839 #define AssertLogRelBreak(expr) \
840     if (RT_UNLIKELY(!(expr))) \
841     { \
842         RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
843         RTAssertPanic(); \
844         break; \
845     } \
846     else do {} while (0)
847
848 /** @def AssertLogRelBreakStmt
849  * Assert that an expression is true, execute \a stmt and break if it isn't.
850  * Strict builds will hit a breakpoint, non-strict will only do LogRel.
851  *
852  * @param   expr    Expression which should be true.
853  * @param   stmt    Statement to execute before break in case of a failed assertion.
854  */
855 #define AssertLogRelBreakStmt(expr, stmt) \
856     if (RT_UNLIKELY(!(expr))) \
857     { \
858         RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
859         RTAssertPanic(); \
860         stmt; \
861         break; \
862     } else do {} while (0)
863
864 /** @def AssertLogRelMsg
865  * Assert that an expression is true.
866  * Strict builds will hit a breakpoint, non-strict will only do LogRel.
867  *
868  * @param   expr    Expression which should be true.
869  * @param   a       printf argument list (in parenthesis).
870  */
871 #define AssertLogRelMsg(expr, a) \
872     do { \
873         if (RT_UNLIKELY(!(expr))) \
874         { \
875             RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
876             RTAssertLogRelMsg2(a); \
877             RTAssertPanic(); \
878         } \
879     } while (0)
880
881 /** @def AssertLogRelMsgReturn
882  * Assert that an expression is true, return \a rc if it isn't.
883  * Strict builds will hit a breakpoint, non-strict will only do LogRel.
884  *
885  * @param   expr    Expression which should be tr