From d013ee49c0f8cc99f92df4118e9804eca3640b7b Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Wed, 7 Feb 2018 17:52:05 -0500 Subject: [PATCH] Propagate error from packet_seek in case of truncated packet MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Jérémie Galarneau --- converter/babeltrace.c | 12 +++++-- formats/ctf/ctf.c | 52 ++++++++++++++++++++++------ formats/lttng-live/lttng-live-comm.c | 6 ++-- include/babeltrace/error.h | 5 +++ lib/iterator.c | 4 +++ 5 files changed, 64 insertions(+), 15 deletions(-) diff --git a/converter/babeltrace.c b/converter/babeltrace.c index 2e4003ca..6e6c3385 100644 --- a/converter/babeltrace.c +++ b/converter/babeltrace.c @@ -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); diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index 5b6e3b90..e414af7b 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -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; } diff --git a/formats/lttng-live/lttng-live-comm.c b/formats/lttng-live/lttng-live-comm.c index cb871a13..055b1c30 100644 --- a/formats/lttng-live/lttng-live-comm.c +++ b/formats/lttng-live/lttng-live-comm.c @@ -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; } diff --git a/include/babeltrace/error.h b/include/babeltrace/error.h index 2f6a6d7c..8b4f3238 100644 --- a/include/babeltrace/error.h +++ b/include/babeltrace/error.h @@ -30,6 +30,11 @@ * 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. * diff --git a/lib/iterator.c b/lib/iterator.c index 30a45423..639a2d29 100644 --- a/lib/iterator.c +++ b/lib/iterator.c @@ -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; } -- 2.34.1