X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=formats%2Fctf%2Fctf.c;h=cf9554739c6647701ecfd44132b7eacd80fdaa38;hb=1f7b01c261b8bd6c2640c0776f0a69865dff0ad8;hp=bff84fe1df631fe836a7c5379ce3b3098782f8bc;hpb=a0b34fbba498a8a447357adf5920ac2c8a22f026;p=babeltrace.git diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index bff84fe1..cf955473 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -147,6 +147,8 @@ uint64_t ctf_timestamp_begin(struct trace_descriptor *descriptor, struct ctf_stream_declaration *stream_class; stream_class = g_ptr_array_index(tin->streams, i); + if (!stream_class) + continue; /* for each file_stream */ for (j = 0; j < stream_class->streams->len; j++) { struct ctf_stream_definition *stream; @@ -190,6 +192,8 @@ uint64_t ctf_timestamp_end(struct trace_descriptor *descriptor, struct ctf_stream_declaration *stream_class; stream_class = g_ptr_array_index(tin->streams, i); + if (!stream_class) + continue; /* for each file_stream */ for (j = 0; j < stream_class->streams->len; j++) { struct ctf_stream_definition *stream; @@ -333,8 +337,6 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream_definition *stream /* save the current position as a restore point */ pos->last_offset = pos->offset; - /* we just read the event, it is consumed when used by the caller */ - stream->consumed = 0; /* * This is the EOF check after we've advanced the position in @@ -491,7 +493,7 @@ void ctf_init_pos(struct ctf_stream_pos *pos, int fd, int open_flags) pos->packet_size = 0; pos->content_size = 0; pos->content_size_loc = NULL; - pos->base = NULL; + pos->base_mma = NULL; pos->offset = 0; pos->dummy = false; pos->cur_index = 0; @@ -526,9 +528,9 @@ void ctf_fini_pos(struct ctf_stream_pos *pos) if (pos->prot == PROT_WRITE && pos->content_size_loc) *pos->content_size_loc = pos->offset; - if (pos->base) { + if (pos->base_mma) { /* unmap old base */ - ret = munmap(pos->base, pos->packet_size / CHAR_BIT); + ret = munmap_align(pos->base_mma); if (ret) { fprintf(stderr, "[error] Unable to unmap old base: %s.\n", strerror(errno)); @@ -555,15 +557,15 @@ void ctf_packet_seek(struct stream_pos *stream_pos, size_t index, int whence) if (pos->prot == PROT_WRITE && pos->content_size_loc) *pos->content_size_loc = pos->offset; - if (pos->base) { + if (pos->base_mma) { /* unmap old base */ - ret = munmap(pos->base, pos->packet_size / CHAR_BIT); + ret = munmap_align(pos->base_mma); if (ret) { fprintf(stderr, "[error] Unable to unmap old base: %s.\n", strerror(errno)); assert(0); } - pos->base = NULL; + pos->base_mma = NULL; } /* @@ -594,7 +596,7 @@ void ctf_packet_seek(struct stream_pos *stream_pos, size_t index, int whence) switch (whence) { case SEEK_CUR: { - uint32_t events_discarded_diff; + uint64_t events_discarded_diff; if (pos->offset == EOF) { return; @@ -610,6 +612,13 @@ void ctf_packet_seek(struct stream_pos *stream_pos, size_t index, int whence) struct packet_index, pos->cur_index - 1); events_discarded_diff -= packet_index->events_discarded; + /* + * Deal with 32-bit wrap-around if the + * tracer provided a 32-bit field. + */ + if (packet_index->events_discarded_len == 32) { + events_discarded_diff = (uint32_t) events_discarded_diff; + } } file_stream->parent.events_discarded = events_discarded_diff; file_stream->parent.prev_timestamp = file_stream->parent.timestamp; @@ -643,7 +652,7 @@ void ctf_packet_seek(struct stream_pos *stream_pos, size_t index, int whence) */ if ((&file_stream->parent)->stream_class->trace->collection) { fflush(stdout); - fprintf(stderr, "[warning] Tracer discarded %d events at end of stream between [", + fprintf(stderr, "[warning] Tracer discarded %" PRIu64 " events at end of stream between [", file_stream->parent.events_discarded); ctf_print_timestamp(stderr, &file_stream->parent, file_stream->parent.prev_timestamp); @@ -679,9 +688,9 @@ void ctf_packet_seek(struct stream_pos *stream_pos, size_t index, int whence) } } /* map new base. Need mapping length from header. */ - pos->base = mmap(NULL, pos->packet_size / CHAR_BIT, pos->prot, - pos->flags, pos->fd, pos->mmap_offset); - if (pos->base == MAP_FAILED) { + pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot, + pos->flags, pos->fd, pos->mmap_offset); + if (pos->base_mma == MAP_FAILED) { fprintf(stderr, "[error] mmap error %s.\n", strerror(errno)); assert(0); @@ -897,6 +906,7 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td, int ret = 0; metadata_stream = g_new0(struct ctf_file_stream, 1); + metadata_stream->pos.last_offset = LAST_OFFSET_POISON; if (packet_seek) { metadata_stream->pos.packet_seek = packet_seek; @@ -1138,19 +1148,20 @@ int create_stream_packet_index(struct ctf_trace *td, for (pos->mmap_offset = 0; pos->mmap_offset < filestats.st_size; ) { uint64_t stream_id = 0; - if (pos->base) { + if (pos->base_mma) { /* unmap old base */ - ret = munmap(pos->base, pos->packet_size / CHAR_BIT); + ret = munmap_align(pos->base_mma); if (ret) { fprintf(stderr, "[error] Unable to unmap old base: %s.\n", strerror(errno)); return ret; } - pos->base = NULL; + pos->base_mma = NULL; } /* map new base. Need mapping length from header. */ - pos->base = mmap(NULL, MAX_PACKET_HEADER_LEN / CHAR_BIT, PROT_READ, + pos->base_mma = mmap_align(MAX_PACKET_HEADER_LEN / CHAR_BIT, PROT_READ, MAP_PRIVATE, pos->fd, pos->mmap_offset); + assert(pos->base_mma != MAP_FAILED); pos->content_size = MAX_PACKET_HEADER_LEN; /* Unknown at this point */ pos->packet_size = MAX_PACKET_HEADER_LEN; /* Unknown at this point */ pos->offset = 0; /* Position of the packet header */ @@ -1296,6 +1307,7 @@ int create_stream_packet_index(struct ctf_trace *td, field = struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); packet_index.events_discarded = get_unsigned_int(field); + packet_index.events_discarded_len = get_int_len(field); } } else { /* Use file size for packet size */ @@ -1313,7 +1325,7 @@ int create_stream_packet_index(struct ctf_trace *td, if (packet_index.packet_size > ((uint64_t)filestats.st_size - packet_index.offset) * CHAR_BIT) { fprintf(stderr, "[error] Packet size (%" PRIu64 " bits) is larger than remaining file size (%" PRIu64 " bits).\n", - packet_index.content_size, ((uint64_t)filestats.st_size - packet_index.offset) * CHAR_BIT); + packet_index.packet_size, ((uint64_t)filestats.st_size - packet_index.offset) * CHAR_BIT); return -EINVAL; } @@ -1365,15 +1377,31 @@ int ctf_open_file_stream_read(struct ctf_trace *td, const char *path, int flags, void (*packet_seek)(struct stream_pos *pos, size_t index, int whence)) { - int ret; + int ret, fd; struct ctf_file_stream *file_stream; + struct stat statbuf; - ret = openat(td->dirfd, path, flags); - if (ret < 0) { + fd = openat(td->dirfd, path, flags); + if (fd < 0) { perror("File stream openat()"); + ret = fd; goto error; } + + /* Don't try to mmap subdirectories. Skip them, return success. */ + ret = fstat(fd, &statbuf); + if (ret) { + perror("File stream fstat()"); + goto fstat_error; + } + if (S_ISDIR(statbuf.st_mode)) { + fprintf(stderr, "[warning] Skipping directory '%s' found in trace\n", path); + ret = 0; + goto fd_is_dir_ok; + } + file_stream = g_new0(struct ctf_file_stream, 1); + file_stream->pos.last_offset = LAST_OFFSET_POISON; if (packet_seek) { file_stream->pos.packet_seek = packet_seek; @@ -1383,7 +1411,7 @@ int ctf_open_file_stream_read(struct ctf_trace *td, const char *path, int flags, goto error_def; } - ctf_init_pos(&file_stream->pos, ret, flags); + ctf_init_pos(&file_stream->pos, fd, flags); ret = create_trace_definitions(td, &file_stream->parent); if (ret) goto error_def; @@ -1404,8 +1432,10 @@ error_index: definition_unref(&file_stream->parent.trace_packet_header->p); error_def: ctf_fini_pos(&file_stream->pos); - close(file_stream->pos.fd); g_free(file_stream); +fd_is_dir_ok: +fstat_error: + close(fd); error: return ret; } @@ -1545,7 +1575,7 @@ void ctf_init_mmap_pos(struct ctf_stream_pos *pos, pos->content_size = 0; pos->content_size_loc = NULL; pos->fd = mmap_info->fd; - pos->base = 0; + pos->base_mma = NULL; pos->offset = 0; pos->dummy = false; pos->cur_index = 0; @@ -1594,6 +1624,7 @@ int ctf_open_mmap_stream_read(struct ctf_trace *td, struct ctf_file_stream *file_stream; file_stream = g_new0(struct ctf_file_stream, 1); + file_stream->pos.last_offset = LAST_OFFSET_POISON; ctf_init_mmap_pos(&file_stream->pos, mmap_info); file_stream->pos.packet_seek = packet_seek;