Propagate error from packet_seek in case of truncated packet stable-1.4
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Wed, 7 Feb 2018 22:52:05 +0000 (17:52 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 20 Feb 2018 19:15:58 +0000 (14:15 -0500)
Report the error all the way up allowing users/scripts to perform error
detection and act on it.

Print to stderr the truncated packet information for easier
identification.

Introduce bt_packet_seek_error enum for specific error handling.

Use the ERANGE errno for error propagation inside bt_iter_next and
ctf_read_event.

Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
converter/babeltrace.c
formats/ctf/ctf.c
formats/lttng-live/lttng-live-comm.c
include/babeltrace/error.h
lib/iterator.c

index 2e4003ca45807c9acf6c9d6ce0811c487c1941b6..6e6c3385f6e986fed202a297dc623ac463f28d87 100644 (file)
@@ -663,6 +663,7 @@ int convert_trace(struct bt_trace_descriptor *td_write,
        struct bt_iter_pos *begin_pos = NULL, *end_pos = NULL;
        struct bt_ctf_event *ctf_event;
        int ret;
+       int error_holder = 0;
 
        sout = container_of(td_write, struct ctf_text_stream_pos,
                        trace_descriptor);
@@ -689,11 +690,18 @@ int convert_trace(struct bt_trace_descriptor *td_write,
                        goto end;
                }
                ret = bt_iter_next(bt_ctf_get_iter(iter));
-               if (ret < 0) {
+               if (ret == -ERANGE) {
+                       /*
+                        * Remember that a range (truncated packet)
+                        * error occurred and continue.
+                        */
+                       error_holder = 1;
+                       continue;
+               } else if (ret < 0) {
                        goto end;
                }
        }
-       ret = 0;
+       ret = error_holder;
 
 end:
        bt_ctf_iter_destroy(iter);
index 5b6e3b90cf886e559b05cfb6fd1992e5805b6bef..e414af7ba9420869825fd8ba73fefc098aff1afc 100644 (file)
@@ -469,6 +469,29 @@ void ctf_print_discarded_lost(FILE *fp, struct ctf_stream_definition *stream)
        fflush(fp);
 }
 
+static
+void ctf_print_truncated_packet(FILE *fp, struct ctf_stream_definition *stream,
+               uint64_t packet_size, uint64_t remaining_file_size)
+{
+       fprintf(fp, "[error] Packet size (%" PRIu64 " bits) is larger than remaining file size (%" PRIu64 " bits) in trace with UUID \"",
+                       packet_size, remaining_file_size);
+       print_uuid(fp, stream->stream_class->trace->uuid);
+       fprintf(fp, "\"");
+
+       if (stream->stream_class->trace->parent.path[0] != '\0') {
+               fprintf(fp, ", at path: \"%s\"",
+                               stream->stream_class->trace->parent.path);
+       }
+
+       fprintf(fp, ", within stream id %" PRIu64, stream->stream_id);
+       if (stream->path[0] != '\0') {
+               fprintf(fp, ", at relative path: \"%s\"", stream->path);
+       }
+
+       fprintf(fp, ".\n");
+       fflush(fp);
+}
+
 static
 int ctf_read_event(struct bt_stream_pos *ppos, struct ctf_stream_definition *stream)
 {
@@ -483,8 +506,12 @@ int ctf_read_event(struct bt_stream_pos *ppos, struct ctf_stream_definition *str
        if (unlikely(pos->offset == EOF))
                return EOF;
 
-       if (ctf_pos_get_event(pos))
+       ret = ctf_pos_get_event(pos);
+       if (ret == -BT_PACKET_SEEK_ERROR_TRUNCATED_PACKET) {
+               return -ERANGE;
+       } else if (ret) {
                return EOF;
+       }
 
        /* save the current position as a restore point */
        pos->last_offset = pos->offset;
@@ -1053,7 +1080,7 @@ void ctf_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence)
        case SEEK_SET:  /* Fall-through */
                break;  /* OK */
        default:
-               ret = -1;
+               ret = -BT_PACKET_SEEK_ERROR;
                goto end;
        }
 
@@ -1066,7 +1093,7 @@ void ctf_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence)
                if (ret) {
                        fprintf(stderr, "[error] Unable to unmap old base: %s.\n",
                                strerror(errno));
-                       ret = -1;
+                       ret = -BT_PACKET_SEEK_ERROR;
                        goto end;
                }
                pos->base_mma = NULL;
