#define BT_COMP_LOG_SELF_COMP (notit->self_comp)
#define BT_LOG_OUTPUT_LEVEL (notit->log_level)
#define BT_LOG_TAG "PLUGIN/CTF/MSG-ITER"
-#include "plugins/comp-logging.h"
+#include "logging/comp-logging.h"
#include <stdint.h>
#include <inttypes.h>
/* State */
enum state {
STATE_INIT,
+ STATE_SWITCH_PACKET,
STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN,
STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE,
STATE_AFTER_TRACE_PACKET_HEADER,
STATE_AFTER_STREAM_PACKET_CONTEXT,
STATE_CHECK_EMIT_MSG_STREAM_BEGINNING,
STATE_EMIT_MSG_STREAM_BEGINNING,
- STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING,
STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS,
STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS,
STATE_EMIT_MSG_DISCARDED_EVENTS,
STATE_SKIP_PACKET_PADDING,
STATE_EMIT_MSG_PACKET_END_MULTI,
STATE_EMIT_MSG_PACKET_END_SINGLE,
- STATE_CHECK_EMIT_MSG_STREAM_ACTIVITY_END,
- STATE_EMIT_MSG_STREAM_ACTIVITY_END,
+ STATE_CHECK_EMIT_MSG_STREAM_END,
STATE_EMIT_MSG_STREAM_END,
STATE_DONE,
};
/* Current message iterator to create messages (weak) */
bt_self_message_iterator *msg_iter;
- /*
- * True to emit stream beginning and stream activity beginning
- * messages.
- */
+ /* True to emit a stream beginning message. */
bool emit_stream_begin_msg;
- /* True to emit stream end and stream activity end messages */
+ /* True to emit a stream end message. */
bool emit_stream_end_msg;
+ /*
+ * True if library objects are unavailable during the decoding and
+ * should not be created/used.
+ */
+ bool dry_run;
+
/* True to set the stream */
bool set_stream;
{
switch (state) {
case STATE_INIT:
- return "STATE_INIT";
+ return "INIT";
+ case STATE_SWITCH_PACKET:
+ return "SWITCH_PACKET";
case STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN:
- return "STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN";
+ return "DSCOPE_TRACE_PACKET_HEADER_BEGIN";
case STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE:
- return "STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE";
+ return "DSCOPE_TRACE_PACKET_HEADER_CONTINUE";
case STATE_AFTER_TRACE_PACKET_HEADER:
- return "STATE_AFTER_TRACE_PACKET_HEADER";
+ return "AFTER_TRACE_PACKET_HEADER";
case STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN:
- return "STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN";
+ return "DSCOPE_STREAM_PACKET_CONTEXT_BEGIN";
case STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE:
- return "STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE";
+ return "DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE";
case STATE_AFTER_STREAM_PACKET_CONTEXT:
- return "STATE_AFTER_STREAM_PACKET_CONTEXT";
+ return "AFTER_STREAM_PACKET_CONTEXT";
case STATE_EMIT_MSG_STREAM_BEGINNING:
- return "STATE_EMIT_MSG_STREAM_BEGINNING";
- case STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING:
- return "STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING";
+ return "EMIT_MSG_STREAM_BEGINNING";
case STATE_EMIT_MSG_PACKET_BEGINNING:
- return "STATE_EMIT_MSG_PACKET_BEGINNING";
+ return "EMIT_MSG_PACKET_BEGINNING";
case STATE_EMIT_MSG_DISCARDED_EVENTS:
- return "STATE_EMIT_MSG_DISCARDED_EVENTS";
+ return "EMIT_MSG_DISCARDED_EVENTS";
case STATE_EMIT_MSG_DISCARDED_PACKETS:
- return "STATE_EMIT_MSG_DISCARDED_PACKETS";
+ return "EMIT_MSG_DISCARDED_PACKETS";
case STATE_DSCOPE_EVENT_HEADER_BEGIN:
- return "STATE_DSCOPE_EVENT_HEADER_BEGIN";
+ return "DSCOPE_EVENT_HEADER_BEGIN";
case STATE_DSCOPE_EVENT_HEADER_CONTINUE:
- return "STATE_DSCOPE_EVENT_HEADER_CONTINUE";
+ return "DSCOPE_EVENT_HEADER_CONTINUE";
case STATE_AFTER_EVENT_HEADER:
- return "STATE_AFTER_EVENT_HEADER";
+ return "AFTER_EVENT_HEADER";
case STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN:
- return "STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN";
+ return "DSCOPE_EVENT_COMMON_CONTEXT_BEGIN";
case STATE_DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE:
- return "STATE_DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE";
+ return "DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE";
case STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN:
- return "STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN";
+ return "DSCOPE_EVENT_SPEC_CONTEXT_BEGIN";
case STATE_DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE:
- return "STATE_DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE";
+ return "DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE";
case STATE_DSCOPE_EVENT_PAYLOAD_BEGIN:
- return "STATE_DSCOPE_EVENT_PAYLOAD_BEGIN";
+ return "DSCOPE_EVENT_PAYLOAD_BEGIN";
case STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE:
- return "STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE";
+ return "DSCOPE_EVENT_PAYLOAD_CONTINUE";
case STATE_EMIT_MSG_EVENT:
- return "STATE_EMIT_MSG_EVENT";
+ return "EMIT_MSG_EVENT";
case STATE_SKIP_PACKET_PADDING:
- return "STATE_SKIP_PACKET_PADDING";
+ return "SKIP_PACKET_PADDING";
case STATE_EMIT_MSG_PACKET_END_MULTI:
- return "STATE_EMIT_MSG_PACKET_END_MULTI";
+ return "EMIT_MSG_PACKET_END_MULTI";
case STATE_EMIT_MSG_PACKET_END_SINGLE:
- return "STATE_EMIT_MSG_PACKET_END_SINGLE";
- case STATE_EMIT_MSG_STREAM_ACTIVITY_END:
- return "STATE_EMIT_MSG_STREAM_ACTIVITY_END";
+ return "EMIT_MSG_PACKET_END_SINGLE";
case STATE_EMIT_MSG_STREAM_END:
- return "STATE_EMIT_MSG_STREAM_END";
+ return "EMIT_MSG_STREAM_END";
case STATE_DONE:
- return "STATE_DONE";
+ return "DONE";
default:
return "(unknown)";
}
}
-static
-int bt_msg_iter_switch_packet(struct bt_msg_iter *notit);
-
static
struct stack *stack_new(struct bt_msg_iter *notit)
{
BT_ASSERT(stack);
notit = stack->notit;
BT_ASSERT(base);
- BT_COMP_LOGV("Pushing base field on stack: stack-addr=%p, "
+ BT_COMP_LOGT("Pushing base field on stack: stack-addr=%p, "
"stack-size-before=%zu, stack-size-after=%zu",
stack, stack->size, stack->size + 1);
BT_ASSERT(stack);
BT_ASSERT(stack_size(stack));
notit = stack->notit;
- BT_COMP_LOGV("Popping from stack: "
+ BT_COMP_LOGT("Popping from stack: "
"stack-addr=%p, stack-size-before=%zu, stack-size-after=%zu",
stack, stack->size, stack->size - 1);
stack->size--;
static inline
void buf_consume_bits(struct bt_msg_iter *notit, size_t incr)
{
- BT_COMP_LOGV("Advancing cursor: notit-addr=%p, cur-before=%zu, cur-after=%zu",
+ BT_COMP_LOGT("Advancing cursor: notit-addr=%p, cur-before=%zu, cur-after=%zu",
notit, notit->buf.at, notit->buf.at + incr);
notit->buf.at += incr;
}
size_t consumed_bits;
notit->cur_dscope_field = dscope_field;
- BT_COMP_LOGV("Starting BFCR: notit-addr=%p, bfcr-addr=%p, fc-addr=%p",
+ BT_COMP_LOGT("Starting BFCR: notit-addr=%p, bfcr-addr=%p, fc-addr=%p",
notit, notit->bfcr, dscope_fc);
consumed_bits = bt_bfcr_start(notit->bfcr, dscope_fc,
notit->buf.addr, notit->buf.at, packet_at(notit),
notit->buf.sz, &bfcr_status);
- BT_COMP_LOGV("BFCR consumed bits: size=%zu", consumed_bits);
+ BT_COMP_LOGT("BFCR consumed bits: size=%zu", consumed_bits);
switch (bfcr_status) {
case BT_BFCR_STATUS_OK:
/* Field class was read completely */
- BT_COMP_LOGV_STR("Field was completely decoded.");
+ BT_COMP_LOGT_STR("Field was completely decoded.");
notit->state = done_state;
break;
case BT_BFCR_STATUS_EOF:
- BT_COMP_LOGV_STR("BFCR needs more data to decode field completely.");
+ BT_COMP_LOGT_STR("BFCR needs more data to decode field completely.");
notit->state = continue_state;
break;
default:
enum bt_bfcr_status bfcr_status;
size_t consumed_bits;
- BT_COMP_LOGV("Continuing BFCR: notit-addr=%p, bfcr-addr=%p",
+ BT_COMP_LOGT("Continuing BFCR: notit-addr=%p, bfcr-addr=%p",
notit, notit->bfcr);
status = buf_ensure_available_bits(notit);
"msg-addr=%p, status=%s",
notit, bt_msg_iter_status_string(status));
} else {
- BT_COMP_LOGV("Cannot ensure that buffer has at least one byte: "
+ BT_COMP_LOGT("Cannot ensure that buffer has at least one byte: "
"msg-addr=%p, status=%s",
notit, bt_msg_iter_status_string(status));
}
consumed_bits = bt_bfcr_continue(notit->bfcr, notit->buf.addr,
notit->buf.sz, &bfcr_status);
- BT_COMP_LOGV("BFCR consumed bits: size=%zu", consumed_bits);
+ BT_COMP_LOGT("BFCR consumed bits: size=%zu", consumed_bits);
switch (bfcr_status) {
case BT_BFCR_STATUS_OK:
/* Type was read completely. */
- BT_COMP_LOGV_STR("Field was completely decoded.");
+ BT_COMP_LOGT_STR("Field was completely decoded.");
notit->state = done_state;
break;
case BT_BFCR_STATUS_EOF:
/* Stay in this continue state. */
- BT_COMP_LOGV_STR("BFCR needs more data to decode field completely.");
+ BT_COMP_LOGT_STR("BFCR needs more data to decode field completely.");
break;
default:
BT_COMP_LOGW("BFCR failed to continue: notit-addr=%p, bfcr-addr=%p, "
release_event_dscopes(notit);
}
+static
+enum bt_msg_iter_status switch_packet_state(struct bt_msg_iter *notit)
+{
+ enum bt_msg_iter_status status = BT_MSG_ITER_STATUS_OK;
+
+ /*
+ * We don't put the stream class here because we need to make
+ * sure that all the packets processed by the same message
+ * iterator refer to the same stream class (the first one).
+ */
+ BT_ASSERT(notit);
+
+ if (notit->cur_exp_packet_total_size != -1) {
+ notit->cur_packet_offset += notit->cur_exp_packet_total_size;
+ }
+
+ BT_COMP_LOGD("Switching packet: notit-addr=%p, cur=%zu, "
+ "packet-offset=%" PRId64, notit, notit->buf.at,
+ notit->cur_packet_offset);
+ stack_clear(notit->stack);
+ notit->meta.ec = NULL;
+ BT_PACKET_PUT_REF_AND_RESET(notit->packet);
+ BT_MESSAGE_PUT_REF_AND_RESET(notit->event_msg);
+ release_all_dscopes(notit);
+ notit->cur_dscope_field = NULL;
+
+ /*
+ * Adjust current buffer so that addr points to the beginning of the new
+ * packet.
+ */
+ if (notit->buf.addr) {
+ size_t consumed_bytes = (size_t) (notit->buf.at / CHAR_BIT);
+
+ /* Packets are assumed to start on a byte frontier. */
+ if (notit->buf.at % CHAR_BIT) {
+ BT_COMP_LOGW("Cannot switch packet: current position is not a multiple of 8: "
+ "notit-addr=%p, cur=%zu", notit, notit->buf.at);
+ status = BT_MSG_ITER_STATUS_ERROR;
+ goto end;
+ }
+
+ notit->buf.addr += consumed_bytes;
+ notit->buf.sz -= consumed_bytes;
+ notit->buf.at = 0;
+ notit->buf.packet_offset = 0;
+ BT_COMP_LOGD("Adjusted buffer: addr=%p, size=%zu",
+ notit->buf.addr, notit->buf.sz);
+ }
+
+ notit->cur_exp_packet_content_size = -1;
+ notit->cur_exp_packet_total_size = -1;
+ notit->cur_stream_class_id = -1;
+ notit->cur_event_class_id = -1;
+ notit->cur_data_stream_id = -1;
+ notit->prev_packet_snapshots = notit->snapshots;
+ notit->snapshots.discarded_events = UINT64_C(-1);
+ notit->snapshots.packets = UINT64_C(-1);
+ notit->snapshots.beginning_clock = UINT64_C(-1);
+ notit->snapshots.end_clock = UINT64_C(-1);
+ notit->state = STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN;
+
+end:
+ return status;
+}
+
static
enum bt_msg_iter_status read_packet_header_begin_state(
struct bt_msg_iter *notit)
struct ctf_field_class *packet_header_fc = NULL;
enum bt_msg_iter_status ret = BT_MSG_ITER_STATUS_OK;
- if (bt_msg_iter_switch_packet(notit)) {
- BT_COMP_LOGW("Cannot switch packet: notit-addr=%p", notit);
- ret = BT_MSG_ITER_STATUS_ERROR;
- goto end;
- }
-
/*
* Make sure at least one bit is available for this packet. An
* empty packet is impossible. If we reach the end of the medium
break;
case BT_MSG_ITER_STATUS_EOF:
ret = BT_MSG_ITER_STATUS_OK;
- notit->state = STATE_CHECK_EMIT_MSG_STREAM_ACTIVITY_END;
+ notit->state = STATE_CHECK_EMIT_MSG_STREAM_END;
goto end;
default:
goto end;
BT_ASSERT(!notit->packet_context_field);
- if (packet_context_fc->in_ir) {
+ if (packet_context_fc->in_ir && !notit->dry_run) {
/*
* Create free packet context field from stream class.
* This field is going to be moved to the packet once we
BT_ASSERT(notit->meta.sc);
if (bt_stream_class_borrow_default_clock_class(notit->meta.sc->ir_sc)) {
- msg = bt_message_event_create_with_default_clock_snapshot(
+ msg = bt_message_event_create_with_packet_and_default_clock_snapshot(
notit->msg_iter, notit->meta.ec->ir_ec,
notit->packet, notit->default_clock_snapshot);
} else {
- msg = bt_message_event_create(notit->msg_iter,
+ msg = bt_message_event_create_with_packet(notit->msg_iter,
notit->meta.ec->ir_ec, notit->packet);
}
goto end;
}
+ if (G_UNLIKELY(notit->dry_run)) {
+ goto next_state;
+ }
+
status = set_current_event_message(notit);
if (status != BT_MSG_ITER_STATUS_OK) {
goto end;
notit->event = bt_message_event_borrow_event(
notit->event_msg);
BT_ASSERT(notit->event);
+
+next_state:
notit->state = STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN;
end:
goto end;
}
- if (event_common_context_fc->in_ir) {
+ if (event_common_context_fc->in_ir && !notit->dry_run) {
BT_ASSERT(!notit->dscopes.event_common_context);
notit->dscopes.event_common_context =
bt_event_borrow_common_context_field(
BT_ASSERT(notit->dscopes.event_common_context);
}
- BT_COMP_LOGV("Decoding event common context field: "
+ BT_COMP_LOGT("Decoding event common context field: "
"notit-addr=%p, stream-class-addr=%p, "
"stream-class-id=%" PRId64 ", "
"fc-addr=%p",
goto end;
}
- if (event_spec_context_fc->in_ir) {
+ if (event_spec_context_fc->in_ir && !notit->dry_run) {
BT_ASSERT(!notit->dscopes.event_spec_context);
notit->dscopes.event_spec_context =
bt_event_borrow_specific_context_field(
BT_ASSERT(notit->dscopes.event_spec_context);
}
- BT_COMP_LOGV("Decoding event specific context field: "
+ BT_COMP_LOGT("Decoding event specific context field: "
"notit-addr=%p, event-class-addr=%p, "
"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
"fc-addr=%p",
goto end;
}
- if (event_payload_fc->in_ir) {
+ if (event_payload_fc->in_ir && !notit->dry_run) {
BT_ASSERT(!notit->dscopes.event_payload);
notit->dscopes.event_payload =
bt_event_borrow_payload_field(
BT_ASSERT(notit->dscopes.event_payload);
}
- BT_COMP_LOGV("Decoding event payload field: "
+ BT_COMP_LOGT("Decoding event payload field: "
"notit-addr=%p, event-class-addr=%p, "
"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
"fc-addr=%p",
{
enum bt_msg_iter_status status = BT_MSG_ITER_STATUS_OK;
size_t bits_to_skip;
+ const enum state next_state = STATE_SWITCH_PACKET;
BT_ASSERT(notit->cur_exp_packet_total_size > 0);
bits_to_skip = notit->cur_exp_packet_total_size - packet_at(notit);
if (bits_to_skip == 0) {
- notit->state = STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN;
+ notit->state = next_state;
goto end;
} else {
size_t bits_to_consume;
bits_to_skip = notit->cur_exp_packet_total_size -
packet_at(notit);
if (bits_to_skip == 0) {
- notit->state = STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN;
+ notit->state = next_state;
goto end;
}
}
}
static
-enum bt_msg_iter_status check_emit_msg_stream_activity_end(
+enum bt_msg_iter_status check_emit_msg_stream_end(
struct bt_msg_iter *notit)
{
if (notit->emit_stream_end_msg) {
- notit->state = STATE_EMIT_MSG_STREAM_ACTIVITY_END;
+ notit->state = STATE_EMIT_MSG_STREAM_END;
} else {
notit->state = STATE_DONE;
}
enum bt_msg_iter_status status = BT_MSG_ITER_STATUS_OK;
const enum state state = notit->state;
- BT_COMP_LOGV("Handling state: notit-addr=%p, state=%s",
+ BT_COMP_LOGT("Handling state: notit-addr=%p, state=%s",
notit, state_string(state));
// TODO: optimalize!
switch (state) {
case STATE_INIT:
- notit->state = STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN;
+ notit->state = STATE_SWITCH_PACKET;
+ break;
+ case STATE_SWITCH_PACKET:
+ status = switch_packet_state(notit);
break;
case STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN:
status = read_packet_header_begin_state(notit);
status = check_emit_msg_stream_beginning_state(notit);
break;
case STATE_EMIT_MSG_STREAM_BEGINNING:
- notit->state = STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING;
- break;
- case STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING:
notit->state = STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS;
break;
case STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS:
notit->state = STATE_SKIP_PACKET_PADDING;
break;
case STATE_EMIT_MSG_PACKET_END_SINGLE:
- notit->state = STATE_CHECK_EMIT_MSG_STREAM_ACTIVITY_END;
+ notit->state = STATE_CHECK_EMIT_MSG_STREAM_END;
break;
- case STATE_CHECK_EMIT_MSG_STREAM_ACTIVITY_END:
- status = check_emit_msg_stream_activity_end(notit);
- break;
- case STATE_EMIT_MSG_STREAM_ACTIVITY_END:
- notit->state = STATE_EMIT_MSG_STREAM_END;
+ case STATE_CHECK_EMIT_MSG_STREAM_END:
+ status = check_emit_msg_stream_end(notit);
break;
case STATE_EMIT_MSG_STREAM_END:
notit->state = STATE_DONE;
abort();
}
- BT_COMP_LOGV("Handled state: notit-addr=%p, status=%s, "
+ BT_COMP_LOGT("Handled state: notit-addr=%p, status=%s, "
"prev-state=%s, cur-state=%s",
notit, bt_msg_iter_status_string(status),
state_string(state), state_string(notit->state));
bt_msg_iter_reset_for_next_stream_file(notit);
notit->cur_stream_class_id = -1;
notit->cur_data_stream_id = -1;
- notit->emit_stream_begin_msg = true;
- notit->emit_stream_end_msg = true;
notit->snapshots.discarded_events = UINT64_C(-1);
notit->snapshots.packets = UINT64_C(-1);
notit->prev_packet_snapshots.discarded_events = UINT64_C(-1);
notit->prev_packet_snapshots.end_clock = UINT64_C(-1);
}
-static
-int bt_msg_iter_switch_packet(struct bt_msg_iter *notit)
-{
- int ret = 0;
-
- /*
- * We don't put the stream class here because we need to make
- * sure that all the packets processed by the same message
- * iterator refer to the same stream class (the first one).
- */
- BT_ASSERT(notit);
-
- if (notit->cur_exp_packet_total_size != -1) {
- notit->cur_packet_offset += notit->cur_exp_packet_total_size;
- }
-
- BT_COMP_LOGD("Switching packet: notit-addr=%p, cur=%zu, "
- "packet-offset=%" PRId64, notit, notit->buf.at,
- notit->cur_packet_offset);
- stack_clear(notit->stack);
- notit->meta.ec = NULL;
- BT_PACKET_PUT_REF_AND_RESET(notit->packet);
- BT_MESSAGE_PUT_REF_AND_RESET(notit->event_msg);
- release_all_dscopes(notit);
- notit->cur_dscope_field = NULL;
-
- /*
- * Adjust current buffer so that addr points to the beginning of the new
- * packet.
- */
- if (notit->buf.addr) {
- size_t consumed_bytes = (size_t) (notit->buf.at / CHAR_BIT);
-
- /* Packets are assumed to start on a byte frontier. */
- if (notit->buf.at % CHAR_BIT) {
- BT_COMP_LOGW("Cannot switch packet: current position is not a multiple of 8: "
- "notit-addr=%p, cur=%zu", notit, notit->buf.at);
- ret = -1;
- goto end;
- }
-
- notit->buf.addr += consumed_bytes;
- notit->buf.sz -= consumed_bytes;
- notit->buf.at = 0;
- notit->buf.packet_offset = 0;
- BT_COMP_LOGD("Adjusted buffer: addr=%p, size=%zu",
- notit->buf.addr, notit->buf.sz);
- }
-
- notit->cur_exp_packet_content_size = -1;
- notit->cur_exp_packet_total_size = -1;
- notit->cur_stream_class_id = -1;
- notit->cur_event_class_id = -1;
- notit->cur_data_stream_id = -1;
- notit->prev_packet_snapshots = notit->snapshots;
- notit->snapshots.discarded_events = UINT64_C(-1);
- notit->snapshots.packets = UINT64_C(-1);
- notit->snapshots.beginning_clock = UINT64_C(-1);
- notit->snapshots.end_clock = UINT64_C(-1);
-
-end:
- return ret;
-}
-
static
bt_field *borrow_next_field(struct bt_msg_iter *notit)
{
next_field = bt_field_array_borrow_element_field_by_index(
base_field, index);
break;
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
+ case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
+ case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR:
BT_ASSERT(index == 0);
next_field = bt_field_variant_borrow_selected_option_field(
base_field);
notit->default_clock_snapshot |= new_val;
end:
- BT_COMP_LOGV("Updated default clock's value from integer field's value: "
+ BT_COMP_LOGT("Updated default clock's value from integer field's value: "
"value=%" PRIu64, notit->default_clock_snapshot);
}
bt_field *field = NULL;
struct ctf_field_class_int *int_fc = (void *) fc;
- BT_COMP_LOGV("Unsigned integer function called from BFCR: "
+ BT_COMP_LOGT("Unsigned integer function called from BFCR: "
"notit-addr=%p, bfcr-addr=%p, fc-addr=%p, "
"fc-type=%d, fc-in-ir=%d, value=%" PRIu64,
notit, notit->bfcr, fc, fc->type, fc->in_ir, value);
(uint64_t) int_fc->storing_index) = value;
}
- if (G_UNLIKELY(!fc->in_ir)) {
+ if (G_UNLIKELY(!fc->in_ir || notit->dry_run)) {
goto end;
}
BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER ||
bt_field_get_class_type(field) ==
BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION);
- bt_field_unsigned_integer_set_value(field, value);
+ bt_field_integer_unsigned_set_value(field, value);
stack_top(notit->stack)->index++;
end:
struct ctf_field_class_int *int_fc = (void *) fc;
char str[2] = {'\0', '\0'};
- BT_COMP_LOGV("Unsigned integer character function called from BFCR: "
+ BT_COMP_LOGT("Unsigned integer character function called from BFCR: "
"notit-addr=%p, bfcr-addr=%p, fc-addr=%p, "
"fc-type=%d, fc-in-ir=%d, value=%" PRIu64,
notit, notit->bfcr, fc, fc->type, fc->in_ir, value);
BT_ASSERT(!int_fc->mapped_clock_class);
BT_ASSERT(int_fc->storing_index < 0);
- if (G_UNLIKELY(!fc->in_ir)) {
+ if (G_UNLIKELY(!fc->in_ir || notit->dry_run)) {
goto end;
}
struct bt_msg_iter *notit = data;
struct ctf_field_class_int *int_fc = (void *) fc;
- BT_COMP_LOGV("Signed integer function called from BFCR: "
+ BT_COMP_LOGT("Signed integer function called from BFCR: "
"notit-addr=%p, bfcr-addr=%p, fc-addr=%p, "
"fc-type=%d, fc-in-ir=%d, value=%" PRId64,
notit, notit->bfcr, fc, fc->type, fc->in_ir, value);
(uint64_t) int_fc->storing_index) = (uint64_t) value;
}
- if (G_UNLIKELY(!fc->in_ir)) {
+ if (G_UNLIKELY(!fc->in_ir || notit->dry_run)) {
goto end;
}
BT_FIELD_CLASS_TYPE_SIGNED_INTEGER ||
bt_field_get_class_type(field) ==
BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION);
- bt_field_signed_integer_set_value(field, value);
+ bt_field_integer_signed_set_value(field, value);
stack_top(notit->stack)->index++;
end:
bt_field *field = NULL;
struct bt_msg_iter *notit = data;
- BT_COMP_LOGV("Floating point number function called from BFCR: "
+ BT_COMP_LOGT("Floating point number function called from BFCR: "
"notit-addr=%p, bfcr-addr=%p, fc-addr=%p, "
"fc-type=%d, fc-in-ir=%d, value=%f",
notit, notit->bfcr, fc, fc->type, fc->in_ir, value);
- if (G_UNLIKELY(!fc->in_ir)) {
+ if (G_UNLIKELY(!fc->in_ir || notit->dry_run)) {
goto end;
}
{
bt_field *field = NULL;
struct bt_msg_iter *notit = data;
- int ret;
- BT_COMP_LOGV("String (beginning) function called from BFCR: "
+ BT_COMP_LOGT("String (beginning) function called from BFCR: "
"notit-addr=%p, bfcr-addr=%p, fc-addr=%p, "
"fc-type=%d, fc-in-ir=%d",
notit, notit->bfcr, fc, fc->type, fc->in_ir);
- if (G_UNLIKELY(!fc->in_ir)) {
+ if (G_UNLIKELY(!fc->in_ir || notit->dry_run)) {
goto end;
}
BT_ASSERT(bt_field_borrow_class_const(field) == fc->ir_fc);
BT_ASSERT(bt_field_get_class_type(field) ==
BT_FIELD_CLASS_TYPE_STRING);
- ret = bt_field_string_clear(field);
- BT_ASSERT(ret == 0);
+ bt_field_string_clear(field);
/*
* Push on stack. Not a compound class per se, but we know that
struct bt_msg_iter *notit = data;
int ret;
- BT_COMP_LOGV("String (substring) function called from BFCR: "
+ BT_COMP_LOGT("String (substring) function called from BFCR: "
"notit-addr=%p, bfcr-addr=%p, fc-addr=%p, "
"fc-type=%d, fc-in-ir=%d, string-length=%zu",
notit, notit->bfcr, fc, fc->type, fc->in_ir,
len);
- if (G_UNLIKELY(!fc->in_ir)) {
+ if (G_UNLIKELY(!fc->in_ir || notit->dry_run)) {
goto end;
}
{
struct bt_msg_iter *notit = data;
- BT_COMP_LOGV("String (end) function called from BFCR: "
+ BT_COMP_LOGT("String (end) function called from BFCR: "
"notit-addr=%p, bfcr-addr=%p, fc-addr=%p, "
"fc-type=%d, fc-in-ir=%d",
notit, notit->bfcr, fc, fc->type, fc->in_ir);
- if (G_UNLIKELY(!fc->in_ir)) {
+ if (G_UNLIKELY(!fc->in_ir || notit->dry_run)) {
goto end;
}
struct bt_msg_iter *notit = data;
bt_field *field;
- BT_COMP_LOGV("Compound (beginning) function called from BFCR: "
+ BT_COMP_LOGT("Compound (beginning) function called from BFCR: "
"notit-addr=%p, bfcr-addr=%p, fc-addr=%p, "
"fc-type=%d, fc-in-ir=%d",
notit, notit->bfcr, fc, fc->type, fc->in_ir);
- if (!fc->in_ir) {
+ if (G_UNLIKELY(!fc->in_ir || notit->dry_run)) {
goto end;
}
struct ctf_field_class_array_base *array_fc = (void *) fc;
if (array_fc->is_text) {
- int ret;
-
BT_ASSERT(bt_field_get_class_type(field) ==
BT_FIELD_CLASS_TYPE_STRING);
notit->done_filling_string = false;
- ret = bt_field_string_clear(field);
- BT_ASSERT(ret == 0);
+ bt_field_string_clear(field);
bt_bfcr_set_unsigned_int_cb(notit->bfcr,
bfcr_unsigned_int_char_cb);
}
{
struct bt_msg_iter *notit = data;
- BT_COMP_LOGV("Compound (end) function called from BFCR: "
+ BT_COMP_LOGT("Compound (end) function called from BFCR: "
"notit-addr=%p, bfcr-addr=%p, fc-addr=%p, "
"fc-type=%d, fc-in-ir=%d",
notit, notit->bfcr, fc, fc->type, fc->in_ir);
- if (!fc->in_ir) {
+ if (G_UNLIKELY(!fc->in_ir || notit->dry_run)) {
goto end;
}
length = (uint64_t) g_array_index(notit->stored_values, uint64_t,
seq_fc->stored_length_index);
+
+ if (G_UNLIKELY(notit->dry_run)){
+ goto end;
+ }
+
seq_field = stack_top(notit->stack)->base;
BT_ASSERT(seq_field);
if (!seq_fc->base.is_text) {
BT_ASSERT(bt_field_get_class_type(seq_field) ==
BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY);
- ret = bt_field_dynamic_array_set_length(seq_field,
+ ret = bt_field_array_dynamic_set_length(seq_field,
(uint64_t) length);
if (ret) {
BT_COMP_LOGE("Cannot set dynamic array field's length field: "
}
}
+end:
return length;
}
selected_option = ctf_field_class_variant_borrow_option_by_index(
var_fc, (uint64_t) option_index);
- if (selected_option->fc->in_ir) {
+ if (selected_option->fc->in_ir && !notit->dry_run) {
bt_field *var_field = stack_top(notit->stack)->base;
- ret = bt_field_variant_select_option_field(
+ ret = bt_field_variant_select_option_field_by_index(
var_field, option_index);
if (ret) {
BT_COMP_LOGW("Cannot select variant field's option field: "
*message = ret;
}
-static
-void create_msg_stream_activity_beginning(struct bt_msg_iter *notit,
- bt_message **message)
-{
- bt_message *ret = NULL;
-
- BT_ASSERT(notit->stream);
- BT_ASSERT(notit->msg_iter);
- ret = bt_message_stream_activity_beginning_create(notit->msg_iter,
- notit->stream);
- if (!ret) {
- BT_COMP_LOGE("Cannot create stream activity beginning message: "
- "notit-addr=%p, stream-addr=%p",
- notit, notit->stream);
- return;
- }
-
- *message = ret;
-}
-
-static
-void create_msg_stream_activity_end(struct bt_msg_iter *notit,
- bt_message **message)
-{
- bt_message *ret = NULL;
-
- if (!notit->stream) {
- BT_COMP_LOGE("Cannot create stream for stream message: "
- "notit-addr=%p", notit);
- return;
- }
-
- BT_ASSERT(notit->stream);
- BT_ASSERT(notit->msg_iter);
- ret = bt_message_stream_activity_end_create(notit->msg_iter,
- notit->stream);
- if (!ret) {
- BT_COMP_LOGE("Cannot create stream activity end message: "
- "notit-addr=%p, stream-addr=%p",
- notit, notit->stream);
- return;
- }
-
- *message = ret;
-}
-
static
void create_msg_stream_end(struct bt_msg_iter *notit, bt_message **message)
{
void create_msg_packet_end(struct bt_msg_iter *notit, bt_message **message)
{
bt_message *msg;
+ bool update_default_cs = true;
if (!notit->packet) {
return;
}
- /* Update default clock from packet's end time */
- if (notit->snapshots.end_clock != UINT64_C(-1)) {
+ /* Check if may be affected by lttng-crash timestamp_end quirk. */
+ if (G_UNLIKELY(notit->meta.tc->quirks.lttng_crash)) {
+ /*
+ * Check if the `timestamp_begin` field is non-zero but
+ * `timestamp_end` is zero. It means the trace is affected by
+ * the lttng-crash packet `timestamp_end` quirk and must be
+ * fixed up by omitting to update the default clock snapshot to
+ * the `timestamp_end` as is typically done.
+ */
+ if (notit->snapshots.beginning_clock != 0 &&
+ notit->snapshots.end_clock == 0) {
+ update_default_cs = false;
+ }
+ }
+
+ /*
+ * Check if may be affected by lttng event-after-packet `timestamp_end`
+ * quirk.
+ */
+ if (notit->meta.tc->quirks.lttng_event_after_packet) {
+ /*
+ * Check if `timestamp_end` is smaller then the current
+ * default_clock_snapshot (which is set to the last event
+ * decoded). It means the trace is affected by the lttng
+ * `event-after-packet` packet `timestamp_end` quirk and must
+ * be fixed up by omitting to update the default clock snapshot
+ * to the `timestamp_end` as is typically done.
+ */
+ if (notit->snapshots.end_clock < notit->default_clock_snapshot) {
+ update_default_cs = false;
+ }
+ }
+
+ /* Update default clock from packet's end time. */
+ if (notit->snapshots.end_clock != UINT64_C(-1) && update_default_cs) {
notit->default_clock_snapshot = notit->snapshots.end_clock;
}
BT_ASSERT(notit->snapshots.end_clock != UINT64_C(-1));
msg = bt_message_packet_end_create_with_default_clock_snapshot(
notit->msg_iter, notit->packet,
- notit->snapshots.end_clock);
+ notit->default_clock_snapshot);
} else {
msg = bt_message_packet_end_create(notit->msg_iter,
notit->packet);
status = BT_MSG_ITER_STATUS_ERROR;
}
- goto end;
- case STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING:
- /* create_msg_stream_activity_beginning() logs errors */
- create_msg_stream_activity_beginning(notit, message);
-
- if (!*message) {
- status = BT_MSG_ITER_STATUS_ERROR;
- }
-
- goto end;
- case STATE_EMIT_MSG_STREAM_ACTIVITY_END:
- /* create_msg_stream_activity_end() logs errors */
- create_msg_stream_activity_end(notit, message);
-
- if (!*message) {
- status = BT_MSG_ITER_STATUS_ERROR;
- }
-
goto end;
case STATE_EMIT_MSG_STREAM_BEGINNING:
/* create_msg_stream_beginning() logs errors */
}
static
-enum bt_msg_iter_status read_packet_header_context_fields(
- struct bt_msg_iter *notit)
+enum bt_msg_iter_status decode_until_state( struct bt_msg_iter *notit,
+ enum state target_state_1, enum state target_state_2)
{
- int ret;
enum bt_msg_iter_status status = BT_MSG_ITER_STATUS_OK;
BT_ASSERT(notit);
notit->set_stream = false;
- if (notit->state == STATE_EMIT_MSG_PACKET_BEGINNING) {
- /* We're already there */
- goto end;
- }
+ do {
+ /*
+ * Check if we reached the state at which we want to stop
+ * decoding.
+ */
+ if (notit->state == target_state_1 ||
+ notit->state == target_state_2) {
+ goto end;
+ }
- while (true) {
status = handle_state(notit);
if (G_UNLIKELY(status == BT_MSG_ITER_STATUS_AGAIN)) {
BT_COMP_LOGD_STR("Medium returned BT_MSG_ITER_STATUS_AGAIN.");
}
switch (notit->state) {
- case STATE_EMIT_MSG_PACKET_BEGINNING:
- /*
- * Packet header and context fields are
- * potentially decoded (or they don't exist).
- */
- goto end;
case STATE_INIT:
+ case STATE_SWITCH_PACKET:
case STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN:
case STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE:
case STATE_AFTER_TRACE_PACKET_HEADER:
case STATE_AFTER_STREAM_PACKET_CONTEXT:
case STATE_CHECK_EMIT_MSG_STREAM_BEGINNING:
case STATE_EMIT_MSG_STREAM_BEGINNING:
- case STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING:
case STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS:
case STATE_EMIT_MSG_DISCARDED_EVENTS:
case STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS:
case STATE_EMIT_MSG_DISCARDED_PACKETS:
- /* Non-emitting state: continue */
+ case STATE_EMIT_MSG_PACKET_BEGINNING:
+ case STATE_DSCOPE_EVENT_HEADER_BEGIN:
+ case STATE_DSCOPE_EVENT_HEADER_CONTINUE:
+ case STATE_AFTER_EVENT_HEADER:
+ case STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN:
+ case STATE_DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE:
+ case STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN:
+ case STATE_DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE:
+ case STATE_DSCOPE_EVENT_PAYLOAD_BEGIN:
+ case STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE:
+ case STATE_EMIT_MSG_EVENT:
+ case STATE_SKIP_PACKET_PADDING:
+ case STATE_EMIT_MSG_PACKET_END_MULTI:
+ case STATE_EMIT_MSG_PACKET_END_SINGLE:
+ case STATE_CHECK_EMIT_MSG_STREAM_END:
+ case STATE_EMIT_MSG_STREAM_END:
break;
+ case STATE_DONE:
+ /* fall-through */
default:
- /*
- * We should never get past the
- * STATE_EMIT_MSG_PACKET_BEGINNING state.
- */
+ /* We should never get to the STATE_DONE state. */
BT_COMP_LOGF("Unexpected state: notit-addr=%p, state=%s",
notit, state_string(notit->state));
abort();
}
- }
+ } while (true);
end:
+ return status;
+}
+
+static
+enum bt_msg_iter_status read_packet_header_context_fields(
+ struct bt_msg_iter *notit)
+{
+ int ret;
+ enum bt_msg_iter_status status = BT_MSG_ITER_STATUS_OK;
+
+ status = decode_until_state(notit, STATE_EMIT_MSG_PACKET_BEGINNING, -1);
+ if (status != BT_MSG_ITER_STATUS_OK) {
+ goto end;
+ }
+
ret = set_current_packet_content_sizes(notit);
if (ret) {
status = BT_MSG_ITER_STATUS_ERROR;
+ goto end;
}
+end:
return status;
}
BT_ASSERT(notit);
if (offset < 0) {
- BT_COMP_LOGE("Cannot seek to negative offset: offset=%jd", offset);
+ BT_COMP_LOGE("Cannot seek to negative offset: offset=%jd", (intmax_t) offset);
ret = BT_MSG_ITER_STATUS_INVAL;
goto end;
}
return ret;
}
+static
+enum bt_msg_iter_status clock_snapshot_at_msg_iter_state(
+ struct bt_msg_iter *notit, enum state target_state_1,
+ enum state target_state_2, uint64_t *clock_snapshot)
+{
+ enum bt_msg_iter_status status = BT_MSG_ITER_STATUS_OK;
+
+ BT_ASSERT(notit);
+ BT_ASSERT(clock_snapshot);
+ status = decode_until_state(notit, target_state_1, target_state_2);
+ if (status != BT_MSG_ITER_STATUS_OK) {
+ goto end;
+ }
+
+ *clock_snapshot = notit->default_clock_snapshot;
+end:
+ return status;
+}
+
+BT_HIDDEN
+enum bt_msg_iter_status bt_msg_iter_curr_packet_first_event_clock_snapshot(
+ struct bt_msg_iter *notit, uint64_t *first_clock_snapshot)
+{
+ return clock_snapshot_at_msg_iter_state(notit,
+ STATE_AFTER_EVENT_HEADER, -1, first_clock_snapshot);
+}
+
+BT_HIDDEN
+enum bt_msg_iter_status bt_msg_iter_curr_packet_last_event_clock_snapshot(
+ struct bt_msg_iter *notit, uint64_t *last_clock_snapshot)
+{
+ return clock_snapshot_at_msg_iter_state(notit,
+ STATE_EMIT_MSG_PACKET_END_SINGLE,
+ STATE_EMIT_MSG_PACKET_END_MULTI, last_clock_snapshot);
+}
+
BT_HIDDEN
enum bt_msg_iter_status bt_msg_iter_get_packet_properties(
struct bt_msg_iter *notit,
{
notit->emit_stream_end_msg = val;
}
+
+BT_HIDDEN
+void bt_msg_iter_set_dry_run(struct bt_msg_iter *notit,
+ bool val)
+{
+ notit->dry_run = val;
+}