Fix non-matching packet context wrt last packet event read
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 11 Aug 2011 20:38:04 +0000 (16:38 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 11 Aug 2011 20:38:04 +0000 (16:38 -0400)
The last event in a packet is seen with the timestamp of the beginning
of the next packet due to an incorrect handling of ctf_move_pos() : the
"ctf_move_pos_slow" that switches between packets needs to be called at
the next event, rather than at the end of the last event of the packet.
When the position was getting to the end of the payload of the last
event, it was immediately changing packet, which changed all packet
context information, including the current timestamp.

This is fixed by explicitely calling the ctf_move_pos_slow() on packet
boundaries at the beginning of event read rather than at each
ctf_move_pos call.

We also fix handling of empty trace packets here: when an empty packet
is detected, we need to move on to the next packet immediately within
ctf_move_pos_slow() rather than let the caller think there is some event
data in the empty packet.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
formats/ctf/ctf.c
include/babeltrace/ctf/types.h

index 23a2179bbf19851bb4685143df0c3301a4e2959d..f078735c3ea9fd5307c46333b28b2c473867a7e1 100644 (file)
@@ -125,8 +125,11 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream *stream)
        uint64_t id = 0;
        int ret;
 
+       ctf_pos_get_event(pos);
+
        if (pos->offset == EOF)
                return EOF;
+       assert(pos->offset < pos->content_size);
 
        /* Read event header */
        if (stream->stream_event_header) {
@@ -390,8 +393,11 @@ void ctf_move_pos_slow(struct ctf_stream_pos *pos, size_t offset, int whence)
                assert(off >= 0);
                pos->offset = 0;
        } else {
+       read_next_packet:
                switch (whence) {
                case SEEK_CUR:
+                       if (pos->offset == EOF)
+                               return;
                        /* The reader will expect us to skip padding */
                        assert(pos->offset + offset == pos->content_size);
                        ++pos->cur_index;
@@ -415,8 +421,13 @@ void ctf_move_pos_slow(struct ctf_stream_pos *pos, size_t offset, int whence)
                file_stream->parent.timestamp = index->timestamp_begin;
                pos->content_size = index->content_size;
                pos->packet_size = index->packet_size;
-               if (index->data_offset <= index->content_size) {
+               if (index->data_offset < index->content_size) {
                        pos->offset = 0;        /* will read headers */
+               } else if (index->data_offset == index->content_size) {
+                       /* empty packet */
+                       pos->offset = index->data_offset;
+                       offset = 0;
+                       goto read_next_packet;
                } else {
                        pos->offset = EOF;
                        return;
index c5912714f903f6f96681ae99b2696cfc8a482454..8d57ec74249108b983a6ce294b243529b235c865 100644 (file)
@@ -101,10 +101,14 @@ void ctf_move_pos(struct ctf_stream_pos *pos, size_t bit_offset)
                return;
 
        if (pos->fd >= 0) {
-               if (((pos->prot == PROT_READ)
-                     && (pos->offset + bit_offset >= pos->content_size))
-                   || ((pos->prot == PROT_WRITE)
-                     && (pos->offset + bit_offset >= pos->packet_size))) {
+               /*
+                * PROT_READ ctf_move_pos_slow is called from within
+                * ctf_pos_get_event so end of packet does not change
+                * the packet context on for the last event of the
+                * packet.
+                */
+               if ((pos->prot == PROT_WRITE)
+                       && (pos->offset + bit_offset >= pos->packet_size)) {
                        printf_debug("ctf_move_pos_slow (before call): %zd\n",
                                     pos->offset);
                        ctf_move_pos_slow(pos, bit_offset, SEEK_CUR);
@@ -172,4 +176,21 @@ int ctf_pos_access_ok(struct ctf_stream_pos *pos, size_t bit_len)
        return 1;
 }
 
+/*
+ * Update the stream position for to the current event. This moves to
+ * the next packet if we are located at the end of the current packet.
+ */
+static inline
+void ctf_pos_get_event(struct ctf_stream_pos *pos)
+{
+       assert(pos->offset <= pos->content_size);
+       if (pos->offset == pos->content_size) {
+               printf_debug("ctf_move_pos_slow (before call): %zd\n",
+                            pos->offset);
+               ctf_move_pos_slow(pos, 0, SEEK_CUR);
+               printf_debug("ctf_move_pos_slow (after call): %zd\n",
+                            pos->offset);
+       }
+}
+
 #endif /* _BABELTRACE_CTF_TYPES_H */
This page took 0.025981 seconds and 4 git commands to generate.