Commit | Line | Data |
---|---|---|
1f9f5b4d | 1 | /* |
0235b0db MJ |
2 | * SPDX-License-Identifier: MIT |
3 | * | |
1f9f5b4d PP |
4 | * Copyright (c) 2019 EfficiOS Inc. and Linux Foundation |
5 | * Copyright (c) 2019 Philippe Proulx <pproulx@efficios.com> | |
1f9f5b4d PP |
6 | */ |
7 | ||
0235b0db MJ |
8 | #ifndef BABELTRACE_ASSERT_POST_INTERNAL_H |
9 | #define BABELTRACE_ASSERT_POST_INTERNAL_H | |
10 | ||
1f9f5b4d PP |
11 | /* |
12 | * The macros in this header use macros defined in "lib/logging.h". | |
13 | * We don't want this header to automatically include | |
14 | * "lib/logging.h" because you need to manually define BT_LOG_TAG | |
15 | * before including "lib/logging.h" and it is unexpected that you | |
16 | * also need to define it before including this header. | |
17 | * | |
18 | * This is a reminder that in order to use "lib/assert-post.h", you also | |
19 | * need to use logging explicitly. | |
20 | */ | |
21 | ||
22 | #ifndef BT_LIB_LOG_SUPPORTED | |
23 | # error Include "lib/logging.h" before this header. | |
24 | #endif | |
25 | ||
c4f23e30 | 26 | #include <stdbool.h> |
1f9f5b4d PP |
27 | #include <stdlib.h> |
28 | #include <inttypes.h> | |
29 | #include "common/macros.h" | |
498e7994 | 30 | #include "common/common.h" |
1f9f5b4d | 31 | |
1f9f5b4d PP |
32 | /* |
33 | * Prints the details of an unsatisfied postcondition without | |
34 | * immediately aborting. You should use this within a function which | |
bdb288b3 PP |
35 | * checks postconditions, but which is called from a |
36 | * BT_ASSERT_POST() context, so that the function can still return | |
37 | * its result for BT_ASSERT_POST() to evaluate it. | |
1f9f5b4d PP |
38 | * |
39 | * Example: | |
40 | * | |
41 | * BT_ASSERT_POST_FUNC | |
42 | * static inline bool check_complex_postcond(...) | |
43 | * { | |
44 | * ... | |
45 | * | |
46 | * if (...) { | |
47 | * BT_ASSERT_POST_MSG("Unexpected status: ...", ...); | |
48 | * return false; | |
49 | * } | |
50 | * | |
51 | * ... | |
52 | * } | |
53 | * | |
54 | * ... | |
55 | * | |
56 | * BT_ASSERT_POST(check_complex_postcond(...), | |
bdb288b3 | 57 | * "Postcondition is not satisfied: ...", ...); |
1f9f5b4d | 58 | */ |
bdb288b3 | 59 | #define BT_ASSERT_POST_MSG(_fmt, ...) \ |
1f9f5b4d PP |
60 | do { \ |
61 | bt_lib_log(_BT_LOG_SRCLOC_FUNCTION, __FILE__, \ | |
62 | __LINE__, BT_LOG_FATAL, BT_LOG_TAG, \ | |
63 | (_fmt), ##__VA_ARGS__); \ | |
64 | } while (0) | |
65 | ||
66 | /* | |
bdb288b3 | 67 | * Asserts that the library postcondition `_cond` is satisfied. |
1f9f5b4d PP |
68 | * |
69 | * If `_cond` is false, log a fatal statement using `_fmt` and the | |
70 | * optional arguments (same usage as BT_LIB_LOGF()), and abort. | |
71 | * | |
72 | * To assert that a library precondition is satisfied (parameters from | |
73 | * the user), use BT_ASSERT_PRE(). | |
74 | * | |
75 | * To assert that an internal postcondition is satisfied, use | |
98b15851 | 76 | * BT_ASSERT() or BT_ASSERT_DBG(). |
1f9f5b4d | 77 | */ |
bdb288b3 | 78 | #define BT_ASSERT_POST(_cond, _fmt, ...) \ |
1f9f5b4d PP |
79 | do { \ |
80 | if (!(_cond)) { \ | |
81 | BT_ASSERT_POST_MSG("Babeltrace 2 library postcondition not satisfied; error is:"); \ | |
bdb288b3 | 82 | BT_ASSERT_POST_MSG(_fmt, ##__VA_ARGS__); \ |
1f9f5b4d | 83 | BT_ASSERT_POST_MSG("Aborting..."); \ |
498e7994 | 84 | bt_common_abort(); \ |
1f9f5b4d PP |
85 | } \ |
86 | } while (0) | |
87 | ||
6ecdcca3 SM |
88 | /* |
89 | * Asserts that if there's an error on the current thread, an error status code | |
90 | * was returned. Puts back the error in place (if there is one) such that if | |
91 | * the assertion hits, it will be possible to inspect it with a debugger. | |
92 | */ | |
93 | #define BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(_status) \ | |
94 | do { \ | |
95 | const struct bt_error *err = bt_current_thread_take_error(); \ | |
96 | if (err) { \ | |
97 | bt_current_thread_move_error(err); \ | |
98 | } \ | |
99 | BT_ASSERT_POST(_status < 0 || !err, \ | |
100 | "Current thread has an error, but user function " \ | |
101 | "returned a non-error status: status=%s", \ | |
102 | bt_common_func_status_string(_status)); \ | |
103 | } while (0) | |
104 | ||
105 | /* | |
106 | * Asserts that the current thread has no error. | |
107 | */ | |
108 | #define BT_ASSERT_POST_NO_ERROR() \ | |
109 | BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(0) | |
110 | ||
1f9f5b4d PP |
111 | /* |
112 | * Marks a function as being only used within a BT_ASSERT_POST() | |
113 | * context. | |
114 | */ | |
bdb288b3 PP |
115 | #define BT_ASSERT_POST_FUNC |
116 | ||
117 | #ifdef BT_DEV_MODE | |
118 | /* Developer mode version of BT_ASSERT_POST_MSG(). */ | |
119 | # define BT_ASSERT_POST_DEV_MSG(_fmt, ...) \ | |
120 | BT_ASSERT_POST_MSG(_fmt, ##__VA_ARGS__) | |
121 | ||
122 | /* Developer mode version of BT_ASSERT_POST(). */ | |
123 | # define BT_ASSERT_POST_DEV(_cond, _fmt, ...) \ | |
124 | BT_ASSERT_POST((_cond), _fmt, ##__VA_ARGS__) | |
125 | ||
6ecdcca3 SM |
126 | /* Developer mode version of BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(). */ |
127 | # define BT_ASSERT_POST_DEV_NO_ERROR_IF_NO_ERROR_STATUS(_status) \ | |
128 | BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(_status) | |
129 | ||
bdb288b3 PP |
130 | /* Developer mode version of `BT_ASSERT_POST_FUNC`. */ |
131 | # define BT_ASSERT_POST_DEV_FUNC BT_ASSERT_POST_FUNC | |
1f9f5b4d | 132 | #else |
bdb288b3 PP |
133 | # define BT_ASSERT_POST_DEV_MSG(_fmt, ...) |
134 | # define BT_ASSERT_POST_DEV(_cond, _fmt, ...) ((void) sizeof((void) (_cond), 0)) | |
6ecdcca3 SM |
135 | # define BT_ASSERT_POST_DEV_NO_ERROR_IF_NO_ERROR_STATUS(_status) \ |
136 | ((void) sizeof((void) (_status), 0)) | |
bdb288b3 | 137 | # define BT_ASSERT_POST_DEV_FUNC __attribute__((unused)) |
1f9f5b4d PP |
138 | #endif /* BT_DEV_MODE */ |
139 | ||
ce53ba7a PP |
140 | #define BT_ASSERT_POST_SUPPORTED |
141 | ||
1f9f5b4d | 142 | #endif /* BABELTRACE_ASSERT_POST_INTERNAL_H */ |