When index files are available, this ensures we report the issue
properly before mapping a truncated packet rather than hitting a
SIGBUS.
For traces without index files, remove the check that was done at
index creation, and use the new check done when mapping the packet
instead. This ensures babeltrace can print stream data prior to the
truncated packet for this stream.
TODO: What is _not_ done in this patch is changing handling of truncated
packets: this should be treated as a warning rather than an error, so
processing of other streams continue.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
CC: Jonathan Rajotte-Julien <jonathan.rajotte-julien@efficios.com>
CC: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+
+ 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;
+ goto end;
+ }
+
pos->content_size = packet_index->content_size;
pos->packet_size = packet_index->packet_size;
pos->mmap_offset = packet_index->offset;
pos->content_size = packet_index->content_size;
pos->packet_size = packet_index->packet_size;
pos->mmap_offset = packet_index->offset;
static
int create_stream_one_packet_index(struct ctf_stream_pos *pos,
struct ctf_trace *td,
static
int create_stream_one_packet_index(struct ctf_stream_pos *pos,
struct ctf_trace *td,
- struct ctf_file_stream *file_stream,
- size_t filesize)
+ struct ctf_file_stream *file_stream)
{
struct packet_index packet_index;
uint64_t stream_id = 0;
{
struct packet_index packet_index;
uint64_t stream_id = 0;
- if (filesize - pos->mmap_offset < (packet_map_len >> LOG2_CHAR_BIT)) {
- packet_map_len = (filesize - pos->mmap_offset) << LOG2_CHAR_BIT;
+ if (pos->file_length - pos->mmap_offset < (packet_map_len >> LOG2_CHAR_BIT)) {
+ packet_map_len = (pos->file_length - pos->mmap_offset) << LOG2_CHAR_BIT;
packet_index.packet_size = bt_get_unsigned_int(field);
} else {
/* Use file size for packet size */
packet_index.packet_size = bt_get_unsigned_int(field);
} else {
/* Use file size for packet size */
- packet_index.packet_size = filesize * CHAR_BIT;
+ packet_index.packet_size = pos->file_length * CHAR_BIT;
}
/* read content size from header */
}
/* read content size from header */
packet_index.content_size = bt_get_unsigned_int(field);
} else {
/* Use packet size if non-zero, else file size */
packet_index.content_size = bt_get_unsigned_int(field);
} else {
/* Use packet size if non-zero, else file size */
- packet_index.content_size = packet_index.packet_size ? : filesize * CHAR_BIT;
+ packet_index.content_size = packet_index.packet_size ? : pos->file_length * CHAR_BIT;
}
/* read timestamp begin from header */
}
/* read timestamp begin from header */
}
} else {
/* Use file size for packet size */
}
} else {
/* Use file size for packet size */
- packet_index.packet_size = filesize * CHAR_BIT;
+ packet_index.packet_size = pos->file_length * CHAR_BIT;
/* Use packet size if non-zero, else file size */
/* Use packet size if non-zero, else file size */
- packet_index.content_size = packet_index.packet_size ? : filesize * CHAR_BIT;
+ packet_index.content_size = packet_index.packet_size ? : pos->file_length * CHAR_BIT;
}
/* Validate content size and packet size values */
}
/* Validate content size and packet size values */
- if (packet_index.packet_size > ((uint64_t) filesize - 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) filesize - packet_index.offset) * CHAR_BIT);
- return -EINVAL;
- }
-
if (packet_index.content_size < pos->offset) {
fprintf(stderr, "[error] Invalid CTF stream: content size is smaller than packet headers.\n");
return -EINVAL;
if (packet_index.content_size < pos->offset) {
fprintf(stderr, "[error] Invalid CTF stream: content size is smaller than packet headers.\n");
return -EINVAL;
/* Retry with larger mapping */
retry:
/* Retry with larger mapping */
retry:
- if (packet_map_len == ((filesize - pos->mmap_offset) << LOG2_CHAR_BIT)) {
+ if (packet_map_len == ((pos->file_length - pos->mmap_offset) << LOG2_CHAR_BIT)) {
/*
* Reached EOF, but still expecting header/context data.
*/
/*
* Reached EOF, but still expecting header/context data.
*/
struct ctf_file_stream *file_stream)
{
struct ctf_stream_pos *pos;
struct ctf_file_stream *file_stream)
{
struct ctf_stream_pos *pos;
int ret;
pos = &file_stream->pos;
int ret;
pos = &file_stream->pos;
- ret = fstat(pos->fd, &filestats);
- if (ret < 0)
- return ret;
-
/* Deal with empty files */
/* Deal with empty files */
- if (!filestats.st_size) {
+ if (!pos->file_length) {
if (file_stream->parent.trace_packet_header
|| file_stream->parent.stream_packet_context) {
/*
if (file_stream->parent.trace_packet_header
|| file_stream->parent.stream_packet_context) {
/*
- for (pos->mmap_offset = 0; pos->mmap_offset < filestats.st_size; ) {
- ret = create_stream_one_packet_index(pos, td, file_stream,
- filestats.st_size);
+ for (pos->mmap_offset = 0; pos->mmap_offset < pos->file_length; ) {
+ ret = create_stream_one_packet_index(pos, td, file_stream);
file_stream->pos.last_offset = LAST_OFFSET_POISON;
file_stream->pos.fd = -1;
file_stream->pos.index_fp = NULL;
file_stream->pos.last_offset = LAST_OFFSET_POISON;
file_stream->pos.fd = -1;
file_stream->pos.index_fp = NULL;
+ file_stream->pos.file_length = statbuf.st_size;
strncpy(file_stream->parent.path, path, PATH_MAX);
file_stream->parent.path[PATH_MAX - 1] = '\0';
strncpy(file_stream->parent.path, path, PATH_MAX);
file_stream->parent.path[PATH_MAX - 1] = '\0';
int dummy; /* dummy position, for length calculation */
struct bt_stream_callbacks *cb; /* Callbacks registered for iterator. */
int dummy; /* dummy position, for length calculation */
struct bt_stream_callbacks *cb; /* Callbacks registered for iterator. */
+ size_t file_length; /* length of backing file, in bytes. */