} \
} while (0)
+/*
+ * Asserts that if there's an error on the current thread, an error status code
+ * was returned. Puts back the error in place (if there is one) such that if
+ * the assertion hits, it will be possible to inspect it with a debugger.
+ */
+#define BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(_status) \
+ do { \
+ const struct bt_error *err = bt_current_thread_take_error(); \
+ if (err) { \
+ bt_current_thread_move_error(err); \
+ } \
+ BT_ASSERT_POST(_status < 0 || !err, \
+ "Current thread has an error, but user function " \
+ "returned a non-error status: status=%s", \
+ bt_common_func_status_string(_status)); \
+ } while (0)
+
+/*
+ * Asserts that the current thread has no error.
+ */
+#define BT_ASSERT_POST_NO_ERROR() \
+ BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(0)
+
/*
* Marks a function as being only used within a BT_ASSERT_POST()
* context.
# define BT_ASSERT_POST_DEV(_cond, _fmt, ...) \
BT_ASSERT_POST((_cond), _fmt, ##__VA_ARGS__)
+/* Developer mode version of BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(). */
+# define BT_ASSERT_POST_DEV_NO_ERROR_IF_NO_ERROR_STATUS(_status) \
+ BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(_status)
+
/* Developer mode version of `BT_ASSERT_POST_FUNC`. */
# define BT_ASSERT_POST_DEV_FUNC BT_ASSERT_POST_FUNC
#else
# define BT_ASSERT_POST_DEV_MSG(_fmt, ...)
# define BT_ASSERT_POST_DEV(_cond, _fmt, ...) ((void) sizeof((void) (_cond), 0))
+# define BT_ASSERT_POST_DEV_NO_ERROR_IF_NO_ERROR_STATUS(_status) \
+ ((void) sizeof((void) (_status), 0))
# define BT_ASSERT_POST_DEV_FUNC __attribute__((unused))
#endif /* BT_DEV_MODE */
status == BT_FUNC_STATUS_MEMORY_ERROR,
"Unexpected returned component status: status=%s",
bt_common_func_status_string(status));
+ BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(status);
}
return status;
consume_status == BT_FUNC_STATUS_MEMORY_ERROR,
"Invalid component status returned by consuming method: "
"status=%s", bt_common_func_status_string(consume_status));
+ BT_ASSERT_POST_DEV_NO_ERROR_IF_NO_ERROR_STATUS(consume_status);
if (consume_status) {
if (consume_status < 0) {
BT_LIB_LOGW_APPEND_CAUSE(
BT_ASSERT(listener->func);
status = listener->func(comp, port, listener->base.data);
+ BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(status);
if (status != BT_FUNC_STATUS_OK) {
goto end;
}
BT_ASSERT(listener->func);
status = listener->func(upstream_comp, downstream_comp,
upstream_port, downstream_port, listener->base.data);
+ BT_ASSERT_POST_DEV_NO_ERROR_IF_NO_ERROR_STATUS(status);
if (status != BT_FUNC_STATUS_OK) {
goto end;
}
init_status = init_method(component, NULL, params, init_method_data);
BT_LOGD("User method returned: status=%s",
bt_common_func_status_string(init_status));
+ BT_ASSERT_POST_DEV_NO_ERROR_IF_NO_ERROR_STATUS(init_status);
if (init_status != BT_FUNC_STATUS_OK) {
if (init_status < 0) {
BT_LIB_LOGW_APPEND_CAUSE(
comp_status == BT_FUNC_STATUS_MEMORY_ERROR,
"Unexpected returned status: status=%s",
bt_common_func_status_string(comp_status));
+ BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(comp_status);
if (comp_status != BT_FUNC_STATUS_OK) {
if (comp_status < 0) {
BT_LIB_LOGW_APPEND_CAUSE(
upstream_port);
BT_LOGD("User method returned: status=%s",
bt_common_func_status_string(iter_status));
+ BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(iter_status);
if (iter_status != BT_FUNC_STATUS_OK) {
BT_LIB_LOGW_APPEND_CAUSE(
"Component input port message iterator initialization method failed: "
"Clock snapshots are not monotonic");
}
+ BT_ASSERT_POST_DEV_NO_ERROR_IF_NO_ERROR_STATUS(status);
+
return status;
}
status = (int) iterator->methods.can_seek_ns_from_origin(iterator,
ns_from_origin, can_seek);
+ BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(status);
+
if (status != BT_FUNC_STATUS_OK) {
BT_LIB_LOGW_APPEND_CAUSE(
"Component input port message iterator's \"can seek nanoseconds from origin\" method failed: "
*can_seek == BT_FALSE,
"Unexpected boolean value returned from user's \"can seek beginning\" method: val=%d, %![iter-]+i",
*can_seek, iterator);
+ BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(status);
} else {
*can_seek = BT_FALSE;
status = BT_FUNC_STATUS_OK;
status == BT_FUNC_STATUS_AGAIN,
"Unexpected status: %![iter-]+i, status=%s",
iterator, bt_common_func_status_string(status));
+ BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(status);
if (status < 0) {
BT_LIB_LOGW_APPEND_CAUSE(
"Component input port message iterator's \"seek beginning\" method failed: "
status == BT_FUNC_STATUS_AGAIN,
"Unexpected status: %![iter-]+i, status=%s",
iterator, bt_common_func_status_string(status));
+ BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(status);
if (status < 0) {
BT_LIB_LOGW_APPEND_CAUSE(
"Component input port message iterator's \"seek nanoseconds from origin\" method failed: "
range_set->ranges->len > 0,
"User method returned `BT_FUNC_STATUS_OK` without "
"adding a range to the supported MIP version range set.");
+ BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(method_status);
if (method_status < 0) {
BT_LIB_LOGW_APPEND_CAUSE(
"Component class's \"get supported MIP versions\" method failed: "
bt_common_func_status_string(query_status), *user_result);
BT_ASSERT_POST(query_status != BT_FUNC_STATUS_OK || *user_result,
"User method returned `BT_FUNC_STATUS_OK` without a result.");
+ BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(query_status);
status = (int) query_status;
if (status < 0) {
if (elem.func) {
elem.func(tc, elem.data);
+ BT_ASSERT_POST_NO_ERROR();
}
/*
if (elem.func) {
elem.func(trace, elem.data);
+ BT_ASSERT_POST_NO_ERROR();
}
/*