X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=formats%2Fctf%2Fctf.c;h=ab4945dddcff18b8c41c6df91798096b4940695b;hp=8b9441fdd701ea078bd2839b1009af05e5e1b117;hb=1842a4c801d0878adf40862fda0c310a52a6fdd2;hpb=82662ad4362f791f9cd7026652f60708923554f4 diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index 8b9441fd..ab4945dd 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -52,10 +52,19 @@ #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif +#define NSEC_PER_SEC 1000000000ULL + +int opt_clock_raw, + opt_clock_seconds, + opt_clock_date, + opt_clock_gmt; + +uint64_t opt_clock_offset; + extern int yydebug; static -struct trace_descriptor *ctf_open_trace(const char *path, int flags, +struct trace_descriptor *ctf_open_trace(const char *collection_path, const char *path, int flags, void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, int whence), FILE *metadata_fp); static @@ -121,9 +130,77 @@ void ctf_update_timestamp(struct ctf_stream *stream, updateval = stream->timestamp; updateval &= ~((1ULL << integer_declaration->len) - 1); updateval += newval; + stream->prev_timestamp = stream->timestamp; stream->timestamp = updateval; } +void ctf_print_timestamp(FILE *fp, + struct ctf_stream *stream, + uint64_t timestamp) +{ + uint64_t ts_sec = 0, ts_nsec; + struct ctf_trace *trace = stream->stream_class->trace; + struct trace_collection *tc = trace->collection; + uint64_t tc_offset = tc->single_clock_offset_avg; + + ts_nsec = timestamp; + + /* Add offsets */ + if (!opt_clock_raw) { + ts_nsec += tc_offset; + } + ts_sec += opt_clock_offset; + + ts_sec += ts_nsec / NSEC_PER_SEC; + ts_nsec = ts_nsec % NSEC_PER_SEC; + + if (!opt_clock_seconds) { + struct tm tm; + time_t time_s = (time_t) ts_sec; + + if (!opt_clock_gmt) { + struct tm *res; + + res = localtime_r(&time_s, &tm); + if (!res) { + fprintf(stderr, "[warning] Unable to get localtime.\n"); + goto seconds; + } + } else { + struct tm *res; + + res = gmtime_r(&time_s, &tm); + if (!res) { + fprintf(stderr, "[warning] Unable to get gmtime.\n"); + goto seconds; + } + } + if (opt_clock_date) { + char timestr[26]; + size_t res; + + /* Print date and time */ + res = strftime(timestr, sizeof(timestr), + "%F ", &tm); + if (!res) { + fprintf(stderr, "[warning] Unable to print ascii time.\n"); + goto seconds; + } + fprintf(fp, "%s", timestr); + } + /* Print time in HH:MM:SS.ns */ + fprintf(fp, "%02d:%02d:%02d.%09" PRIu64, + tm.tm_hour, tm.tm_min, tm.tm_sec, ts_nsec); + goto end; + } +seconds: + fprintf(fp, "%3" PRIu64 ".%09" PRIu64, + ts_sec, ts_nsec); + +end: + return; +} + static int ctf_read_event(struct stream_pos *ppos, struct ctf_stream *stream) { @@ -203,12 +280,12 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream *stream) } if (unlikely(id >= stream_class->events_by_id->len)) { - fprintf(stdout, "[error] Event id %" PRIu64 " is outside range.\n", id); + fprintf(stderr, "[error] Event id %" PRIu64 " is outside range.\n", id); return -EINVAL; } event = g_ptr_array_index(stream->events_by_id, id); if (unlikely(!event)) { - fprintf(stdout, "[error] Event id %" PRIu64 " is unknown.\n", id); + fprintf(stderr, "[error] Event id %" PRIu64 " is unknown.\n", id); return -EINVAL; } @@ -229,7 +306,7 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream *stream) return 0; error: - fprintf(stdout, "[error] Unexpected end of stream. Either the trace data stream is corrupted or metadata description does not match data layout.\n"); + fprintf(stderr, "[error] Unexpected end of stream. Either the trace data stream is corrupted or metadata description does not match data layout.\n"); return ret; } @@ -258,12 +335,12 @@ int ctf_write_event(struct stream_pos *pos, struct ctf_stream *stream) } if (unlikely(id >= stream_class->events_by_id->len)) { - fprintf(stdout, "[error] Event id %" PRIu64 " is outside range.\n", id); + fprintf(stderr, "[error] Event id %" PRIu64 " is outside range.\n", id); return -EINVAL; } event = g_ptr_array_index(stream->events_by_id, id); if (unlikely(!event)) { - fprintf(stdout, "[error] Event id %" PRIu64 " is unknown.\n", id); + fprintf(stderr, "[error] Event id %" PRIu64 " is unknown.\n", id); return -EINVAL; } @@ -284,7 +361,7 @@ int ctf_write_event(struct stream_pos *pos, struct ctf_stream *stream) return 0; error: - fprintf(stdout, "[error] Unexpected end of stream. Either the trace data stream is corrupted or metadata description does not match data layout.\n"); + fprintf(stderr, "[error] Unexpected end of stream. Either the trace data stream is corrupted or metadata description does not match data layout.\n"); return ret; } @@ -334,7 +411,7 @@ void ctf_fini_pos(struct ctf_stream_pos *pos) /* unmap old base */ ret = munmap(pos->base, pos->packet_size / CHAR_BIT); if (ret) { - fprintf(stdout, "[error] Unable to unmap old base: %s.\n", + fprintf(stderr, "[error] Unable to unmap old base: %s.\n", strerror(errno)); assert(0); } @@ -357,7 +434,7 @@ void ctf_move_pos_slow(struct ctf_stream_pos *pos, size_t offset, int whence) /* unmap old base */ ret = munmap(pos->base, pos->packet_size / CHAR_BIT); if (ret) { - fprintf(stdout, "[error] Unable to unmap old base: %s.\n", + fprintf(stderr, "[error] Unable to unmap old base: %s.\n", strerror(errno)); assert(0); } @@ -392,20 +469,61 @@ void ctf_move_pos_slow(struct ctf_stream_pos *pos, size_t offset, int whence) read_next_packet: switch (whence) { case SEEK_CUR: - if (pos->offset == EOF) + { + uint32_t events_discarded_diff; + + if (pos->offset == EOF) { return; + } + /* For printing discarded event count */ + index = &g_array_index(pos->packet_index, + struct packet_index, pos->cur_index); + events_discarded_diff = index->events_discarded; + file_stream->parent.prev_timestamp_end = + index->timestamp_end; + if (pos->cur_index > 0) { + index = &g_array_index(pos->packet_index, + struct packet_index, + pos->cur_index - 1); + events_discarded_diff -= index->events_discarded; + } + file_stream->parent.events_discarded = events_discarded_diff; + file_stream->parent.prev_timestamp = file_stream->parent.timestamp; /* The reader will expect us to skip padding */ assert(pos->offset + offset == pos->content_size); ++pos->cur_index; break; + } case SEEK_SET: assert(offset == 0); /* only seek supported for now */ pos->cur_index = 0; + file_stream->parent.prev_timestamp = 0; + file_stream->parent.prev_timestamp_end = 0; break; default: assert(0); } if (pos->cur_index >= pos->packet_index->len) { + /* + * When a stream reaches the end of the + * file, we need to show the number of + * events discarded ourselves, because + * there is no next event scheduled to + * be printed in the output. + */ + if (file_stream->parent.events_discarded) { + fflush(stdout); + fprintf(stderr, "[warning] Tracer discarded %d events at end of stream between [", + file_stream->parent.events_discarded); + ctf_print_timestamp(stderr, &file_stream->parent, + file_stream->parent.prev_timestamp); + fprintf(stderr, "] and ["); + ctf_print_timestamp(stderr, &file_stream->parent, + file_stream->parent.prev_timestamp_end); + fprintf(stderr, "]. You should consider increasing the buffer size.\n"); + fflush(stderr); + file_stream->parent.events_discarded = 0; + } pos->offset = EOF; return; } @@ -434,7 +552,7 @@ void ctf_move_pos_slow(struct ctf_stream_pos *pos, size_t offset, int whence) pos->base = mmap(NULL, pos->packet_size / CHAR_BIT, pos->prot, pos->flags, pos->fd, pos->mmap_offset); if (pos->base == MAP_FAILED) { - fprintf(stdout, "[error] mmap error %s.\n", + fprintf(stderr, "[error] mmap error %s.\n", strerror(errno)); assert(0); } @@ -499,7 +617,7 @@ int check_version(unsigned int major, unsigned int minor) /* eventually return an error instead of warning */ warning: - fprintf(stdout, "[warning] Unsupported CTF specification version %u.%u. Trying anyway.\n", + fprintf(stderr, "[warning] Unsupported CTF specification version %u.%u. Trying anyway.\n", major, minor); return 0; } @@ -524,19 +642,19 @@ int ctf_open_trace_metadata_packet_read(struct ctf_trace *td, FILE *in, header.packet_size = GUINT32_SWAP_LE_BE(header.packet_size); } if (header.checksum) - fprintf(stdout, "[warning] checksum verification not supported yet.\n"); + fprintf(stderr, "[warning] checksum verification not supported yet.\n"); if (header.compression_scheme) { - fprintf(stdout, "[error] compression (%u) not supported yet.\n", + fprintf(stderr, "[error] compression (%u) not supported yet.\n", header.compression_scheme); return -EINVAL; } if (header.encryption_scheme) { - fprintf(stdout, "[error] encryption (%u) not supported yet.\n", + fprintf(stderr, "[error] encryption (%u) not supported yet.\n", header.encryption_scheme); return -EINVAL; } if (header.checksum_scheme) { - fprintf(stdout, "[error] checksum (%u) not supported yet.\n", + fprintf(stderr, "[error] checksum (%u) not supported yet.\n", header.checksum_scheme); return -EINVAL; } @@ -560,7 +678,7 @@ int ctf_open_trace_metadata_packet_read(struct ctf_trace *td, FILE *in, } if (babeltrace_debug) { buf[readlen] = '\0'; - fprintf(stdout, "[debug] metadata packet read: %s\n", + fprintf(stderr, "[debug] metadata packet read: %s\n", buf); } @@ -585,7 +703,7 @@ read_padding: toread = (header.packet_size - header.content_size) / CHAR_BIT; ret = fseek(in, toread, SEEK_CUR); if (ret < 0) { - fprintf(stdout, "[warning] Missing padding at end of file\n"); + fprintf(stderr, "[warning] Missing padding at end of file\n"); ret = 0; } return ret; @@ -658,13 +776,13 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td, td->metadata = &metadata_stream->parent; metadata_stream->pos.fd = openat(td->dirfd, "metadata", O_RDONLY); if (metadata_stream->pos.fd < 0) { - fprintf(stdout, "Unable to open metadata.\n"); + fprintf(stderr, "Unable to open metadata.\n"); return metadata_stream->pos.fd; } fp = fdopen(metadata_stream->pos.fd, "r"); if (!fp) { - fprintf(stdout, "[error] Unable to open metadata stream.\n"); + fprintf(stderr, "[error] Unable to open metadata stream.\n"); perror("Metadata stream open"); ret = -errno; goto end_stream; @@ -686,7 +804,7 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td, /* Check text-only metadata header and version */ nr_items = fscanf(fp, "/* CTF %u.%u", &major, &minor); if (nr_items < 2) - fprintf(stdout, "[warning] Ill-shapen or missing \"/* CTF x.y\" header for text-only metadata.\n"); + fprintf(stderr, "[warning] Ill-shapen or missing \"/* CTF x.y\" header for text-only metadata.\n"); if (check_version(major, minor) < 0) { ret = -EINVAL; goto end_packet_read; @@ -696,33 +814,33 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td, scanner = ctf_scanner_alloc(fp); if (!scanner) { - fprintf(stdout, "[error] Error allocating scanner\n"); + fprintf(stderr, "[error] Error allocating scanner\n"); ret = -ENOMEM; goto end_scanner_alloc; } ret = ctf_scanner_append_ast(scanner); if (ret) { - fprintf(stdout, "[error] Error creating AST\n"); + fprintf(stderr, "[error] Error creating AST\n"); goto end; } if (babeltrace_debug) { - ret = ctf_visitor_print_xml(stdout, 0, &scanner->ast->root); + ret = ctf_visitor_print_xml(stderr, 0, &scanner->ast->root); if (ret) { - fprintf(stdout, "[error] Error visiting AST for XML output\n"); + fprintf(stderr, "[error] Error visiting AST for XML output\n"); goto end; } } - ret = ctf_visitor_semantic_check(stdout, 0, &scanner->ast->root); + ret = ctf_visitor_semantic_check(stderr, 0, &scanner->ast->root); if (ret) { - fprintf(stdout, "[error] Error in CTF semantic validation %d\n", ret); + fprintf(stderr, "[error] Error in CTF semantic validation %d\n", ret); goto end; } - ret = ctf_visitor_construct_metadata(stdout, 0, &scanner->ast->root, + ret = ctf_visitor_construct_metadata(stderr, 0, &scanner->ast->root, td, td->byte_order); if (ret) { - fprintf(stdout, "[error] Error in CTF metadata constructor %d\n", ret); + fprintf(stderr, "[error] Error in CTF metadata constructor %d\n", ret); goto end; } end: @@ -886,7 +1004,7 @@ int create_stream_packet_index(struct ctf_trace *td, /* unmap old base */ ret = munmap(pos->base, pos->packet_size / CHAR_BIT); if (ret) { - fprintf(stdout, "[error] Unable to unmap old base: %s.\n", + fprintf(stderr, "[error] Unable to unmap old base: %s.\n", strerror(errno)); return ret; } @@ -904,6 +1022,7 @@ int create_stream_packet_index(struct ctf_trace *td, packet_index.packet_size = 0; packet_index.timestamp_begin = 0; packet_index.timestamp_end = 0; + packet_index.events_discarded = 0; /* read and check header, set stream id (and check) */ if (file_stream->parent.trace_packet_header) { @@ -919,7 +1038,7 @@ int create_stream_packet_index(struct ctf_trace *td, field = struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index); magic = get_unsigned_int(field); if (magic != CTF_MAGIC) { - fprintf(stdout, "[error] Invalid magic number 0x%" PRIX64 " at packet %u (file offset %zd).\n", + fprintf(stderr, "[error] Invalid magic number 0x%" PRIX64 " at packet %u (file offset %zd).\n", magic, file_stream->pos.packet_index->len, (ssize_t) pos->mmap_offset); @@ -948,7 +1067,7 @@ int create_stream_packet_index(struct ctf_trace *td, } ret = uuid_compare(td->uuid, uuidval); if (ret) { - fprintf(stdout, "[error] Unique Universal Identifiers do not match.\n"); + fprintf(stderr, "[error] Unique Universal Identifiers do not match.\n"); return -EINVAL; } } @@ -964,18 +1083,18 @@ int create_stream_packet_index(struct ctf_trace *td, } if (!first_packet && file_stream->parent.stream_id != stream_id) { - fprintf(stdout, "[error] Stream ID is changing within a stream.\n"); + fprintf(stderr, "[error] Stream ID is changing within a stream.\n"); return -EINVAL; } if (first_packet) { file_stream->parent.stream_id = stream_id; if (stream_id >= td->streams->len) { - fprintf(stdout, "[error] Stream %" PRIu64 " is not declared in metadata.\n", stream_id); + 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(stdout, "[error] Stream %" PRIu64 " is not declared in metadata.\n", stream_id); + fprintf(stderr, "[error] Stream %" PRIu64 " is not declared in metadata.\n", stream_id); return -EINVAL; } file_stream->parent.stream_class = stream; @@ -1031,6 +1150,15 @@ 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.timestamp_end = get_unsigned_int(field); } + + /* read events discarded from header */ + len_index = struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_static_string("events_discarded")); + if (len_index >= 0) { + struct definition *field; + + field = struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); + packet_index.events_discarded = get_unsigned_int(field); + } } else { /* Use file size for packet size */ packet_index.content_size = filestats.st_size * CHAR_BIT; @@ -1040,13 +1168,13 @@ int create_stream_packet_index(struct ctf_trace *td, /* Validate content size and packet size values */ if (packet_index.content_size > packet_index.packet_size) { - fprintf(stdout, "[error] Content size (%zu bits) is larger than packet size (%zu bits).\n", + fprintf(stderr, "[error] Content size (%zu bits) is larger than packet size (%zu bits).\n", packet_index.content_size, packet_index.packet_size); return -EINVAL; } if (packet_index.packet_size > (filestats.st_size - packet_index.offset) * CHAR_BIT) { - fprintf(stdout, "[error] Packet size (%zu bits) is larger than remaining file size (%zu bits).\n", + fprintf(stderr, "[error] Packet size (%zu bits) is larger than remaining file size (%zu bits).\n", packet_index.content_size, (size_t) (filestats.st_size - packet_index.offset) * CHAR_BIT); return -EINVAL; } @@ -1140,8 +1268,98 @@ error: return ret; } +static void +init_domain_name(struct ctf_trace *td) +{ + char *start, *end; + + start = td->path + strlen(td->collection_path); + while (start[0] == '/') + start++; /* skip / */ + end = strchr(start, '/'); + if (!end) + end = start + strlen(start); + memcpy(td->domain, start, end - start); + td->domain[end - start] = '\0'; +} + +static void +init_proc_name(struct ctf_trace *td) +{ + char buf[PATH_MAX]; + char *start, *end; + + if (td->domain[0] == '\0') + return; + memcpy(buf, td->path, PATH_MAX); + start = buf + strlen(td->collection_path); + while (start[0] == '/') + start++; /* skip / */ + start = strchr(start, '/'); /* get begin of domain content */ + if (!start) + return; + while (start[0] == '/') + start++; /* skip / */ + /* find last -, skips time */ + end = strrchr(start, '-'); + if (!end) + return; + *end = '\0'; + /* find previous -, skips date */ + end = strrchr(start, '-'); + if (!end) + return; + *end = '\0'; + /* find previous -, skips pid */ + end = strrchr(start, '-'); + if (!end) + return; + *end = '\0'; + + memcpy(td->procname, start, end - start); + td->procname[end - start] = '\0'; +} + +static void +init_vpid(struct ctf_trace *td) +{ + char buf[PATH_MAX]; + char *start, *end; + + if (td->domain[0] == '\0') + return; + memcpy(buf, td->path, PATH_MAX); + start = buf + strlen(td->collection_path); + while (start[0] == '/') + start++; /* skip / */ + start = strchr(start, '/'); /* get begin of domain content */ + if (!start) + return; + while (start[0] == '/') + start++; /* skip / */ + /* find last -, skips time */ + end = strrchr(start, '-'); + if (!end) + return; + *end = '\0'; + /* find previous -, skips date */ + end = strrchr(start, '-'); + if (!end) + return; + *end = '\0'; + /* find previous -, skips pid */ + start = strrchr(start, '-'); + if (!start) + return; + start++; /* skip - */ + + memcpy(td->vpid, start, end - start); + td->vpid[end - start] = '\0'; +} + static -int ctf_open_trace_read(struct ctf_trace *td, const char *path, int flags, +int ctf_open_trace_read(struct ctf_trace *td, const char *collection_path, + const char *path, int flags, void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, int whence), FILE *metadata_fp) { @@ -1149,26 +1367,38 @@ int ctf_open_trace_read(struct ctf_trace *td, const char *path, int flags, struct dirent *dirent; struct dirent *diriter; size_t dirent_len; + char *respath, *rescolpath; td->flags = flags; /* Open trace directory */ td->dir = opendir(path); if (!td->dir) { - fprintf(stdout, "[error] Unable to open trace directory.\n"); + fprintf(stderr, "[error] Unable to open trace directory.\n"); ret = -ENOENT; goto error; } td->dirfd = open(path, 0); if (td->dirfd < 0) { - fprintf(stdout, "[error] Unable to open trace directory file descriptor.\n"); + fprintf(stderr, "[error] Unable to open trace directory file descriptor.\n"); perror("Trace directory open"); ret = -errno; goto error_dirfd; } - strncpy(td->path, path, PATH_MAX); - td->path[PATH_MAX - 1] = '\0'; + rescolpath = realpath(collection_path, td->collection_path); + if (!rescolpath) { + fprintf(stderr, "[error] collection path resolution failure\n"); + return -EINVAL; + } + respath = realpath(path, td->path); + if (!respath) { + fprintf(stderr, "[error] path resolution failure\n"); + return -EINVAL; + } + init_domain_name(td); + init_proc_name(td); + init_vpid(td); /* * Keep the metadata file separate. @@ -1193,7 +1423,7 @@ int ctf_open_trace_read(struct ctf_trace *td, const char *path, int flags, for (;;) { ret = readdir_r(td->dir, dirent, &diriter); if (ret) { - fprintf(stdout, "[error] Readdir error.\n"); + fprintf(stderr, "[error] Readdir error.\n"); goto readdir_error; } if (!diriter) @@ -1205,7 +1435,7 @@ int ctf_open_trace_read(struct ctf_trace *td, const char *path, int flags, continue; ret = ctf_open_file_stream_read(td, diriter->d_name, flags, move_pos_slow); if (ret) { - fprintf(stdout, "[error] Open file stream error.\n"); + fprintf(stderr, "[error] Open file stream error.\n"); goto readdir_error; } } @@ -1224,7 +1454,7 @@ error: } static -struct trace_descriptor *ctf_open_trace(const char *path, int flags, +struct trace_descriptor *ctf_open_trace(const char *collection_path, const char *path, int flags, void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, int whence), FILE *metadata_fp) { @@ -1236,18 +1466,18 @@ struct trace_descriptor *ctf_open_trace(const char *path, int flags, switch (flags & O_ACCMODE) { case O_RDONLY: if (!path) { - fprintf(stdout, "[error] Path missing for input CTF trace.\n"); + fprintf(stderr, "[error] Path missing for input CTF trace.\n"); goto error; } - ret = ctf_open_trace_read(td, path, flags, move_pos_slow, metadata_fp); + ret = ctf_open_trace_read(td, collection_path, path, flags, move_pos_slow, metadata_fp); if (ret) goto error; break; case O_RDWR: - fprintf(stdout, "[error] Opening CTF traces for output is not supported yet.\n"); + fprintf(stderr, "[error] Opening CTF traces for output is not supported yet.\n"); goto error; default: - fprintf(stdout, "[error] Incorrect open flags.\n"); + fprintf(stderr, "[error] Incorrect open flags.\n"); goto error; } @@ -1287,14 +1517,14 @@ int prepare_mmap_stream_definition(struct ctf_trace *td, file_stream->parent.stream_id = stream_id; if (stream_id >= td->streams->len) { - fprintf(stdout, "[error] Stream %" PRIu64 " is not declared " + fprintf(stderr, "[error] Stream %" PRIu64 " is not declared " "in metadata.\n", stream_id); ret = -EINVAL; goto end; } stream = g_ptr_array_index(td->streams, stream_id); if (!stream) { - fprintf(stdout, "[error] Stream %" PRIu64 " is not declared " + fprintf(stderr, "[error] Stream %" PRIu64 " is not declared " "in metadata.\n", stream_id); ret = -EINVAL; goto end; @@ -1362,7 +1592,7 @@ int ctf_open_mmap_trace_read(struct ctf_trace *td, cds_list_for_each_entry(mmap_info, &mmap_list->head, list) { ret = ctf_open_mmap_stream_read(td, mmap_info, move_pos_slow); if (ret) { - fprintf(stdout, "[error] Open file mmap stream error.\n"); + fprintf(stderr, "[error] Open file mmap stream error.\n"); goto error; } }