If something fails in `bt_bt2_auto_discover_source_components`, we
append an error cause and we go to the error label. This function
returns a bt_value map containing the return status code and the auto-discovery results, if it was successful.
So we then run into:
if (result) {
insert_entry_status = bt_value_map_insert_signed_integer_entry(result, "status", status);
if (insert_entry_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) {
BT_VALUE_PUT_REF_AND_RESET(result);
PyErr_NoMemory();
}
}
However, since there is an error on the current thread, we fail this
precondition:
06-30 11:27:11.697
3948806 3948806 F LIB/ASSERT-COND bt_lib_assert_cond_failed@assert-cond.c:64 Babeltrace 2 library precondition not satisfied.
06-30 11:27:11.697
3948806 3948806 F LIB/ASSERT-COND bt_lib_assert_cond_failed@assert-cond.c:66 ------------------------------------------------------------------------
06-30 11:27:11.697
3948806 3948806 F LIB/ASSERT-COND bt_lib_assert_cond_failed@assert-cond.c:67 Condition ID: `pre:value-map-insert-signed-integer-entry:no-error`.
06-30 11:27:11.697
3948806 3948806 F LIB/ASSERT-COND bt_lib_assert_cond_failed@assert-cond.c:69 Function: bt_value_map_insert_signed_integer_entry().
06-30 11:27:11.697
3948806 3948806 F LIB/ASSERT-COND bt_lib_assert_cond_failed@assert-cond.c:70 ------------------------------------------------------------------------
06-30 11:27:11.697
3948806 3948806 F LIB/ASSERT-COND bt_lib_assert_cond_failed@assert-cond.c:71 Error is:
06-30 11:27:11.697
3948806 3948806 F LIB/ASSERT-COND bt_lib_assert_cond_failed@assert-cond.c:73 API function called while current thread has an error: function=bt_value_map_insert_signed_integer_entry
06-30 11:27:11.697
3948806 3948806 F LIB/ASSERT-COND bt_lib_assert_cond_failed@assert-cond.c:76 Aborting...
Change the function to temporarily remove the current thread error,
while inserting the status in the map. In the unlikely event where the
insertion fail because of a memory error, then we just release the error
and it gets lost.
Cherry-pick note
----------------
Just like the previous commit, the error string expected by the test had
to be updated.
Change-Id: I1b54fb7c8cb0f719fee867e7385dd6a3949cbde4
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/8512
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
(cherry picked from commit
827e42e017fc5f525aa39a3851bf2e7e50e887aa)
Reviewed-on: https://review.lttng.org/c/babeltrace/+/9512
Tested-by: jenkins <jenkins@lttng.org>
bt_value *components_list = NULL;
bt_value *component_info = NULL;
bt_value_map_insert_entry_status insert_entry_status;
+ const bt_error *error = NULL;
BT_ASSERT(bt_value_get_type(inputs) == BT_VALUE_TYPE_ARRAY);
for (i = 0; i < bt_value_array_get_length(inputs); i++) {
end:
if (result) {
+ /*
+ * If an error happened, we must clear the error temporarily
+ * while we insert the status in the map.
+ */
+ error = bt_current_thread_take_error();
insert_entry_status = bt_value_map_insert_signed_integer_entry(result, "status", status);
- if (insert_entry_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) {
+ if (insert_entry_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) {
+ if (error) {
+ bt_current_thread_move_error(error);
+ error = NULL;
+ }
+ } else {
BT_VALUE_PUT_REF_AND_RESET(result);
PyErr_NoMemory();
}
+
+
}
auto_source_discovery_fini(&auto_disc);
bt_value_put_ref(components_list);
bt_value_put_ref(component_info);
+ if (error) {
+ bt_error_release(error);
+ }
+
return result;
}
_BT_TESTS_DATADIR, 'auto-source-discovery', 'params-log-level'
)
+_METADATA_SYNTAX_ERROR_TRACE_PATH = os.path.join(
+ _BT_CTF_TRACES_PATH, "fail", "metadata-syntax-error"
+)
+
class _SomeSource(
bt2._UserSourceComponent, message_iterator_class=bt2._UserMessageIterator
self.assertEqual(msgs[1].stream.name, "TestSourceB: deore")
+class TestAutoDiscoverFailures(unittest.TestCase):
+ def test_metadata_syntax_error(self):
+ with self.assertRaisesRegex(
+ bt2._Error,
+ 'Component class\'s "query" method failed',
+ ):
+ specs = [bt2.AutoSourceComponentSpec(_METADATA_SYNTAX_ERROR_TRACE_PATH)]
+ bt2.TraceCollectionMessageIterator(specs)
+
+
if __name__ == '__main__':
unittest.main()