@@ -1087,7 +1114,7 @@ void ctf_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence)
                        pos->cur_index = 0;
                        break;
                default:
-                       ret = -1;
+                       ret = -BT_PACKET_SEEK_ERROR;
                        goto end;
                }
                pos->content_size = -1U;        /* Unknown at this point */
@@ -1099,6 +1126,7 @@ void ctf_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence)
                assert(ret == 0);
                pos->offset = 0;
        } else {
+               uint64_t remaining_file_size;
        read_next_packet:
                switch (whence) {
                case SEEK_CUR:
@@ -1121,7 +1149,7 @@ void ctf_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence)
                        pos->cur_index = index;
                        break;
                default:
-                       ret = -1;
+                       ret = -BT_PACKET_SEEK_ERROR;
                        goto end;
                }
 
@@ -1170,15 +1198,19 @@ void ctf_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence)
                if (packet_index->data_offset == -1) {
                        ret = find_data_offset(pos, file_stream, packet_index);
                        if (ret < 0) {
-                               ret = -1;
+                               ret = -BT_PACKET_SEEK_ERROR;
                                goto end;
                        }
                }
 
-               if (packet_index->packet_size > ((uint64_t) pos->file_length - packet_index->offset) * CHAR_BIT) {
-                       fprintf(stderr, "[error] Packet size (%" PRIu64 " bits) is larger than remaining file size (%" PRIu64 " bits).\n",
-                               packet_index->packet_size, ((uint64_t) pos->file_length - packet_index->offset) * CHAR_BIT);
-                       ret = -1;
+               remaining_file_size = (pos->file_length - ((uint64_t) packet_index->offset)) * CHAR_BIT;
+               if (packet_index->packet_size > remaining_file_size) {
+                       fflush(stdout);
+                       ctf_print_truncated_packet(stderr, &file_stream->parent,
+                                       packet_index->packet_size,
+                                       remaining_file_size);
+                       pos->offset = EOF;
+                       ret = -BT_PACKET_SEEK_ERROR_TRUNCATED_PACKET;
                        goto end;
                }
 
index cb871a1318113e4909ba3db8ad3ceae132ed7e05..055b1c30e5b321981d3e1fa3072429d545cae8b6 100644 (file)
@@ -1223,7 +1223,7 @@ void ctf_live_packet_seek(struct bt_stream_pos *stream_pos, size_t index,
        ret = handle_seek_position(index, whence, viewer_stream, pos,
                        file_stream);
        if (ret != 0) {
-               ret = -1;
+               ret = -BT_PACKET_SEEK_ERROR;
                goto end;
        }
 
@@ -1266,7 +1266,7 @@ retry:
                        if (!lttng_live_should_quit()) {
                                fprintf(stderr, "[error] get_next_index failed\n");
                        }
-                       ret = -1;
+                       ret = -BT_PACKET_SEEK_ERROR;
                        goto end;
                }
                printf_verbose("Index received : packet_size : %" PRIu64
@@ -1389,7 +1389,7 @@ retry:
                pos->offset = EOF;
                if (!lttng_live_should_quit()) {
                        fprintf(stderr, "[error] get_data_packet failed\n");
-                       ret = -1;
+                       ret = -BT_PACKET_SEEK_ERROR;
                } else {
                        ret = 0;
                }
index 2f6a6d7c73339235211dcb22b75451cac5bbd8be..8b4f323848aa778b06b0da6e5de275065b86adf7 100644 (file)
  * SOFTWARE.
  */
 
+enum bt_packet_seek_error {
+       BT_PACKET_SEEK_ERROR = 1,
+       BT_PACKET_SEEK_ERROR_TRUNCATED_PACKET = 2,
+};
+
 /*
  * bt_packet_seek_get_error: get the return code of the last packet_seek use.
  *
index 30a45423dfc1c2130b342aa7d274bd8dcd9b39d0..639a2d290a5abc5aeabc94148c772c6b3dc9dc67 100644 (file)
@@ -864,6 +864,10 @@ int bt_iter_next(struct bt_iter *iter)
                 */
                ret = 0;
                goto reinsert;
+       } else if (ret == -ERANGE) {
+               removed = bt_heap_remove(iter->stream_heap);
+               assert(removed == file_stream);
+               goto end;
        } else if (ret) {
                goto end;
        }
This page took 0.028839 seconds and 4 git commands to generate.