X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=formats%2Fctf%2Fctf.c;h=b27f2ec8fba14e99fa0a56f90b5b70345d1edc3d;hb=3b7335c35a07310fd5fc01d4a0259c367acaaec5;hp=01035f3d0be119d1d24798481b3b71a883ca8a73;hpb=ca334c7230d120ffe211efbfd6efe467b5d4d794;p=babeltrace.git diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index 01035f3d..b27f2ec8 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include @@ -51,7 +51,7 @@ #include "metadata/ctf-parser.h" #include "metadata/ctf-ast.h" #include "events-private.h" -#include "memstream.h" +#include " #define LOG2_CHAR_BIT 3 @@ -77,6 +77,7 @@ int opt_clock_cycles, opt_clock_gmt; uint64_t opt_clock_offset; +uint64_t opt_clock_offset_ns; extern int yydebug; @@ -321,6 +322,9 @@ void ctf_print_timestamp_real(FILE *fp, ts_nsec = timestamp; + /* Add command-line offset in ns*/ + ts_nsec += opt_clock_offset_ns; + /* Add command-line offset */ ts_sec += opt_clock_offset; @@ -426,9 +430,9 @@ void ctf_print_discarded(FILE *fp, struct ctf_stream_definition *stream, } fprintf(fp, "] in trace UUID "); print_uuid(fp, stream->stream_class->trace->uuid); - if (stream->stream_class->trace->path[0]) + if (stream->stream_class->trace->parent.path[0]) fprintf(fp, ", at path: \"%s\"", - stream->stream_class->trace->path); + stream->stream_class->trace->parent.path); fprintf(fp, ", within stream id %" PRIu64, stream->stream_id); if (stream->path[0]) @@ -678,6 +682,14 @@ void ctf_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence) off_t off; struct packet_index *packet_index; + switch (whence) { + case SEEK_CUR: + case SEEK_SET: /* Fall-through */ + break; /* OK */ + default: + assert(0); + } + if (pos->prot == PROT_WRITE && pos->content_size_loc) *pos->content_size_loc = pos->offset; @@ -717,6 +729,14 @@ void ctf_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence) pos->offset = 0; } else { read_next_packet: + if (pos->cur_index >= pos->packet_cycles_index->len) { + pos->offset = EOF; + return; + } + if (pos->cur_index >= pos->packet_real_index->len) { + pos->offset = EOF; + return; + } switch (whence) { case SEEK_CUR: { @@ -781,7 +801,7 @@ void ctf_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence) * case, the collection is not there, so we * cannot print the timestamps. */ - if ((&file_stream->parent)->stream_class->trace->collection) { + if ((&file_stream->parent)->stream_class->trace->parent.collection) { /* * When a stream reaches the end of the * file, we need to show the number of @@ -1214,6 +1234,8 @@ error: bt_definition_unref(&stream_event->event_fields->p); if (stream_event->event_context) bt_definition_unref(&stream_event->event_context->p); + fprintf(stderr, "[error] Unable to create event definition for event \"%s\".\n", + g_quark_to_string(event->name)); return NULL; } @@ -1274,8 +1296,10 @@ int create_stream_definitions(struct ctf_trace *td, struct ctf_stream_definition if (!event) continue; stream_event = create_event_definitions(td, stream, event); - if (!stream_event) + if (!stream_event) { + ret = -EINVAL; goto error_event; + } g_ptr_array_index(stream->events_by_id, i) = stream_event; } return 0; @@ -1294,9 +1318,36 @@ error: bt_definition_unref(&stream->stream_event_header->p); if (stream->stream_packet_context) bt_definition_unref(&stream->stream_packet_context->p); + fprintf(stderr, "[error] Unable to create stream (%" PRIu64 ") definitions: %s\n", + stream_class->stream_id, strerror(-ret)); return ret; } +static +int stream_assign_class(struct ctf_trace *td, + struct ctf_file_stream *file_stream, + uint64_t stream_id) +{ + struct ctf_stream_declaration *stream; + int ret; + + file_stream->parent.stream_id = stream_id; + if (stream_id >= td->streams->len) { + fprintf(stderr, "[error] Stream %" PRIu64 " is not declared in metadata.\n", stream_id); + return -EINVAL; + } + stream = g_ptr_array_index(td->streams, stream_id); + if (!stream) { + fprintf(stderr, "[error] Stream %" PRIu64 " is not declared in metadata.\n", stream_id); + return -EINVAL; + } + file_stream->parent.stream_class = stream; + ret = create_stream_definitions(td, &file_stream->parent); + if (ret) + return ret; + return 0; +} + static int create_stream_one_packet_index(struct ctf_stream_pos *pos, struct ctf_trace *td, @@ -1304,7 +1355,6 @@ int create_stream_one_packet_index(struct ctf_stream_pos *pos, size_t filesize) { struct packet_index packet_index; - struct ctf_stream_declaration *stream; uint64_t stream_id = 0; uint64_t packet_map_len = DEFAULT_HEADER_LEN, tmp_map_len; int first_packet = 0; @@ -1357,6 +1407,7 @@ begin: if (ret) { if (ret == -EFAULT) goto retry; + fprintf(stderr, "[error] Unable to read packet header: %s\n", strerror(-ret)); return ret; } len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.trace_packet_header->declaration, g_quark_from_static_string("magic")); @@ -1417,18 +1468,7 @@ begin: return -EINVAL; } if (first_packet) { - file_stream->parent.stream_id = stream_id; - if (stream_id >= td->streams->len) { - fprintf(stderr, "[error] Stream %" PRIu64 " is not declared in metadata.\n", stream_id); - return -EINVAL; - } - stream = g_ptr_array_index(td->streams, stream_id); - if (!stream) { - fprintf(stderr, "[error] Stream %" PRIu64 " is not declared in metadata.\n", stream_id); - return -EINVAL; - } - file_stream->parent.stream_class = stream; - ret = create_stream_definitions(td, &file_stream->parent); + ret = stream_assign_class(td, file_stream, stream_id); if (ret) return ret; } @@ -1439,6 +1479,7 @@ begin: if (ret) { if (ret == -EFAULT) goto retry; + fprintf(stderr, "[error] Unable to read packet context: %s\n", strerror(-ret)); return ret; } /* read content size from header */ @@ -1472,7 +1513,7 @@ begin: field = bt_struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); packet_index.timestamp_begin = bt_get_unsigned_int(field); - if (file_stream->parent.stream_class->trace->collection) { + if (file_stream->parent.stream_class->trace->parent.collection) { packet_index.timestamp_begin = ctf_get_real_timestamp( &file_stream->parent, @@ -1487,7 +1528,7 @@ begin: field = bt_struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); packet_index.timestamp_end = bt_get_unsigned_int(field); - if (file_stream->parent.stream_class->trace->collection) { + if (file_stream->parent.stream_class->trace->parent.collection) { packet_index.timestamp_end = ctf_get_real_timestamp( &file_stream->parent, @@ -1547,6 +1588,7 @@ retry: tmp_map_len = packet_map_len << 1; if (tmp_map_len >> 1 != packet_map_len) { /* Overflow */ + fprintf(stderr, "[error] Packet mapping length overflow\n"); return -EFAULT; } packet_map_len = tmp_map_len; @@ -1567,6 +1609,30 @@ int create_stream_packet_index(struct ctf_trace *td, if (ret < 0) return ret; + /* Deal with empty files */ + if (!filestats.st_size) { + if (file_stream->parent.trace_packet_header + || file_stream->parent.stream_packet_context) { + /* + * We expect a trace packet header and/or stream packet + * context. Since a trace needs to have at least one + * packet, empty files are therefore not accepted. + */ + fprintf(stderr, "[error] Encountered an empty file, but expecting a trace packet header.\n"); + return -EINVAL; + } else { + /* + * Without trace packet header nor stream packet + * context, a one-packet trace can indeed be empty. This + * is only valid if there is only one stream class: 0. + */ + ret = stream_assign_class(td, file_stream, 0); + if (ret) + return ret; + return 0; + } + } + for (pos->mmap_offset = 0; pos->mmap_offset < filestats.st_size; ) { ret = create_stream_one_packet_index(pos, td, file_stream, filestats.st_size); @@ -1597,6 +1663,7 @@ int create_trace_definitions(struct ctf_trace *td, struct ctf_stream_definition return 0; error: + fprintf(stderr, "[error] Unable to create trace definitions: %s\n", strerror(-ret)); return ret; } @@ -1655,10 +1722,12 @@ int ctf_open_file_stream_read(struct ctf_trace *td, const char *path, int flags, /* * For now, only a single clock per trace is supported. */ - file_stream->parent.current_clock = td->single_clock; + file_stream->parent.current_clock = td->parent.single_clock; ret = create_stream_packet_index(td, file_stream); - if (ret) + if (ret) { + fprintf(stderr, "[error] Stream index creation error.\n"); goto error_index; + } /* Add stream file to stream class */ g_ptr_array_add(file_stream->parent.stream_class->streams, &file_stream->parent); @@ -1711,8 +1780,8 @@ int ctf_open_trace_read(struct ctf_trace *td, ret = -errno; goto error_dirfd; } - strncpy(td->path, path, sizeof(td->path)); - td->path[sizeof(td->path) - 1] = '\0'; + strncpy(td->parent.path, path, sizeof(td->parent.path)); + td->parent.path[sizeof(td->parent.path) - 1] = '\0'; /* * Keep the metadata file separate. @@ -1896,7 +1965,7 @@ int ctf_open_mmap_stream_read(struct ctf_trace *td, /* * For now, only a single clock per trace is supported. */ - file_stream->parent.current_clock = td->single_clock; + file_stream->parent.current_clock = td->parent.single_clock; /* Add stream file to stream class */ g_ptr_array_add(file_stream->parent.stream_class->streams, @@ -2093,7 +2162,7 @@ void ctf_set_context(struct bt_trace_descriptor *descriptor, struct ctf_trace *td = container_of(descriptor, struct ctf_trace, parent); - td->ctx = ctx; + td->parent.ctx = ctx; } static @@ -2103,7 +2172,7 @@ void ctf_set_handle(struct bt_trace_descriptor *descriptor, struct ctf_trace *td = container_of(descriptor, struct ctf_trace, parent); - td->handle = handle; + td->parent.handle = handle; } static