Message ID | 20220309082607.2165890-1-zhe.he@windriver.com |
---|---|
State | New |
Headers | show |
Series | [hardknott] babeltrace: Handle negative time and offset from Epoch | expand |
On Wed, 2022-03-09 at 16:26 +0800, He Zhe wrote: > Backport a patch from upstream to handle negative time and offset > from Epoch This is causing ptest failures for both qemux86-64 and qemuarm64: https://autobuilder.yoctoproject.org/typhoon/#/builders/82/builds/2970 https://autobuilder.yoctoproject.org/typhoon/#/builders/81/builds/3231 'babeltrace': ['bin/intersection/test_intersection_2_- _3_events_in_packets_intersecting', 'bin/intersection/test_intersection_4_- _3_events_in_packets_intersecting', 'bin/intersection/test_intersection_6_- _0_events_in_packets_intersecting'], Thanks, Anuj > > Signed-off-by: He Zhe <zhe.he@windriver.com> > --- > ...-negative-time-and-offset-from-Epoch.patch | 853 > ++++++++++++++++++ > meta/recipes-kernel/lttng/babeltrace_1.5.8.bb | 1 + > 2 files changed, 854 insertions(+) > create mode 100644 meta/recipes-kernel/lttng/babeltrace/0001-Handle- > negative-time-and-offset-from-Epoch.patch > > diff --git a/meta/recipes-kernel/lttng/babeltrace/0001-Handle- > negative-time-and-offset-from-Epoch.patch b/meta/recipes- > kernel/lttng/babeltrace/0001-Handle-negative-time-and-offset-from- > Epoch.patch > new file mode 100644 > index 0000000000..37ca698bd8 > --- /dev/null > +++ b/meta/recipes-kernel/lttng/babeltrace/0001-Handle-negative-time- > and-offset-from-Epoch.patch > @@ -0,0 +1,853 @@ > +From 78f62745313a51ebdaa64d4c59131ef87ef00917 Mon Sep 17 00:00:00 > 2001 > +From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> > +Date: Wed, 22 Apr 2020 03:00:02 +0000 > +Subject: [PATCH] Handle negative time and offset from Epoch > + > +Handle cases where a trace have a negative offset from Epoch. > +If Epoch is arbitrary (e.g. embedded system starting at 0, without > any > +network access), the "0" can be used as correlation point between > +various components, and some components could start before the > +correlation point. Therefore, especially in traces where the time is > +meant to be shown in nanoseconds or cycles from the correlation > point, > +it also makes sense to have a negative time value. > + > +It introduces API-breaking changes in the C and Python APIs, since > we > +need to be able to return negative time values, which were > previously > +used as errors (-1ULL). > + > +The --offset and --offset-ns command line parameters can now take > +negative offset (seconds and nanoseconds) values too. > + > +The [sec.ns] format is used as fallback so we don't attempt to pass > +a negative time value to POSIX time-formatting APIs. > + > +This also fixes an inaccurate return value in an error path of > +bt_ctf_event_populate_event_header(). > + > +Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> > +Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com> > + > +Upstream-Status: Backport > [https://git.efficios.com/?p=babeltrace.git;a=commit;h=61cf588beae752 > e5ddfc60b6b5310f769ac9e852] > + > +Signed-off-by: He Zhe <zhe.he@windriver.com> > +--- > + converter/babeltrace.c | 4 +- > + formats/ctf-text/ctf-text.c | 2 +- > + formats/ctf/ctf.c | 115 +++++++++++++-- > --- > + formats/ctf/events-private.h | 10 +- > + formats/ctf/events.c | 11 +- > + .../metadata/ctf-visitor-generate-io-struct.c | 1 - > + include/babeltrace/babeltrace-internal.h | 8 +- > + include/babeltrace/clock-internal.h | 2 +- > + include/babeltrace/ctf-ir/clock-internal.h | 2 +- > + include/babeltrace/ctf/events.h | 8 +- > + include/babeltrace/ctf/types.h | 6 +- > + include/babeltrace/format.h | 10 +- > + include/babeltrace/trace-handle-internal.h | 8 +- > + include/babeltrace/trace-handle.h | 25 ++-- > + lib/context.c | 44 +++++-- > + lib/trace-handle.c | 39 +++--- > + tests/lib/test_ctf_writer.c | 6 +- > + tests/lib/test_seek.c | 28 ++--- > + 18 files changed, 209 insertions(+), 120 deletions(-) > + > +diff --git a/converter/babeltrace.c b/converter/babeltrace.c > +index ef783ed4..2ac16179 100644 > +--- a/converter/babeltrace.c > ++++ b/converter/babeltrace.c > +@@ -375,7 +375,7 @@ static int parse_options(int argc, char **argv) > + goto end; > + } > + errno = 0; > +- opt_clock_offset = strtoull(str, &endptr, 0); > ++ opt_clock_offset = strtoll(str, &endptr, 0); > + if (*endptr != '\0' || str == endptr || errno > != 0) { > + fprintf(stderr, "[error] Incorrect -- > clock-offset argument: %s\n", str); > + ret = -EINVAL; > +@@ -400,7 +400,7 @@ static int parse_options(int argc, char **argv) > + goto end; > + } > + errno = 0; > +- opt_clock_offset_ns = strtoull(str, &endptr, > 0); > ++ opt_clock_offset_ns = strtoll(str, &endptr, > 0); > + if (*endptr != '\0' || str == endptr || errno > != 0) { > + fprintf(stderr, "[error] Incorrect -- > clock-offset-ns argument: %s\n", str); > + ret = -EINVAL; > +diff --git a/formats/ctf-text/ctf-text.c b/formats/ctf-text/ctf- > text.c > +index 16f156de..e001a548 100644 > +--- a/formats/ctf-text/ctf-text.c > ++++ b/formats/ctf-text/ctf-text.c > +@@ -43,7 +43,7 @@ > + #include <unistd.h> > + #include <stdlib.h> > + > +-#define NSEC_PER_SEC 1000000000ULL > ++#define NSEC_PER_SEC 1000000000LL > + > + int opt_all_field_names, > + opt_scope_field_names, > +diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c > +index 1ba9017f..3c774188 100644 > +--- a/formats/ctf/ctf.c > ++++ b/formats/ctf/ctf.c > +@@ -70,7 +70,7 @@ > + */ > + #define WRITE_PACKET_LEN (getpagesize() * 8 * CHAR_BIT) > + > +-#define NSEC_PER_SEC 1000000000ULL > ++#define NSEC_PER_SEC 1000000000LL > + > + #define INDEX_PATH "./index/%s.idx" > + > +@@ -79,8 +79,8 @@ int opt_clock_cycles, > + opt_clock_date, > + opt_clock_gmt; > + > +-uint64_t opt_clock_offset; > +-uint64_t opt_clock_offset_ns; > ++int64_t opt_clock_offset; > ++int64_t opt_clock_offset_ns; > + > + extern int yydebug; > + char *opt_debug_info_dir; > +@@ -114,11 +114,13 @@ void ctf_set_handle(struct bt_trace_descriptor > *descriptor, > + static > + int ctf_close_trace(struct bt_trace_descriptor *descriptor); > + static > +-uint64_t ctf_timestamp_begin(struct bt_trace_descriptor > *descriptor, > +- struct bt_trace_handle *handle, enum bt_clock_type > type); > ++int ctf_timestamp_begin(struct bt_trace_descriptor *descriptor, > ++ struct bt_trace_handle *handle, enum bt_clock_type > type, > ++ int64_t *timestamp); > + static > +-uint64_t ctf_timestamp_end(struct bt_trace_descriptor *descriptor, > +- struct bt_trace_handle *handle, enum bt_clock_type > type); > ++int ctf_timestamp_end(struct bt_trace_descriptor *descriptor, > ++ struct bt_trace_handle *handle, enum bt_clock_type > type, > ++ int64_t *timestamp); > + static > + int ctf_convert_index_timestamp(struct bt_trace_descriptor *tdp); > + > +@@ -167,17 +169,20 @@ void bt_ctf_hook(void) > + } > + > + static > +-uint64_t ctf_timestamp_begin(struct bt_trace_descriptor > *descriptor, > +- struct bt_trace_handle *handle, enum bt_clock_type > type) > ++int ctf_timestamp_begin(struct bt_trace_descriptor *descriptor, > ++ struct bt_trace_handle *handle, enum bt_clock_type > type, > ++ int64_t *timestamp) > + { > + struct ctf_trace *tin; > +- uint64_t begin = ULLONG_MAX; > +- int i, j; > ++ int64_t begin = LLONG_MAX; > ++ int i, j, ret; > + > + tin = container_of(descriptor, struct ctf_trace, parent); > + > +- if (!tin) > ++ if (!tin || !timestamp) { > ++ ret = -EINVAL; > + goto error; > ++ } > + > + /* for each stream_class */ > + for (i = 0; i < tin->streams->len; i++) { > +@@ -198,8 +203,10 @@ uint64_t ctf_timestamp_begin(struct > bt_trace_descriptor *descriptor, > + parent); > + stream_pos = &cfs->pos; > + > +- if (!stream_pos->packet_index) > ++ if (!stream_pos->packet_index) { > ++ ret = -EINVAL; > + goto error; > ++ } > + > + if (stream_pos->packet_index->len <= 0) > + continue; > +@@ -214,29 +221,38 @@ uint64_t ctf_timestamp_begin(struct > bt_trace_descriptor *descriptor, > + if (index->ts_cycles.timestamp_begin > < begin) > + begin = index- > >ts_cycles.timestamp_begin; > + } else { > ++ ret = -EINVAL; > + goto error; > + } > + } > + } > + > +- return begin; > ++ if (begin == LLONG_MAX) { > ++ ret = -ENOENT; > ++ goto error; > ++ } > ++ *timestamp = begin; > ++ return 0; > + > + error: > +- return -1ULL; > ++ return ret; > + } > + > + static > +-uint64_t ctf_timestamp_end(struct bt_trace_descriptor *descriptor, > +- struct bt_trace_handle *handle, enum bt_clock_type > type) > ++int ctf_timestamp_end(struct bt_trace_descriptor *descriptor, > ++ struct bt_trace_handle *handle, enum bt_clock_type > type, > ++ int64_t *timestamp) > + { > + struct ctf_trace *tin; > +- uint64_t end = 0; > +- int i, j; > ++ int64_t end = LLONG_MIN; > ++ int i, j, ret; > + > + tin = container_of(descriptor, struct ctf_trace, parent); > + > +- if (!tin) > ++ if (!tin || !timestamp) { > ++ ret = -EINVAL; > + goto error; > ++ } > + > + /* for each stream_class */ > + for (i = 0; i < tin->streams->len; i++) { > +@@ -257,8 +273,10 @@ uint64_t ctf_timestamp_end(struct > bt_trace_descriptor *descriptor, > + parent); > + stream_pos = &cfs->pos; > + > +- if (!stream_pos->packet_index) > ++ if (!stream_pos->packet_index) { > ++ ret = -EINVAL; > + goto error; > ++ } > + > + if (stream_pos->packet_index->len <= 0) > + continue; > +@@ -273,15 +291,21 @@ uint64_t ctf_timestamp_end(struct > bt_trace_descriptor *descriptor, > + if (index->ts_cycles.timestamp_end > > end) > + end = index- > >ts_cycles.timestamp_end; > + } else { > ++ ret = -EINVAL; > + goto error; > + } > + } > + } > + > +- return end; > ++ if (end == LLONG_MIN) { > ++ ret = -ENOENT; > ++ goto error; > ++ } > ++ *timestamp = end; > ++ return 0; > + > + error: > +- return -1ULL; > ++ return ret; > + } > + > + /* > +@@ -328,7 +352,9 @@ void ctf_print_timestamp_real(FILE *fp, > + struct ctf_stream_definition *stream, > + uint64_t timestamp) > + { > +- uint64_t ts_sec = 0, ts_nsec; > ++ int64_t ts_sec = 0, ts_nsec; > ++ uint64_t ts_sec_abs, ts_nsec_abs; > ++ bool is_negative; > + > + ts_nsec = timestamp; > + > +@@ -341,9 +367,40 @@ void ctf_print_timestamp_real(FILE *fp, > + ts_sec += ts_nsec / NSEC_PER_SEC; > + ts_nsec = ts_nsec % NSEC_PER_SEC; > + > ++ if (ts_sec >= 0 && ts_nsec >= 0) { > ++ is_negative = false; > ++ ts_sec_abs = ts_sec; > ++ ts_nsec_abs = ts_nsec; > ++ } else if (ts_sec > 0 && ts_nsec < 0) { > ++ is_negative = false; > ++ ts_sec_abs = ts_sec - 1; > ++ ts_nsec_abs = NSEC_PER_SEC + ts_nsec; > ++ } else if (ts_sec == 0 && ts_nsec < 0) { > ++ is_negative = true; > ++ ts_sec_abs = ts_sec; > ++ ts_nsec_abs = -ts_nsec; > ++ } else if (ts_sec < 0 && ts_nsec > 0) { > ++ is_negative = true; > ++ ts_sec_abs = -(ts_sec + 1); > ++ ts_nsec_abs = NSEC_PER_SEC - ts_nsec; > ++ } else if (ts_sec < 0 && ts_nsec == 0) { > ++ is_negative = true; > ++ ts_sec_abs = -ts_sec; > ++ ts_nsec_abs = ts_nsec; > ++ } else { /* (ts_sec < 0 && ts_nsec < 0) */ > ++ is_negative = true; > ++ ts_sec_abs = -ts_sec; > ++ ts_nsec_abs = -ts_nsec; > ++ } > ++ > + if (!opt_clock_seconds) { > + struct tm tm; > +- time_t time_s = (time_t) ts_sec; > ++ time_t time_s = (time_t) ts_sec_abs; > ++ > ++ if (is_negative) { > ++ fprintf(stderr, "[warning] Fallback to > [sec.ns] for printing negative time value. Use --clock-seconds.\n"); > ++ goto seconds; > ++ } > + > + if (!opt_clock_gmt) { > + struct tm *res; > +@@ -377,12 +434,12 @@ void ctf_print_timestamp_real(FILE *fp, > + } > + /* 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); > ++ tm.tm_hour, tm.tm_min, tm.tm_sec, > ts_nsec_abs); > + goto end; > + } > + seconds: > +- fprintf(fp, "%3" PRIu64 ".%09" PRIu64, > +- ts_sec, ts_nsec); > ++ fprintf(fp, "%s%" PRId64 ".%09" PRIu64, > ++ is_negative ? "-" : "", ts_sec_abs, ts_nsec_abs); > + > + end: > + return; > +@@ -401,7 +458,7 @@ void ctf_print_timestamp_cycles(FILE *fp, > + > + void ctf_print_timestamp(FILE *fp, > + struct ctf_stream_definition *stream, > +- uint64_t timestamp) > ++ int64_t timestamp) > + { > + if (opt_clock_cycles) { > + ctf_print_timestamp_cycles(fp, stream, timestamp); > +diff --git a/formats/ctf/events-private.h b/formats/ctf/events- > private.h > +index 9bea75d4..c47fd7d8 100644 > +--- a/formats/ctf/events-private.h > ++++ b/formats/ctf/events-private.h > +@@ -35,20 +35,20 @@ > + #include <babeltrace/clock-internal.h> > + > + static inline > +-uint64_t ctf_get_real_timestamp(struct ctf_stream_definition > *stream, > +- uint64_t timestamp) > ++int64_t ctf_get_real_timestamp(struct ctf_stream_definition > *stream, > ++ uint64_t ts_cycles) > + { > +- uint64_t ts_nsec; > ++ int64_t ts_nsec; > + struct ctf_trace *trace = stream->stream_class->trace; > + struct trace_collection *tc = trace->parent.collection; > +- uint64_t tc_offset; > ++ int64_t tc_offset; > + > + if (tc->clock_use_offset_avg) > + tc_offset = tc->single_clock_offset_avg; > + else > + tc_offset = clock_offset_ns(trace- > >parent.single_clock); > + > +- ts_nsec = clock_cycles_to_ns(stream->current_clock, > timestamp); > ++ ts_nsec = clock_cycles_to_ns(stream->current_clock, > ts_cycles); > + ts_nsec += tc_offset; /* Add offset */ > + return ts_nsec; > + } > +diff --git a/formats/ctf/events.c b/formats/ctf/events.c > +index bd195b93..c5aefd82 100644 > +--- a/formats/ctf/events.c > ++++ b/formats/ctf/events.c > +@@ -315,18 +315,19 @@ int bt_ctf_event_get_handle_id(const struct > bt_ctf_event *ctf_event) > + return ret; > + } > + > +-uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event) > ++int bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event, > int64_t *timestamp) > + { > + const struct ctf_event_definition *event; > + > +- if (!ctf_event) > +- return -1ULL; > ++ if (!ctf_event || !timestamp) > ++ return -1; > + > + event = ctf_event->parent; > + if (event && event->stream->has_timestamp) > +- return event->stream->real_timestamp; > ++ *timestamp = event->stream->real_timestamp; > + else > +- return -1ULL; > ++ return -1; > ++ return 0; > + } > + > + uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *ctf_event) > +diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c > b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c > +index 8d348d66..dd8374fc 100644 > +--- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c > ++++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c > +@@ -219,7 +219,6 @@ int get_unary_signed(struct bt_list_head *head, > int64_t *value) > + > + bt_list_for_each_entry(node, head, siblings) { > + if (node->type != NODE_UNARY_EXPRESSION > +- || node->u.unary_expression.type != > UNARY_UNSIGNED_CONSTANT > + || (node->u.unary_expression.type != > UNARY_UNSIGNED_CONSTANT && node->u.unary_expression.type != > UNARY_SIGNED_CONSTANT) > + || node->u.unary_expression.link != > UNARY_LINK_UNKNOWN > + || i != 0) > +diff --git a/include/babeltrace/babeltrace-internal.h > b/include/babeltrace/babeltrace-internal.h > +index 6f8e2006..3e137e4c 100644 > +--- a/include/babeltrace/babeltrace-internal.h > ++++ b/include/babeltrace/babeltrace-internal.h > +@@ -178,8 +178,8 @@ struct trace_collection { > + GPtrArray *array; /* struct bt_trace_descriptor */ > + GHashTable *clocks; /* struct ctf_clock */ > + > +- uint64_t single_clock_offset_avg; > +- uint64_t offset_first; > ++ int64_t single_clock_offset_avg; > ++ int64_t offset_first; > + int64_t delta_offset_first_sum; > + int offset_nr; > + int clock_use_offset_avg; > +@@ -208,8 +208,8 @@ extern int opt_all_field_names, > + opt_clock_force_correlate, > + opt_debug_info_full_path; > + > +-extern uint64_t opt_clock_offset; > +-extern uint64_t opt_clock_offset_ns; > ++extern int64_t opt_clock_offset; > ++extern int64_t opt_clock_offset_ns; > + extern int babeltrace_ctf_console_output; > + extern char *opt_debug_info_dir; > + extern char *opt_debug_info_target_prefix; > +diff --git a/include/babeltrace/clock-internal.h > b/include/babeltrace/clock-internal.h > +index cd6bdbae..86954b78 100644 > +--- a/include/babeltrace/clock-internal.h > ++++ b/include/babeltrace/clock-internal.h > +@@ -49,7 +49,7 @@ uint64_t clock_cycles_to_ns(struct ctf_clock > *clock, uint64_t cycles) > + * mantissa. > + */ > + static inline > +-uint64_t clock_offset_ns(struct ctf_clock *clock) > ++int64_t clock_offset_ns(struct ctf_clock *clock) > + { > + return clock->offset_s * 1000000000ULL > + + clock_cycles_to_ns(clock, clock->offset); > +diff --git a/include/babeltrace/ctf-ir/clock-internal.h > b/include/babeltrace/ctf-ir/clock-internal.h > +index 75677707..f1e896b6 100644 > +--- a/include/babeltrace/ctf-ir/clock-internal.h > ++++ b/include/babeltrace/ctf-ir/clock-internal.h > +@@ -42,7 +42,7 @@ struct bt_ctf_clock { > + uint64_t precision; > + int64_t offset_s; /* Offset in seconds */ > + int64_t offset; /* Offset in ticks */ > +- uint64_t value; /* Current clock value */ > ++ int64_t value; /* Current clock value */ > + uuid_t uuid; > + int uuid_set; > + int absolute; > +diff --git a/include/babeltrace/ctf/events.h > b/include/babeltrace/ctf/events.h > +index c81d8852..15830a30 100644 > +--- a/include/babeltrace/ctf/events.h > ++++ b/include/babeltrace/ctf/events.h > +@@ -109,10 +109,12 @@ const char *bt_ctf_event_name(const struct > bt_ctf_event *event); > + uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *event); > + > + /* > +- * bt_ctf_get_timestamp: returns the timestamp of the event > offsetted > +- * with the system clock source (in ns) or -1ULL on error > ++ * bt_ctf_get_timestamp: get the timestamp of the event offsetted > ++ * with the system clock source (in ns) in *timestamp. > ++ * > ++ * Return 0 on success, or -1ULL on error. > + */ > +-uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *event); > ++int bt_ctf_get_timestamp(const struct bt_ctf_event *event, int64_t > *timestamp); > + > + /* > + * bt_ctf_get_field_list: obtain the list of fields for compound > type > +diff --git a/include/babeltrace/ctf/types.h > b/include/babeltrace/ctf/types.h > +index 0bc003c8..4b626b39 100644 > +--- a/include/babeltrace/ctf/types.h > ++++ b/include/babeltrace/ctf/types.h > +@@ -46,8 +46,8 @@ > + struct bt_stream_callbacks; > + > + struct packet_index_time { > +- uint64_t timestamp_begin; > +- uint64_t timestamp_end; > ++ int64_t timestamp_begin; > ++ int64_t timestamp_end; > + }; > + > + struct packet_index { > +@@ -253,7 +253,7 @@ int ctf_pos_get_event(struct ctf_stream_pos > *pos) > + } > + > + void ctf_print_timestamp(FILE *fp, struct ctf_stream_definition > *stream, > +- uint64_t timestamp); > ++ int64_t timestamp); > + int ctf_append_trace_metadata(struct bt_trace_descriptor *tdp, > + FILE *metadata_fp); > + void ctf_print_discarded_lost(FILE *fp, struct > ctf_stream_definition *stream); > +diff --git a/include/babeltrace/format.h > b/include/babeltrace/format.h > +index dea8e0e5..bf33a239 100644 > +--- a/include/babeltrace/format.h > ++++ b/include/babeltrace/format.h > +@@ -73,10 +73,12 @@ struct bt_format { > + struct bt_context *ctx); > + void (*set_handle)(struct bt_trace_descriptor *descriptor, > + struct bt_trace_handle *handle); > +- uint64_t (*timestamp_begin)(struct bt_trace_descriptor > *descriptor, > +- struct bt_trace_handle *handle, enum > bt_clock_type type); > +- uint64_t (*timestamp_end)(struct bt_trace_descriptor > *descriptor, > +- struct bt_trace_handle *handle, enum > bt_clock_type type); > ++ int (*timestamp_begin)(struct bt_trace_descriptor > *descriptor, > ++ struct bt_trace_handle *handle, enum > bt_clock_type type, > ++ int64_t *timestamp); > ++ int (*timestamp_end)(struct bt_trace_descriptor > *descriptor, > ++ struct bt_trace_handle *handle, enum > bt_clock_type type, > ++ int64_t *timestamp); > + int (*convert_index_timestamp)(struct bt_trace_descriptor > *descriptor); > + }; > + > +diff --git a/include/babeltrace/trace-handle-internal.h > b/include/babeltrace/trace-handle-internal.h > +index 5e9c1c6a..924c730c 100644 > +--- a/include/babeltrace/trace-handle-internal.h > ++++ b/include/babeltrace/trace-handle-internal.h > +@@ -46,10 +46,10 @@ struct bt_trace_handle { > + struct bt_trace_descriptor *td; > + struct bt_format *format; > + char path[PATH_MAX]; > +- uint64_t real_timestamp_begin; > +- uint64_t real_timestamp_end; > +- uint64_t cycles_timestamp_begin; > +- uint64_t cycles_timestamp_end; > ++ int64_t real_timestamp_begin; > ++ int64_t real_timestamp_end; > ++ int64_t cycles_timestamp_begin; > ++ int64_t cycles_timestamp_end; > + }; > + > + /* > +diff --git a/include/babeltrace/trace-handle.h > b/include/babeltrace/trace-handle.h > +index 96e4a81b..55c850f8 100644 > +--- a/include/babeltrace/trace-handle.h > ++++ b/include/babeltrace/trace-handle.h > +@@ -53,20 +53,25 @@ struct bt_ctf_event; > + const char *bt_trace_handle_get_path(struct bt_context *ctx, int > handle_id); > + > + /* > +- * bt_trace_handle_get_timestamp_begin : returns the creation time > (in > +- * nanoseconds or cycles depending on type) of the buffers of a > trace > +- * or -1ULL on error. > ++ * bt_trace_handle_get_timestamp_begin : get the creation time (in > ++ * nanoseconds or cycles depending on type) of the buffers of a > trace. > ++ * > ++ * Returns 0 on success, -1 on error. > + */ > +-uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context > *ctx, > +- int handle_id, enum bt_clock_type type); > ++int bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, > ++ int handle_id, enum bt_clock_type type, > ++ int64_t *timestamp); > + > + /* > +- * bt_trace_handle_get_timestamp_end : returns the destruction > timestamp > +- * (in nanoseconds or cycles depending on type) of the buffers of a > trace > +- * or -1ULL on error. > ++ * bt_trace_handle_get_timestamp_end : get the destruction time > ++ * (in nanoseconds or cycles depending on type) of the buffers of a > ++ * trace. > ++ * > ++ * Returns 0 on success, -1 on error. > + */ > +-uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx, > +- int handle_id, enum bt_clock_type type); > ++int bt_trace_handle_get_timestamp_end(struct bt_context *ctx, > ++ int handle_id, enum bt_clock_type type, > ++ int64_t *timestamp); > + > + /* > + * bt_ctf_event_get_handle_id : get the handle id associated with > an event > +diff --git a/lib/context.c b/lib/context.c > +index 87901b3c..34a1bc82 100644 > +--- a/lib/context.c > ++++ b/lib/context.c > +@@ -139,18 +139,38 @@ int bt_context_add_trace(struct bt_context > *ctx, const char *path, > + goto error_collection_del; > + } > + > +- if (fmt->timestamp_begin) > +- handle->real_timestamp_begin = fmt- > >timestamp_begin(td, > +- handle, BT_CLOCK_REAL); > +- if (fmt->timestamp_end) > +- handle->real_timestamp_end = fmt->timestamp_end(td, > handle, > +- BT_CLOCK_REAL); > +- if (fmt->timestamp_begin) > +- handle->cycles_timestamp_begin = fmt- > >timestamp_begin(td, > +- handle, BT_CLOCK_CYCLES); > +- if (fmt->timestamp_end) > +- handle->cycles_timestamp_end = fmt->timestamp_end(td, > handle, > +- BT_CLOCK_CYCLES); > ++ if (fmt->timestamp_begin) { > ++ ret = fmt->timestamp_begin(td, handle, > BT_CLOCK_REAL, > ++ &handle->real_timestamp_begin); > ++ if (ret < 0 && ret != -ENOENT) { > ++ ret = -1; > ++ goto error_collection_del; > ++ } > ++ } > ++ if (fmt->timestamp_end) { > ++ ret = fmt->timestamp_end(td, handle, BT_CLOCK_REAL, > ++ &handle->real_timestamp_end); > ++ if (ret < 0 && ret != -ENOENT) { > ++ ret = -1; > ++ goto error_collection_del; > ++ } > ++ } > ++ if (fmt->timestamp_begin) { > ++ ret = fmt->timestamp_begin(td, handle, > BT_CLOCK_CYCLES, > ++ &handle->cycles_timestamp_begin); > ++ if (ret < 0 && ret != -ENOENT) { > ++ ret = -1; > ++ goto error_collection_del; > ++ } > ++ } > ++ if (fmt->timestamp_end) { > ++ ret = fmt->timestamp_end(td, handle, > BT_CLOCK_CYCLES, > ++ &handle->cycles_timestamp_end); > ++ if (ret < 0 && ret != -ENOENT) { > ++ ret = -1; > ++ goto error_collection_del; > ++ } > ++ } > + > + /* Add new handle to container */ > + g_hash_table_insert(ctx->trace_handles, > +diff --git a/lib/trace-handle.c b/lib/trace-handle.c > +index d5b906aa..8f11c7cc 100644 > +--- a/lib/trace-handle.c > ++++ b/lib/trace-handle.c > +@@ -66,54 +66,57 @@ const char *bt_trace_handle_get_path(struct > bt_context *ctx, int handle_id) > + return handle->path; > + } > + > +-uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context > *ctx, > +- int handle_id, enum bt_clock_type type) > ++int bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, > ++ int handle_id, enum bt_clock_type type, > ++ int64_t *timestamp) > + { > + struct bt_trace_handle *handle; > +- uint64_t ret; > + > +- if (!ctx) > +- return -1ULL; > ++ int ret = 0; > ++ > ++ if (!ctx || !timestamp) > ++ return -1; > + > + handle = g_hash_table_lookup(ctx->trace_handles, > + (gpointer) (unsigned long) handle_id); > + if (!handle) { > +- ret = -1ULL; > ++ ret = -1; > + goto end; > + } > + if (type == BT_CLOCK_REAL) { > +- ret = handle->real_timestamp_begin; > ++ *timestamp = handle->real_timestamp_begin; > + } else if (type == BT_CLOCK_CYCLES) { > +- ret = handle->cycles_timestamp_begin; > ++ *timestamp = handle->cycles_timestamp_begin; > + } else { > +- ret = -1ULL; > ++ ret = -1; > + } > + > + end: > + return ret; > + } > + > +-uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx, > +- int handle_id, enum bt_clock_type type) > ++int bt_trace_handle_get_timestamp_end(struct bt_context *ctx, > ++ int handle_id, enum bt_clock_type type, > ++ int64_t *timestamp) > + { > + struct bt_trace_handle *handle; > +- uint64_t ret; > ++ int ret = 0; > + > +- if (!ctx) > +- return -1ULL; > ++ if (!ctx || !timestamp) > ++ return -1; > + > + handle = g_hash_table_lookup(ctx->trace_handles, > + (gpointer) (unsigned long) handle_id); > + if (!handle) { > +- ret = -1ULL; > ++ ret = -1; > + goto end; > + } > + if (type == BT_CLOCK_REAL) { > +- ret = handle->real_timestamp_end; > ++ *timestamp = handle->real_timestamp_end; > + } else if (type == BT_CLOCK_CYCLES) { > +- ret = handle->cycles_timestamp_end; > ++ *timestamp = handle->cycles_timestamp_end; > + } else { > +- ret = -1ULL; > ++ ret = -1; > + } > + > + end: > +diff --git a/tests/lib/test_ctf_writer.c > b/tests/lib/test_ctf_writer.c > +index 53613c91..29d76df8 100644 > +--- a/tests/lib/test_ctf_writer.c > ++++ b/tests/lib/test_ctf_writer.c > +@@ -45,7 +45,7 @@ > + #define SEQUENCE_TEST_LENGTH 10 > + #define PACKET_RESIZE_TEST_LENGTH 100000 > + > +-static uint64_t current_time; > ++static int64_t current_time; > + > + void validate_metadata(char *parser_path, char *metadata_path) > + { > +@@ -695,8 +695,8 @@ int main(int argc, char **argv) > + const char *clock_name = "test_clock"; > + const char *clock_description = "This is a test clock"; > + const uint64_t frequency = 1000000000; > +- const uint64_t offset_s = 1351530929945824323; > +- const uint64_t offset = 1234567; > ++ const int64_t offset_s = 1351530929945824323; > ++ const int64_t offset = 1234567; > + const uint64_t precision = 10; > + char *metadata_string; > + struct bt_ctf_writer *writer; > +diff --git a/tests/lib/test_seek.c b/tests/lib/test_seek.c > +index 3c78e8ad..04beaf97 100644 > +--- a/tests/lib/test_seek.c > ++++ b/tests/lib/test_seek.c > +@@ -33,7 +33,7 @@ > + #include <tap/tap.h> > + #include "common.h" > + > +-#define NR_TESTS 29 > ++#define NR_TESTS 36 > + > + void run_seek_begin(char *path, uint64_t expected_begin) > + { > +@@ -42,8 +42,8 @@ void run_seek_begin(char *path, uint64_t > expected_begin) > + struct bt_ctf_event *event; > + struct bt_iter_pos newpos; > + int ret; > +- uint64_t timestamp_begin; > +- uint64_t timestamp_seek_begin; > ++ int64_t timestamp_begin; > ++ int64_t timestamp_seek_begin; > + unsigned int nr_seek_begin_test; > + > + nr_seek_begin_test = 5; > +@@ -67,7 +67,7 @@ void run_seek_begin(char *path, uint64_t > expected_begin) > + ok(event, "Event valid"); > + > + /* Validate that the first timestamp is right */ > +- timestamp_begin = bt_ctf_get_timestamp(event); > ++ ok1(bt_ctf_get_timestamp(event, ×tamp_begin) == 0); > + > + ok1(timestamp_begin == expected_begin); > + > +@@ -81,8 +81,8 @@ void run_seek_begin(char *path, uint64_t > expected_begin) > + > + ok(event, "Event valid"); > + > +- timestamp_seek_begin = bt_ctf_get_timestamp(event); > +- > ++ ok1(bt_ctf_get_timestamp(event, ×tamp_seek_begin) == 0); > ++ > + ok1(timestamp_begin == timestamp_seek_begin); > + > + bt_context_put(ctx); > +@@ -96,7 +96,7 @@ void run_seek_last(char *path, uint64_t > expected_last) > + struct bt_ctf_event *event; > + struct bt_iter_pos newpos; > + int ret; > +- uint64_t timestamp_last; > ++ int64_t timestamp_last; > + unsigned int nr_seek_last_tests; > + > + nr_seek_last_tests = 6; > +@@ -129,7 +129,7 @@ void run_seek_last(char *path, uint64_t > expected_last) > + > + ok(event, "Event valid at last position"); > + > +- timestamp_last = bt_ctf_get_timestamp(event); > ++ ok1(bt_ctf_get_timestamp(event, ×tamp_last) == 0); > + > + ok1(timestamp_last == expected_last); > + > +@@ -152,7 +152,7 @@ void run_seek_time_at_last(char *path, uint64_t > expected_last) > + struct bt_ctf_event *event; > + struct bt_iter_pos newpos; > + int ret; > +- uint64_t timestamp_last; > ++ int64_t timestamp_last; > + unsigned int nr_seek_time_at_last_tests; > + > + nr_seek_time_at_last_tests = 6; > +@@ -188,7 +188,7 @@ void run_seek_time_at_last(char *path, uint64_t > expected_last) > + > + ok(event, "Event valid at last position"); > + > +- timestamp_last = bt_ctf_get_timestamp(event); > ++ ok1(bt_ctf_get_timestamp(event, ×tamp_last) == 0); > + > + ok1(timestamp_last == expected_last); > + > +@@ -213,7 +213,7 @@ void run_seek_cycles(char *path, > + struct bt_ctf_event *event; > + struct bt_iter_pos newpos; > + int ret; > +- uint64_t timestamp; > ++ int64_t timestamp; > + > + unsigned int nr_seek_cycles_tests; > + > +@@ -247,7 +247,7 @@ void run_seek_cycles(char *path, > + > + ok(event, "Event valid at last position"); > + > +- timestamp = bt_ctf_get_timestamp(event); > ++ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0); > + > + ok1(timestamp == expected_last); > + > +@@ -270,7 +270,7 @@ void run_seek_cycles(char *path, > + > + ok(event, "Event valid at first position"); > + > +- timestamp = bt_ctf_get_timestamp(event); > ++ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0); > + > + ok1(timestamp == expected_begin); > + > +@@ -284,7 +284,7 @@ void run_seek_cycles(char *path, > + > + ok(event, "Event valid at last position"); > + > +- timestamp = bt_ctf_get_timestamp(event); > ++ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0); > + > + ok1(timestamp == expected_last); > + > +-- > +2.25.1 > + > diff --git a/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb > b/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb > index 9e5d3a7a97..86664b14ba 100644 > --- a/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb > +++ b/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb > @@ -9,6 +9,7 @@ DEPENDS = "glib-2.0 util-linux popt bison-native > flex-native" > > SRC_URI = "git://git.efficios.com/babeltrace.git;branch=stable-1.5 \ > file://run-ptest \ > + > file://0001-Handle-negative-time-and-offset-from-Epoch.patch \ > " > SRCREV = "054a54ae10b01a271afc4f19496c041b10fb414c" > UPSTREAM_CHECK_GITTAGREGEX = "v(?P<pver>1(\.\d+)+)$" > > -=-=-=-=-=-=-=-=-=-=-=- > Links: You receive all messages sent to this group. > View/Reply Online (#162952): > https://lists.openembedded.org/g/openembedded-core/message/162952 > Mute This Topic: https://lists.openembedded.org/mt/89657972/3616702 > Group Owner: openembedded-core+owner@lists.openembedded.org > Unsubscribe: > https://lists.openembedded.org/g/openembedded-core/unsub [ > anuj.mittal@intel.com] > -=-=-=-=-=-=-=-=-=-=-=- >
On 3/14/22 15:08, Mittal, Anuj wrote: > On Wed, 2022-03-09 at 16:26 +0800, He Zhe wrote: >> Backport a patch from upstream to handle negative time and offset >> from Epoch > This is causing ptest failures for both qemux86-64 and qemuarm64: > > https://autobuilder.yoctoproject.org/typhoon/#/builders/82/builds/2970 > > https://autobuilder.yoctoproject.org/typhoon/#/builders/81/builds/3231 > > 'babeltrace': ['bin/intersection/test_intersection_2_- > _3_events_in_packets_intersecting', > 'bin/intersection/test_intersection_4_- > _3_events_in_packets_intersecting', > 'bin/intersection/test_intersection_6_- > _0_events_in_packets_intersecting'], OK. We will take a look at this. Thanks. Zhe > > Thanks, > > Anuj > > >> Signed-off-by: He Zhe <zhe.he@windriver.com> >> --- >> ...-negative-time-and-offset-from-Epoch.patch | 853 >> ++++++++++++++++++ >> meta/recipes-kernel/lttng/babeltrace_1.5.8.bb | 1 + >> 2 files changed, 854 insertions(+) >> create mode 100644 meta/recipes-kernel/lttng/babeltrace/0001-Handle- >> negative-time-and-offset-from-Epoch.patch >> >> diff --git a/meta/recipes-kernel/lttng/babeltrace/0001-Handle- >> negative-time-and-offset-from-Epoch.patch b/meta/recipes- >> kernel/lttng/babeltrace/0001-Handle-negative-time-and-offset-from- >> Epoch.patch >> new file mode 100644 >> index 0000000000..37ca698bd8 >> --- /dev/null >> +++ b/meta/recipes-kernel/lttng/babeltrace/0001-Handle-negative-time- >> and-offset-from-Epoch.patch >> @@ -0,0 +1,853 @@ >> +From 78f62745313a51ebdaa64d4c59131ef87ef00917 Mon Sep 17 00:00:00 >> 2001 >> +From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> >> +Date: Wed, 22 Apr 2020 03:00:02 +0000 >> +Subject: [PATCH] Handle negative time and offset from Epoch >> + >> +Handle cases where a trace have a negative offset from Epoch. >> +If Epoch is arbitrary (e.g. embedded system starting at 0, without >> any >> +network access), the "0" can be used as correlation point between >> +various components, and some components could start before the >> +correlation point. Therefore, especially in traces where the time is >> +meant to be shown in nanoseconds or cycles from the correlation >> point, >> +it also makes sense to have a negative time value. >> + >> +It introduces API-breaking changes in the C and Python APIs, since >> we >> +need to be able to return negative time values, which were >> previously >> +used as errors (-1ULL). >> + >> +The --offset and --offset-ns command line parameters can now take >> +negative offset (seconds and nanoseconds) values too. >> + >> +The [sec.ns] format is used as fallback so we don't attempt to pass >> +a negative time value to POSIX time-formatting APIs. >> + >> +This also fixes an inaccurate return value in an error path of >> +bt_ctf_event_populate_event_header(). >> + >> +Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> >> +Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com> >> + >> +Upstream-Status: Backport >> [https://git.efficios.com/?p=babeltrace.git;a=commit;h=61cf588beae752 >> e5ddfc60b6b5310f769ac9e852] >> + >> +Signed-off-by: He Zhe <zhe.he@windriver.com> >> +--- >> + converter/babeltrace.c | 4 +- >> + formats/ctf-text/ctf-text.c | 2 +- >> + formats/ctf/ctf.c | 115 +++++++++++++-- >> --- >> + formats/ctf/events-private.h | 10 +- >> + formats/ctf/events.c | 11 +- >> + .../metadata/ctf-visitor-generate-io-struct.c | 1 - >> + include/babeltrace/babeltrace-internal.h | 8 +- >> + include/babeltrace/clock-internal.h | 2 +- >> + include/babeltrace/ctf-ir/clock-internal.h | 2 +- >> + include/babeltrace/ctf/events.h | 8 +- >> + include/babeltrace/ctf/types.h | 6 +- >> + include/babeltrace/format.h | 10 +- >> + include/babeltrace/trace-handle-internal.h | 8 +- >> + include/babeltrace/trace-handle.h | 25 ++-- >> + lib/context.c | 44 +++++-- >> + lib/trace-handle.c | 39 +++--- >> + tests/lib/test_ctf_writer.c | 6 +- >> + tests/lib/test_seek.c | 28 ++--- >> + 18 files changed, 209 insertions(+), 120 deletions(-) >> + >> +diff --git a/converter/babeltrace.c b/converter/babeltrace.c >> +index ef783ed4..2ac16179 100644 >> +--- a/converter/babeltrace.c >> ++++ b/converter/babeltrace.c >> +@@ -375,7 +375,7 @@ static int parse_options(int argc, char **argv) >> + goto end; >> + } >> + errno = 0; >> +- opt_clock_offset = strtoull(str, &endptr, 0); >> ++ opt_clock_offset = strtoll(str, &endptr, 0); >> + if (*endptr != '\0' || str == endptr || errno >> != 0) { >> + fprintf(stderr, "[error] Incorrect -- >> clock-offset argument: %s\n", str); >> + ret = -EINVAL; >> +@@ -400,7 +400,7 @@ static int parse_options(int argc, char **argv) >> + goto end; >> + } >> + errno = 0; >> +- opt_clock_offset_ns = strtoull(str, &endptr, >> 0); >> ++ opt_clock_offset_ns = strtoll(str, &endptr, >> 0); >> + if (*endptr != '\0' || str == endptr || errno >> != 0) { >> + fprintf(stderr, "[error] Incorrect -- >> clock-offset-ns argument: %s\n", str); >> + ret = -EINVAL; >> +diff --git a/formats/ctf-text/ctf-text.c b/formats/ctf-text/ctf- >> text.c >> +index 16f156de..e001a548 100644 >> +--- a/formats/ctf-text/ctf-text.c >> ++++ b/formats/ctf-text/ctf-text.c >> +@@ -43,7 +43,7 @@ >> + #include <unistd.h> >> + #include <stdlib.h> >> + >> +-#define NSEC_PER_SEC 1000000000ULL >> ++#define NSEC_PER_SEC 1000000000LL >> + >> + int opt_all_field_names, >> + opt_scope_field_names, >> +diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c >> +index 1ba9017f..3c774188 100644 >> +--- a/formats/ctf/ctf.c >> ++++ b/formats/ctf/ctf.c >> +@@ -70,7 +70,7 @@ >> + */ >> + #define WRITE_PACKET_LEN (getpagesize() * 8 * CHAR_BIT) >> + >> +-#define NSEC_PER_SEC 1000000000ULL >> ++#define NSEC_PER_SEC 1000000000LL >> + >> + #define INDEX_PATH "./index/%s.idx" >> + >> +@@ -79,8 +79,8 @@ int opt_clock_cycles, >> + opt_clock_date, >> + opt_clock_gmt; >> + >> +-uint64_t opt_clock_offset; >> +-uint64_t opt_clock_offset_ns; >> ++int64_t opt_clock_offset; >> ++int64_t opt_clock_offset_ns; >> + >> + extern int yydebug; >> + char *opt_debug_info_dir; >> +@@ -114,11 +114,13 @@ void ctf_set_handle(struct bt_trace_descriptor >> *descriptor, >> + static >> + int ctf_close_trace(struct bt_trace_descriptor *descriptor); >> + static >> +-uint64_t ctf_timestamp_begin(struct bt_trace_descriptor >> *descriptor, >> +- struct bt_trace_handle *handle, enum bt_clock_type >> type); >> ++int ctf_timestamp_begin(struct bt_trace_descriptor *descriptor, >> ++ struct bt_trace_handle *handle, enum bt_clock_type >> type, >> ++ int64_t *timestamp); >> + static >> +-uint64_t ctf_timestamp_end(struct bt_trace_descriptor *descriptor, >> +- struct bt_trace_handle *handle, enum bt_clock_type >> type); >> ++int ctf_timestamp_end(struct bt_trace_descriptor *descriptor, >> ++ struct bt_trace_handle *handle, enum bt_clock_type >> type, >> ++ int64_t *timestamp); >> + static >> + int ctf_convert_index_timestamp(struct bt_trace_descriptor *tdp); >> + >> +@@ -167,17 +169,20 @@ void bt_ctf_hook(void) >> + } >> + >> + static >> +-uint64_t ctf_timestamp_begin(struct bt_trace_descriptor >> *descriptor, >> +- struct bt_trace_handle *handle, enum bt_clock_type >> type) >> ++int ctf_timestamp_begin(struct bt_trace_descriptor *descriptor, >> ++ struct bt_trace_handle *handle, enum bt_clock_type >> type, >> ++ int64_t *timestamp) >> + { >> + struct ctf_trace *tin; >> +- uint64_t begin = ULLONG_MAX; >> +- int i, j; >> ++ int64_t begin = LLONG_MAX; >> ++ int i, j, ret; >> + >> + tin = container_of(descriptor, struct ctf_trace, parent); >> + >> +- if (!tin) >> ++ if (!tin || !timestamp) { >> ++ ret = -EINVAL; >> + goto error; >> ++ } >> + >> + /* for each stream_class */ >> + for (i = 0; i < tin->streams->len; i++) { >> +@@ -198,8 +203,10 @@ uint64_t ctf_timestamp_begin(struct >> bt_trace_descriptor *descriptor, >> + parent); >> + stream_pos = &cfs->pos; >> + >> +- if (!stream_pos->packet_index) >> ++ if (!stream_pos->packet_index) { >> ++ ret = -EINVAL; >> + goto error; >> ++ } >> + >> + if (stream_pos->packet_index->len <= 0) >> + continue; >> +@@ -214,29 +221,38 @@ uint64_t ctf_timestamp_begin(struct >> bt_trace_descriptor *descriptor, >> + if (index->ts_cycles.timestamp_begin >> < begin) >> + begin = index- >>> ts_cycles.timestamp_begin; >> + } else { >> ++ ret = -EINVAL; >> + goto error; >> + } >> + } >> + } >> + >> +- return begin; >> ++ if (begin == LLONG_MAX) { >> ++ ret = -ENOENT; >> ++ goto error; >> ++ } >> ++ *timestamp = begin; >> ++ return 0; >> + >> + error: >> +- return -1ULL; >> ++ return ret; >> + } >> + >> + static >> +-uint64_t ctf_timestamp_end(struct bt_trace_descriptor *descriptor, >> +- struct bt_trace_handle *handle, enum bt_clock_type >> type) >> ++int ctf_timestamp_end(struct bt_trace_descriptor *descriptor, >> ++ struct bt_trace_handle *handle, enum bt_clock_type >> type, >> ++ int64_t *timestamp) >> + { >> + struct ctf_trace *tin; >> +- uint64_t end = 0; >> +- int i, j; >> ++ int64_t end = LLONG_MIN; >> ++ int i, j, ret; >> + >> + tin = container_of(descriptor, struct ctf_trace, parent); >> + >> +- if (!tin) >> ++ if (!tin || !timestamp) { >> ++ ret = -EINVAL; >> + goto error; >> ++ } >> + >> + /* for each stream_class */ >> + for (i = 0; i < tin->streams->len; i++) { >> +@@ -257,8 +273,10 @@ uint64_t ctf_timestamp_end(struct >> bt_trace_descriptor *descriptor, >> + parent); >> + stream_pos = &cfs->pos; >> + >> +- if (!stream_pos->packet_index) >> ++ if (!stream_pos->packet_index) { >> ++ ret = -EINVAL; >> + goto error; >> ++ } >> + >> + if (stream_pos->packet_index->len <= 0) >> + continue; >> +@@ -273,15 +291,21 @@ uint64_t ctf_timestamp_end(struct >> bt_trace_descriptor *descriptor, >> + if (index->ts_cycles.timestamp_end > >> end) >> + end = index- >>> ts_cycles.timestamp_end; >> + } else { >> ++ ret = -EINVAL; >> + goto error; >> + } >> + } >> + } >> + >> +- return end; >> ++ if (end == LLONG_MIN) { >> ++ ret = -ENOENT; >> ++ goto error; >> ++ } >> ++ *timestamp = end; >> ++ return 0; >> + >> + error: >> +- return -1ULL; >> ++ return ret; >> + } >> + >> + /* >> +@@ -328,7 +352,9 @@ void ctf_print_timestamp_real(FILE *fp, >> + struct ctf_stream_definition *stream, >> + uint64_t timestamp) >> + { >> +- uint64_t ts_sec = 0, ts_nsec; >> ++ int64_t ts_sec = 0, ts_nsec; >> ++ uint64_t ts_sec_abs, ts_nsec_abs; >> ++ bool is_negative; >> + >> + ts_nsec = timestamp; >> + >> +@@ -341,9 +367,40 @@ void ctf_print_timestamp_real(FILE *fp, >> + ts_sec += ts_nsec / NSEC_PER_SEC; >> + ts_nsec = ts_nsec % NSEC_PER_SEC; >> + >> ++ if (ts_sec >= 0 && ts_nsec >= 0) { >> ++ is_negative = false; >> ++ ts_sec_abs = ts_sec; >> ++ ts_nsec_abs = ts_nsec; >> ++ } else if (ts_sec > 0 && ts_nsec < 0) { >> ++ is_negative = false; >> ++ ts_sec_abs = ts_sec - 1; >> ++ ts_nsec_abs = NSEC_PER_SEC + ts_nsec; >> ++ } else if (ts_sec == 0 && ts_nsec < 0) { >> ++ is_negative = true; >> ++ ts_sec_abs = ts_sec; >> ++ ts_nsec_abs = -ts_nsec; >> ++ } else if (ts_sec < 0 && ts_nsec > 0) { >> ++ is_negative = true; >> ++ ts_sec_abs = -(ts_sec + 1); >> ++ ts_nsec_abs = NSEC_PER_SEC - ts_nsec; >> ++ } else if (ts_sec < 0 && ts_nsec == 0) { >> ++ is_negative = true; >> ++ ts_sec_abs = -ts_sec; >> ++ ts_nsec_abs = ts_nsec; >> ++ } else { /* (ts_sec < 0 && ts_nsec < 0) */ >> ++ is_negative = true; >> ++ ts_sec_abs = -ts_sec; >> ++ ts_nsec_abs = -ts_nsec; >> ++ } >> ++ >> + if (!opt_clock_seconds) { >> + struct tm tm; >> +- time_t time_s = (time_t) ts_sec; >> ++ time_t time_s = (time_t) ts_sec_abs; >> ++ >> ++ if (is_negative) { >> ++ fprintf(stderr, "[warning] Fallback to >> [sec.ns] for printing negative time value. Use --clock-seconds.\n"); >> ++ goto seconds; >> ++ } >> + >> + if (!opt_clock_gmt) { >> + struct tm *res; >> +@@ -377,12 +434,12 @@ void ctf_print_timestamp_real(FILE *fp, >> + } >> + /* 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); >> ++ tm.tm_hour, tm.tm_min, tm.tm_sec, >> ts_nsec_abs); >> + goto end; >> + } >> + seconds: >> +- fprintf(fp, "%3" PRIu64 ".%09" PRIu64, >> +- ts_sec, ts_nsec); >> ++ fprintf(fp, "%s%" PRId64 ".%09" PRIu64, >> ++ is_negative ? "-" : "", ts_sec_abs, ts_nsec_abs); >> + >> + end: >> + return; >> +@@ -401,7 +458,7 @@ void ctf_print_timestamp_cycles(FILE *fp, >> + >> + void ctf_print_timestamp(FILE *fp, >> + struct ctf_stream_definition *stream, >> +- uint64_t timestamp) >> ++ int64_t timestamp) >> + { >> + if (opt_clock_cycles) { >> + ctf_print_timestamp_cycles(fp, stream, timestamp); >> +diff --git a/formats/ctf/events-private.h b/formats/ctf/events- >> private.h >> +index 9bea75d4..c47fd7d8 100644 >> +--- a/formats/ctf/events-private.h >> ++++ b/formats/ctf/events-private.h >> +@@ -35,20 +35,20 @@ >> + #include <babeltrace/clock-internal.h> >> + >> + static inline >> +-uint64_t ctf_get_real_timestamp(struct ctf_stream_definition >> *stream, >> +- uint64_t timestamp) >> ++int64_t ctf_get_real_timestamp(struct ctf_stream_definition >> *stream, >> ++ uint64_t ts_cycles) >> + { >> +- uint64_t ts_nsec; >> ++ int64_t ts_nsec; >> + struct ctf_trace *trace = stream->stream_class->trace; >> + struct trace_collection *tc = trace->parent.collection; >> +- uint64_t tc_offset; >> ++ int64_t tc_offset; >> + >> + if (tc->clock_use_offset_avg) >> + tc_offset = tc->single_clock_offset_avg; >> + else >> + tc_offset = clock_offset_ns(trace- >>> parent.single_clock); >> + >> +- ts_nsec = clock_cycles_to_ns(stream->current_clock, >> timestamp); >> ++ ts_nsec = clock_cycles_to_ns(stream->current_clock, >> ts_cycles); >> + ts_nsec += tc_offset; /* Add offset */ >> + return ts_nsec; >> + } >> +diff --git a/formats/ctf/events.c b/formats/ctf/events.c >> +index bd195b93..c5aefd82 100644 >> +--- a/formats/ctf/events.c >> ++++ b/formats/ctf/events.c >> +@@ -315,18 +315,19 @@ int bt_ctf_event_get_handle_id(const struct >> bt_ctf_event *ctf_event) >> + return ret; >> + } >> + >> +-uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event) >> ++int bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event, >> int64_t *timestamp) >> + { >> + const struct ctf_event_definition *event; >> + >> +- if (!ctf_event) >> +- return -1ULL; >> ++ if (!ctf_event || !timestamp) >> ++ return -1; >> + >> + event = ctf_event->parent; >> + if (event && event->stream->has_timestamp) >> +- return event->stream->real_timestamp; >> ++ *timestamp = event->stream->real_timestamp; >> + else >> +- return -1ULL; >> ++ return -1; >> ++ return 0; >> + } >> + >> + uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *ctf_event) >> +diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c >> b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c >> +index 8d348d66..dd8374fc 100644 >> +--- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c >> ++++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c >> +@@ -219,7 +219,6 @@ int get_unary_signed(struct bt_list_head *head, >> int64_t *value) >> + >> + bt_list_for_each_entry(node, head, siblings) { >> + if (node->type != NODE_UNARY_EXPRESSION >> +- || node->u.unary_expression.type != >> UNARY_UNSIGNED_CONSTANT >> + || (node->u.unary_expression.type != >> UNARY_UNSIGNED_CONSTANT && node->u.unary_expression.type != >> UNARY_SIGNED_CONSTANT) >> + || node->u.unary_expression.link != >> UNARY_LINK_UNKNOWN >> + || i != 0) >> +diff --git a/include/babeltrace/babeltrace-internal.h >> b/include/babeltrace/babeltrace-internal.h >> +index 6f8e2006..3e137e4c 100644 >> +--- a/include/babeltrace/babeltrace-internal.h >> ++++ b/include/babeltrace/babeltrace-internal.h >> +@@ -178,8 +178,8 @@ struct trace_collection { >> + GPtrArray *array; /* struct bt_trace_descriptor */ >> + GHashTable *clocks; /* struct ctf_clock */ >> + >> +- uint64_t single_clock_offset_avg; >> +- uint64_t offset_first; >> ++ int64_t single_clock_offset_avg; >> ++ int64_t offset_first; >> + int64_t delta_offset_first_sum; >> + int offset_nr; >> + int clock_use_offset_avg; >> +@@ -208,8 +208,8 @@ extern int opt_all_field_names, >> + opt_clock_force_correlate, >> + opt_debug_info_full_path; >> + >> +-extern uint64_t opt_clock_offset; >> +-extern uint64_t opt_clock_offset_ns; >> ++extern int64_t opt_clock_offset; >> ++extern int64_t opt_clock_offset_ns; >> + extern int babeltrace_ctf_console_output; >> + extern char *opt_debug_info_dir; >> + extern char *opt_debug_info_target_prefix; >> +diff --git a/include/babeltrace/clock-internal.h >> b/include/babeltrace/clock-internal.h >> +index cd6bdbae..86954b78 100644 >> +--- a/include/babeltrace/clock-internal.h >> ++++ b/include/babeltrace/clock-internal.h >> +@@ -49,7 +49,7 @@ uint64_t clock_cycles_to_ns(struct ctf_clock >> *clock, uint64_t cycles) >> + * mantissa. >> + */ >> + static inline >> +-uint64_t clock_offset_ns(struct ctf_clock *clock) >> ++int64_t clock_offset_ns(struct ctf_clock *clock) >> + { >> + return clock->offset_s * 1000000000ULL >> + + clock_cycles_to_ns(clock, clock->offset); >> +diff --git a/include/babeltrace/ctf-ir/clock-internal.h >> b/include/babeltrace/ctf-ir/clock-internal.h >> +index 75677707..f1e896b6 100644 >> +--- a/include/babeltrace/ctf-ir/clock-internal.h >> ++++ b/include/babeltrace/ctf-ir/clock-internal.h >> +@@ -42,7 +42,7 @@ struct bt_ctf_clock { >> + uint64_t precision; >> + int64_t offset_s; /* Offset in seconds */ >> + int64_t offset; /* Offset in ticks */ >> +- uint64_t value; /* Current clock value */ >> ++ int64_t value; /* Current clock value */ >> + uuid_t uuid; >> + int uuid_set; >> + int absolute; >> +diff --git a/include/babeltrace/ctf/events.h >> b/include/babeltrace/ctf/events.h >> +index c81d8852..15830a30 100644 >> +--- a/include/babeltrace/ctf/events.h >> ++++ b/include/babeltrace/ctf/events.h >> +@@ -109,10 +109,12 @@ const char *bt_ctf_event_name(const struct >> bt_ctf_event *event); >> + uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *event); >> + >> + /* >> +- * bt_ctf_get_timestamp: returns the timestamp of the event >> offsetted >> +- * with the system clock source (in ns) or -1ULL on error >> ++ * bt_ctf_get_timestamp: get the timestamp of the event offsetted >> ++ * with the system clock source (in ns) in *timestamp. >> ++ * >> ++ * Return 0 on success, or -1ULL on error. >> + */ >> +-uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *event); >> ++int bt_ctf_get_timestamp(const struct bt_ctf_event *event, int64_t >> *timestamp); >> + >> + /* >> + * bt_ctf_get_field_list: obtain the list of fields for compound >> type >> +diff --git a/include/babeltrace/ctf/types.h >> b/include/babeltrace/ctf/types.h >> +index 0bc003c8..4b626b39 100644 >> +--- a/include/babeltrace/ctf/types.h >> ++++ b/include/babeltrace/ctf/types.h >> +@@ -46,8 +46,8 @@ >> + struct bt_stream_callbacks; >> + >> + struct packet_index_time { >> +- uint64_t timestamp_begin; >> +- uint64_t timestamp_end; >> ++ int64_t timestamp_begin; >> ++ int64_t timestamp_end; >> + }; >> + >> + struct packet_index { >> +@@ -253,7 +253,7 @@ int ctf_pos_get_event(struct ctf_stream_pos >> *pos) >> + } >> + >> + void ctf_print_timestamp(FILE *fp, struct ctf_stream_definition >> *stream, >> +- uint64_t timestamp); >> ++ int64_t timestamp); >> + int ctf_append_trace_metadata(struct bt_trace_descriptor *tdp, >> + FILE *metadata_fp); >> + void ctf_print_discarded_lost(FILE *fp, struct >> ctf_stream_definition *stream); >> +diff --git a/include/babeltrace/format.h >> b/include/babeltrace/format.h >> +index dea8e0e5..bf33a239 100644 >> +--- a/include/babeltrace/format.h >> ++++ b/include/babeltrace/format.h >> +@@ -73,10 +73,12 @@ struct bt_format { >> + struct bt_context *ctx); >> + void (*set_handle)(struct bt_trace_descriptor *descriptor, >> + struct bt_trace_handle *handle); >> +- uint64_t (*timestamp_begin)(struct bt_trace_descriptor >> *descriptor, >> +- struct bt_trace_handle *handle, enum >> bt_clock_type type); >> +- uint64_t (*timestamp_end)(struct bt_trace_descriptor >> *descriptor, >> +- struct bt_trace_handle *handle, enum >> bt_clock_type type); >> ++ int (*timestamp_begin)(struct bt_trace_descriptor >> *descriptor, >> ++ struct bt_trace_handle *handle, enum >> bt_clock_type type, >> ++ int64_t *timestamp); >> ++ int (*timestamp_end)(struct bt_trace_descriptor >> *descriptor, >> ++ struct bt_trace_handle *handle, enum >> bt_clock_type type, >> ++ int64_t *timestamp); >> + int (*convert_index_timestamp)(struct bt_trace_descriptor >> *descriptor); >> + }; >> + >> +diff --git a/include/babeltrace/trace-handle-internal.h >> b/include/babeltrace/trace-handle-internal.h >> +index 5e9c1c6a..924c730c 100644 >> +--- a/include/babeltrace/trace-handle-internal.h >> ++++ b/include/babeltrace/trace-handle-internal.h >> +@@ -46,10 +46,10 @@ struct bt_trace_handle { >> + struct bt_trace_descriptor *td; >> + struct bt_format *format; >> + char path[PATH_MAX]; >> +- uint64_t real_timestamp_begin; >> +- uint64_t real_timestamp_end; >> +- uint64_t cycles_timestamp_begin; >> +- uint64_t cycles_timestamp_end; >> ++ int64_t real_timestamp_begin; >> ++ int64_t real_timestamp_end; >> ++ int64_t cycles_timestamp_begin; >> ++ int64_t cycles_timestamp_end; >> + }; >> + >> + /* >> +diff --git a/include/babeltrace/trace-handle.h >> b/include/babeltrace/trace-handle.h >> +index 96e4a81b..55c850f8 100644 >> +--- a/include/babeltrace/trace-handle.h >> ++++ b/include/babeltrace/trace-handle.h >> +@@ -53,20 +53,25 @@ struct bt_ctf_event; >> + const char *bt_trace_handle_get_path(struct bt_context *ctx, int >> handle_id); >> + >> + /* >> +- * bt_trace_handle_get_timestamp_begin : returns the creation time >> (in >> +- * nanoseconds or cycles depending on type) of the buffers of a >> trace >> +- * or -1ULL on error. >> ++ * bt_trace_handle_get_timestamp_begin : get the creation time (in >> ++ * nanoseconds or cycles depending on type) of the buffers of a >> trace. >> ++ * >> ++ * Returns 0 on success, -1 on error. >> + */ >> +-uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context >> *ctx, >> +- int handle_id, enum bt_clock_type type); >> ++int bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, >> ++ int handle_id, enum bt_clock_type type, >> ++ int64_t *timestamp); >> + >> + /* >> +- * bt_trace_handle_get_timestamp_end : returns the destruction >> timestamp >> +- * (in nanoseconds or cycles depending on type) of the buffers of a >> trace >> +- * or -1ULL on error. >> ++ * bt_trace_handle_get_timestamp_end : get the destruction time >> ++ * (in nanoseconds or cycles depending on type) of the buffers of a >> ++ * trace. >> ++ * >> ++ * Returns 0 on success, -1 on error. >> + */ >> +-uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx, >> +- int handle_id, enum bt_clock_type type); >> ++int bt_trace_handle_get_timestamp_end(struct bt_context *ctx, >> ++ int handle_id, enum bt_clock_type type, >> ++ int64_t *timestamp); >> + >> + /* >> + * bt_ctf_event_get_handle_id : get the handle id associated with >> an event >> +diff --git a/lib/context.c b/lib/context.c >> +index 87901b3c..34a1bc82 100644 >> +--- a/lib/context.c >> ++++ b/lib/context.c >> +@@ -139,18 +139,38 @@ int bt_context_add_trace(struct bt_context >> *ctx, const char *path, >> + goto error_collection_del; >> + } >> + >> +- if (fmt->timestamp_begin) >> +- handle->real_timestamp_begin = fmt- >>> timestamp_begin(td, >> +- handle, BT_CLOCK_REAL); >> +- if (fmt->timestamp_end) >> +- handle->real_timestamp_end = fmt->timestamp_end(td, >> handle, >> +- BT_CLOCK_REAL); >> +- if (fmt->timestamp_begin) >> +- handle->cycles_timestamp_begin = fmt- >>> timestamp_begin(td, >> +- handle, BT_CLOCK_CYCLES); >> +- if (fmt->timestamp_end) >> +- handle->cycles_timestamp_end = fmt->timestamp_end(td, >> handle, >> +- BT_CLOCK_CYCLES); >> ++ if (fmt->timestamp_begin) { >> ++ ret = fmt->timestamp_begin(td, handle, >> BT_CLOCK_REAL, >> ++ &handle->real_timestamp_begin); >> ++ if (ret < 0 && ret != -ENOENT) { >> ++ ret = -1; >> ++ goto error_collection_del; >> ++ } >> ++ } >> ++ if (fmt->timestamp_end) { >> ++ ret = fmt->timestamp_end(td, handle, BT_CLOCK_REAL, >> ++ &handle->real_timestamp_end); >> ++ if (ret < 0 && ret != -ENOENT) { >> ++ ret = -1; >> ++ goto error_collection_del; >> ++ } >> ++ } >> ++ if (fmt->timestamp_begin) { >> ++ ret = fmt->timestamp_begin(td, handle, >> BT_CLOCK_CYCLES, >> ++ &handle->cycles_timestamp_begin); >> ++ if (ret < 0 && ret != -ENOENT) { >> ++ ret = -1; >> ++ goto error_collection_del; >> ++ } >> ++ } >> ++ if (fmt->timestamp_end) { >> ++ ret = fmt->timestamp_end(td, handle, >> BT_CLOCK_CYCLES, >> ++ &handle->cycles_timestamp_end); >> ++ if (ret < 0 && ret != -ENOENT) { >> ++ �� ret = -1; >> ++ goto error_collection_del; >> ++ } >> ++ } >> + >> + /* Add new handle to container */ >> + g_hash_table_insert(ctx->trace_handles, >> +diff --git a/lib/trace-handle.c b/lib/trace-handle.c >> +index d5b906aa..8f11c7cc 100644 >> +--- a/lib/trace-handle.c >> ++++ b/lib/trace-handle.c >> +@@ -66,54 +66,57 @@ const char *bt_trace_handle_get_path(struct >> bt_context *ctx, int handle_id) >> + return handle->path; >> + } >> + >> +-uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context >> *ctx, >> +- int handle_id, enum bt_clock_type type) >> ++int bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, >> ++ int handle_id, enum bt_clock_type type, >> ++ int64_t *timestamp) >> + { >> + struct bt_trace_handle *handle; >> +- uint64_t ret; >> + >> +- if (!ctx) >> +- return -1ULL; >> ++ int ret = 0; >> ++ >> ++ if (!ctx || !timestamp) >> ++ return -1; >> + >> + handle = g_hash_table_lookup(ctx->trace_handles, >> + (gpointer) (unsigned long) handle_id); >> + if (!handle) { >> +- ret = -1ULL; >> ++ ret = -1; >> + goto end; >> + } >> + if (type == BT_CLOCK_REAL) { >> +- ret = handle->real_timestamp_begin; >> ++ *timestamp = handle->real_timestamp_begin; >> + } else if (type == BT_CLOCK_CYCLES) { >> +- ret = handle->cycles_timestamp_begin; >> ++ *timestamp = handle->cycles_timestamp_begin; >> + } else { >> +- ret = -1ULL; >> ++ ret = -1; >> + } >> + >> + end: >> + return ret; >> + } >> + >> +-uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx, >> +- int handle_id, enum bt_clock_type type) >> ++int bt_trace_handle_get_timestamp_end(struct bt_context *ctx, >> ++ int handle_id, enum bt_clock_type type, >> ++ int64_t *timestamp) >> + { >> + struct bt_trace_handle *handle; >> +- uint64_t ret; >> ++ int ret = 0; >> + >> +- if (!ctx) >> +- return -1ULL; >> ++ if (!ctx || !timestamp) >> ++ return -1; >> + >> + handle = g_hash_table_lookup(ctx->trace_handles, >> + (gpointer) (unsigned long) handle_id); >> + if (!handle) { >> +- ret = -1ULL; >> ++ ret = -1; >> + goto end; >> + } >> + if (type == BT_CLOCK_REAL) { >> +- ret = handle->real_timestamp_end; >> ++ *timestamp = handle->real_timestamp_end; >> + } else if (type == BT_CLOCK_CYCLES) { >> +- ret = handle->cycles_timestamp_end; >> ++ *timestamp = handle->cycles_timestamp_end; >> + } else { >> +- ret = -1ULL; >> ++ ret = -1; >> + } >> + >> + end: >> +diff --git a/tests/lib/test_ctf_writer.c >> b/tests/lib/test_ctf_writer.c >> +index 53613c91..29d76df8 100644 >> +--- a/tests/lib/test_ctf_writer.c >> ++++ b/tests/lib/test_ctf_writer.c >> +@@ -45,7 +45,7 @@ >> + #define SEQUENCE_TEST_LENGTH 10 >> + #define PACKET_RESIZE_TEST_LENGTH 100000 >> + >> +-static uint64_t current_time; >> ++static int64_t current_time; >> + >> + void validate_metadata(char *parser_path, char *metadata_path) >> + { >> +@@ -695,8 +695,8 @@ int main(int argc, char **argv) >> + const char *clock_name = "test_clock"; >> + const char *clock_description = "This is a test clock"; >> + const uint64_t frequency = 1000000000; >> +- const uint64_t offset_s = 1351530929945824323; >> +- const uint64_t offset = 1234567; >> ++ const int64_t offset_s = 1351530929945824323; >> ++ const int64_t offset = 1234567; >> + const uint64_t precision = 10; >> + char *metadata_string; >> + struct bt_ctf_writer *writer; >> +diff --git a/tests/lib/test_seek.c b/tests/lib/test_seek.c >> +index 3c78e8ad..04beaf97 100644 >> +--- a/tests/lib/test_seek.c >> ++++ b/tests/lib/test_seek.c >> +@@ -33,7 +33,7 @@ >> + #include <tap/tap.h> >> + #include "common.h" >> + >> +-#define NR_TESTS 29 >> ++#define NR_TESTS 36 >> + >> + void run_seek_begin(char *path, uint64_t expected_begin) >> + { >> +@@ -42,8 +42,8 @@ void run_seek_begin(char *path, uint64_t >> expected_begin) >> + struct bt_ctf_event *event; >> + struct bt_iter_pos newpos; >> + int ret; >> +- uint64_t timestamp_begin; >> +- uint64_t timestamp_seek_begin; >> ++ int64_t timestamp_begin; >> ++ int64_t timestamp_seek_begin; >> + unsigned int nr_seek_begin_test; >> + >> + nr_seek_begin_test = 5; >> +@@ -67,7 +67,7 @@ void run_seek_begin(char *path, uint64_t >> expected_begin) >> + ok(event, "Event valid"); >> + >> + /* Validate that the first timestamp is right */ >> +- timestamp_begin = bt_ctf_get_timestamp(event); >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp_begin) == 0); >> + >> + ok1(timestamp_begin == expected_begin); >> + >> +@@ -81,8 +81,8 @@ void run_seek_begin(char *path, uint64_t >> expected_begin) >> + >> + ok(event, "Event valid"); >> + >> +- timestamp_seek_begin = bt_ctf_get_timestamp(event); >> +- >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp_seek_begin) == 0); >> ++ >> + ok1(timestamp_begin == timestamp_seek_begin); >> + >> + bt_context_put(ctx); >> +@@ -96,7 +96,7 @@ void run_seek_last(char *path, uint64_t >> expected_last) >> + struct bt_ctf_event *event; >> + struct bt_iter_pos newpos; >> + int ret; >> +- uint64_t timestamp_last; >> ++ int64_t timestamp_last; >> + unsigned int nr_seek_last_tests; >> + >> + nr_seek_last_tests = 6; >> +@@ -129,7 +129,7 @@ void run_seek_last(char *path, uint64_t >> expected_last) >> + >> + ok(event, "Event valid at last position"); >> + >> +- timestamp_last = bt_ctf_get_timestamp(event); >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp_last) == 0); >> + >> + ok1(timestamp_last == expected_last); >> + >> +@@ -152,7 +152,7 @@ void run_seek_time_at_last(char *path, uint64_t >> expected_last) >> + struct bt_ctf_event *event; >> + struct bt_iter_pos newpos; >> + int ret; >> +- uint64_t timestamp_last; >> ++ int64_t timestamp_last; >> + unsigned int nr_seek_time_at_last_tests; >> + >> + nr_seek_time_at_last_tests = 6; >> +@@ -188,7 +188,7 @@ void run_seek_time_at_last(char *path, uint64_t >> expected_last) >> + >> + ok(event, "Event valid at last position"); >> + >> +- timestamp_last = bt_ctf_get_timestamp(event); >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp_last) == 0); >> + >> + ok1(timestamp_last == expected_last); >> + >> +@@ -213,7 +213,7 @@ void run_seek_cycles(char *path, >> + struct bt_ctf_event *event; >> + struct bt_iter_pos newpos; >> + int ret; >> +- uint64_t timestamp; >> ++ int64_t timestamp; >> + >> + unsigned int nr_seek_cycles_tests; >> + >> +@@ -247,7 +247,7 @@ void run_seek_cycles(char *path, >> + >> + ok(event, "Event valid at last position"); >> + >> +- timestamp = bt_ctf_get_timestamp(event); >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0); >> + >> + ok1(timestamp == expected_last); >> + >> +@@ -270,7 +270,7 @@ void run_seek_cycles(char *path, >> + >> + ok(event, "Event valid at first position"); >> + >> +- timestamp = bt_ctf_get_timestamp(event); >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0); >> + >> + ok1(timestamp == expected_begin); >> + >> +@@ -284,7 +284,7 @@ void run_seek_cycles(char *path, >> + >> + ok(event, "Event valid at last position"); >> + >> +- timestamp = bt_ctf_get_timestamp(event); >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0); >> + >> + ok1(timestamp == expected_last); >> + >> +-- >> +2.25.1 >> + >> diff --git a/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb >> b/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb >> index 9e5d3a7a97..86664b14ba 100644 >> --- a/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb >> +++ b/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb >> @@ -9,6 +9,7 @@ DEPENDS = "glib-2.0 util-linux popt bison-native >> flex-native" >> >> SRC_URI = "git://git.efficios.com/babeltrace.git;branch=stable-1.5 \ >> file://run-ptest \ >> + >> file://0001-Handle-negative-time-and-offset-from-Epoch.patch \ >> " >> SRCREV = "054a54ae10b01a271afc4f19496c041b10fb414c" >> UPSTREAM_CHECK_GITTAGREGEX = "v(?P<pver>1(\.\d+)+)$" >> >> -=-=-=-=-=-=-=-=-=-=-=- >> Links: You receive all messages sent to this group. >> View/Reply Online (#162952): >> https://lists.openembedded.org/g/openembedded-core/message/162952 >> Mute This Topic: https://lists.openembedded.org/mt/89657972/3616702 >> Group Owner: openembedded-core+owner@lists.openembedded.org >> Unsubscribe: >> https://lists.openembedded.org/g/openembedded-core/unsub [ >> anuj.mittal@intel.com] >> -=-=-=-=-=-=-=-=-=-=-=- >>
On 3/14/22 15:08, Mittal, Anuj wrote: > On Wed, 2022-03-09 at 16:26 +0800, He Zhe wrote: >> Backport a patch from upstream to handle negative time and offset >> from Epoch > This is causing ptest failures for both qemux86-64 and qemuarm64: > > https://autobuilder.yoctoproject.org/typhoon/#/builders/82/builds/2970 > > https://autobuilder.yoctoproject.org/typhoon/#/builders/81/builds/3231 > > 'babeltrace': ['bin/intersection/test_intersection_2_- > _3_events_in_packets_intersecting', > 'bin/intersection/test_intersection_4_- > _3_events_in_packets_intersecting', > 'bin/intersection/test_intersection_6_- > _0_events_in_packets_intersecting'], > > Thanks, OK. We will take a look at this. Thanks. Zhe > > Anuj > > >> Signed-off-by: He Zhe <zhe.he@windriver.com> >> --- >> ...-negative-time-and-offset-from-Epoch.patch | 853 >> ++++++++++++++++++ >> meta/recipes-kernel/lttng/babeltrace_1.5.8.bb | 1 + >> 2 files changed, 854 insertions(+) >> create mode 100644 meta/recipes-kernel/lttng/babeltrace/0001-Handle- >> negative-time-and-offset-from-Epoch.patch >> >> diff --git a/meta/recipes-kernel/lttng/babeltrace/0001-Handle- >> negative-time-and-offset-from-Epoch.patch b/meta/recipes- >> kernel/lttng/babeltrace/0001-Handle-negative-time-and-offset-from- >> Epoch.patch >> new file mode 100644 >> index 0000000000..37ca698bd8 >> --- /dev/null >> +++ b/meta/recipes-kernel/lttng/babeltrace/0001-Handle-negative-time- >> and-offset-from-Epoch.patch >> @@ -0,0 +1,853 @@ >> +From 78f62745313a51ebdaa64d4c59131ef87ef00917 Mon Sep 17 00:00:00 >> 2001 >> +From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> >> +Date: Wed, 22 Apr 2020 03:00:02 +0000 >> +Subject: [PATCH] Handle negative time and offset from Epoch >> + >> +Handle cases where a trace have a negative offset from Epoch. >> +If Epoch is arbitrary (e.g. embedded system starting at 0, without >> any >> +network access), the "0" can be used as correlation point between >> +various components, and some components could start before the >> +correlation point. Therefore, especially in traces where the time is >> +meant to be shown in nanoseconds or cycles from the correlation >> point, >> +it also makes sense to have a negative time value. >> + >> +It introduces API-breaking changes in the C and Python APIs, since >> we >> +need to be able to return negative time values, which were >> previously >> +used as errors (-1ULL). >> + >> +The --offset and --offset-ns command line parameters can now take >> +negative offset (seconds and nanoseconds) values too. >> + >> +The [sec.ns] format is used as fallback so we don't attempt to pass >> +a negative time value to POSIX time-formatting APIs. >> + >> +This also fixes an inaccurate return value in an error path of >> +bt_ctf_event_populate_event_header(). >> + >> +Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> >> +Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com> >> + >> +Upstream-Status: Backport >> [https://git.efficios.com/?p=babeltrace.git;a=commit;h=61cf588beae752 >> e5ddfc60b6b5310f769ac9e852] >> + >> +Signed-off-by: He Zhe <zhe.he@windriver.com> >> +--- >> + converter/babeltrace.c | 4 +- >> + formats/ctf-text/ctf-text.c | 2 +- >> + formats/ctf/ctf.c | 115 +++++++++++++-- >> --- >> + formats/ctf/events-private.h | 10 +- >> + formats/ctf/events.c | 11 +- >> + .../metadata/ctf-visitor-generate-io-struct.c | 1 - >> + include/babeltrace/babeltrace-internal.h | 8 +- >> + include/babeltrace/clock-internal.h | 2 +- >> + include/babeltrace/ctf-ir/clock-internal.h | 2 +- >> + include/babeltrace/ctf/events.h | 8 +- >> + include/babeltrace/ctf/types.h | 6 +- >> + include/babeltrace/format.h | 10 +- >> + include/babeltrace/trace-handle-internal.h | 8 +- >> + include/babeltrace/trace-handle.h | 25 ++-- >> + lib/context.c | 44 +++++-- >> + lib/trace-handle.c | 39 +++--- >> + tests/lib/test_ctf_writer.c | 6 +- >> + tests/lib/test_seek.c | 28 ++--- >> + 18 files changed, 209 insertions(+), 120 deletions(-) >> + >> +diff --git a/converter/babeltrace.c b/converter/babeltrace.c >> +index ef783ed4..2ac16179 100644 >> +--- a/converter/babeltrace.c >> ++++ b/converter/babeltrace.c >> +@@ -375,7 +375,7 @@ static int parse_options(int argc, char **argv) >> + goto end; >> + } >> + errno = 0; >> +- opt_clock_offset = strtoull(str, &endptr, 0); >> ++ opt_clock_offset = strtoll(str, &endptr, 0); >> + if (*endptr != '\0' || str == endptr || errno >> != 0) { >> + fprintf(stderr, "[error] Incorrect -- >> clock-offset argument: %s\n", str); >> + ret = -EINVAL; >> +@@ -400,7 +400,7 @@ static int parse_options(int argc, char **argv) >> + goto end; >> + } >> + errno = 0; >> +- opt_clock_offset_ns = strtoull(str, &endptr, >> 0); >> ++ opt_clock_offset_ns = strtoll(str, &endptr, >> 0); >> + if (*endptr != '\0' || str == endptr || errno >> != 0) { >> + fprintf(stderr, "[error] Incorrect -- >> clock-offset-ns argument: %s\n", str); >> + ret = -EINVAL; >> +diff --git a/formats/ctf-text/ctf-text.c b/formats/ctf-text/ctf- >> text.c >> +index 16f156de..e001a548 100644 >> +--- a/formats/ctf-text/ctf-text.c >> ++++ b/formats/ctf-text/ctf-text.c >> +@@ -43,7 +43,7 @@ >> + #include <unistd.h> >> + #include <stdlib.h> >> + >> +-#define NSEC_PER_SEC 1000000000ULL >> ++#define NSEC_PER_SEC 1000000000LL >> + >> + int opt_all_field_names, >> + opt_scope_field_names, >> +diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c >> +index 1ba9017f..3c774188 100644 >> +--- a/formats/ctf/ctf.c >> ++++ b/formats/ctf/ctf.c >> +@@ -70,7 +70,7 @@ >> + */ >> + #define WRITE_PACKET_LEN (getpagesize() * 8 * CHAR_BIT) >> + >> +-#define NSEC_PER_SEC 1000000000ULL >> ++#define NSEC_PER_SEC 1000000000LL >> + >> + #define INDEX_PATH "./index/%s.idx" >> + >> +@@ -79,8 +79,8 @@ int opt_clock_cycles, >> + opt_clock_date, >> + opt_clock_gmt; >> + >> +-uint64_t opt_clock_offset; >> +-uint64_t opt_clock_offset_ns; >> ++int64_t opt_clock_offset; >> ++int64_t opt_clock_offset_ns; >> + >> + extern int yydebug; >> + char *opt_debug_info_dir; >> +@@ -114,11 +114,13 @@ void ctf_set_handle(struct bt_trace_descriptor >> *descriptor, >> + static >> + int ctf_close_trace(struct bt_trace_descriptor *descriptor); >> + static >> +-uint64_t ctf_timestamp_begin(struct bt_trace_descriptor >> *descriptor, >> +- struct bt_trace_handle *handle, enum bt_clock_type >> type); >> ++int ctf_timestamp_begin(struct bt_trace_descriptor *descriptor, >> ++ struct bt_trace_handle *handle, enum bt_clock_type >> type, >> ++ int64_t *timestamp); >> + static >> +-uint64_t ctf_timestamp_end(struct bt_trace_descriptor *descriptor, >> +- struct bt_trace_handle *handle, enum bt_clock_type >> type); >> ++int ctf_timestamp_end(struct bt_trace_descriptor *descriptor, >> ++ struct bt_trace_handle *handle, enum bt_clock_type >> type, >> ++ int64_t *timestamp); >> + static >> + int ctf_convert_index_timestamp(struct bt_trace_descriptor *tdp); >> + >> +@@ -167,17 +169,20 @@ void bt_ctf_hook(void) >> + } >> + >> + static >> +-uint64_t ctf_timestamp_begin(struct bt_trace_descriptor >> *descriptor, >> +- struct bt_trace_handle *handle, enum bt_clock_type >> type) >> ++int ctf_timestamp_begin(struct bt_trace_descriptor *descriptor, >> ++ struct bt_trace_handle *handle, enum bt_clock_type >> type, >> ++ int64_t *timestamp) >> + { >> + struct ctf_trace *tin; >> +- uint64_t begin = ULLONG_MAX; >> +- int i, j; >> ++ int64_t begin = LLONG_MAX; >> ++ int i, j, ret; >> + >> + tin = container_of(descriptor, struct ctf_trace, parent); >> + >> +- if (!tin) >> ++ if (!tin || !timestamp) { >> ++ ret = -EINVAL; >> + goto error; >> ++ } >> + >> + /* for each stream_class */ >> + for (i = 0; i < tin->streams->len; i++) { >> +@@ -198,8 +203,10 @@ uint64_t ctf_timestamp_begin(struct >> bt_trace_descriptor *descriptor, >> + parent); >> + stream_pos = &cfs->pos; >> + >> +- if (!stream_pos->packet_index) >> ++ if (!stream_pos->packet_index) { >> ++ ret = -EINVAL; >> + goto error; >> ++ } >> + >> + if (stream_pos->packet_index->len <= 0) >> + continue; >> +@@ -214,29 +221,38 @@ uint64_t ctf_timestamp_begin(struct >> bt_trace_descriptor *descriptor, >> + if (index->ts_cycles.timestamp_begin >> < begin) >> + begin = index- >>> ts_cycles.timestamp_begin; >> + } else { >> ++ ret = -EINVAL; >> + goto error; >> + } >> + } >> + } >> + >> +- return begin; >> ++ if (begin == LLONG_MAX) { >> ++ ret = -ENOENT; >> ++ goto error; >> ++ } >> ++ *timestamp = begin; >> ++ return 0; >> + >> + error: >> +- return -1ULL; >> ++ return ret; >> + } >> + >> + static >> +-uint64_t ctf_timestamp_end(struct bt_trace_descriptor *descriptor, >> +- struct bt_trace_handle *handle, enum bt_clock_type >> type) >> ++int ctf_timestamp_end(struct bt_trace_descriptor *descriptor, >> ++ struct bt_trace_handle *handle, enum bt_clock_type >> type, >> ++ int64_t *timestamp) >> + { >> + struct ctf_trace *tin; >> +- uint64_t end = 0; >> +- int i, j; >> ++ int64_t end = LLONG_MIN; >> ++ int i, j, ret; >> + >> + tin = container_of(descriptor, struct ctf_trace, parent); >> + >> +- if (!tin) >> ++ if (!tin || !timestamp) { >> ++ ret = -EINVAL; >> + goto error; >> ++ } >> + >> + /* for each stream_class */ >> + for (i = 0; i < tin->streams->len; i++) { >> +@@ -257,8 +273,10 @@ uint64_t ctf_timestamp_end(struct >> bt_trace_descriptor *descriptor, >> + parent); >> + stream_pos = &cfs->pos; >> + >> +- if (!stream_pos->packet_index) >> ++ if (!stream_pos->packet_index) { >> ++ ret = -EINVAL; >> + goto error; >> ++ } >> + >> + if (stream_pos->packet_index->len <= 0) >> + continue; >> +@@ -273,15 +291,21 @@ uint64_t ctf_timestamp_end(struct >> bt_trace_descriptor *descriptor, >> + if (index->ts_cycles.timestamp_end > >> end) >> + end = index- >>> ts_cycles.timestamp_end; >> + } else { >> ++ ret = -EINVAL; >> + goto error; >> + } >> + } >> + } >> + >> +- return end; >> ++ if (end == LLONG_MIN) { >> ++ ret = -ENOENT; >> ++ goto error; >> ++ } >> ++ *timestamp = end; >> ++ return 0; >> + >> + error: >> +- return -1ULL; >> ++ return ret; >> + } >> + >> + /* >> +@@ -328,7 +352,9 @@ void ctf_print_timestamp_real(FILE *fp, >> + struct ctf_stream_definition *stream, >> + uint64_t timestamp) >> + { >> +- uint64_t ts_sec = 0, ts_nsec; >> ++ int64_t ts_sec = 0, ts_nsec; >> ++ uint64_t ts_sec_abs, ts_nsec_abs; >> ++ bool is_negative; >> + >> + ts_nsec = timestamp; >> + >> +@@ -341,9 +367,40 @@ void ctf_print_timestamp_real(FILE *fp, >> + ts_sec += ts_nsec / NSEC_PER_SEC; >> + ts_nsec = ts_nsec % NSEC_PER_SEC; >> + >> ++ if (ts_sec >= 0 && ts_nsec >= 0) { >> ++ is_negative = false; >> ++ ts_sec_abs = ts_sec; >> ++ ts_nsec_abs = ts_nsec; >> ++ } else if (ts_sec > 0 && ts_nsec < 0) { >> ++ is_negative = false; >> ++ ts_sec_abs = ts_sec - 1; >> ++ ts_nsec_abs = NSEC_PER_SEC + ts_nsec; >> ++ } else if (ts_sec == 0 && ts_nsec < 0) { >> ++ is_negative = true; >> ++ ts_sec_abs = ts_sec; >> ++ ts_nsec_abs = -ts_nsec; >> ++ } else if (ts_sec < 0 && ts_nsec > 0) { >> ++ is_negative = true; >> ++ ts_sec_abs = -(ts_sec + 1); >> ++ ts_nsec_abs = NSEC_PER_SEC - ts_nsec; >> ++ } else if (ts_sec < 0 && ts_nsec == 0) { >> ++ is_negative = true; >> ++ ts_sec_abs = -ts_sec; >> ++ ts_nsec_abs = ts_nsec; >> ++ } else { /* (ts_sec < 0 && ts_nsec < 0) */ >> ++ is_negative = true; >> ++ ts_sec_abs = -ts_sec; >> ++ ts_nsec_abs = -ts_nsec; >> ++ } >> ++ >> + if (!opt_clock_seconds) { >> + struct tm tm; >> +- time_t time_s = (time_t) ts_sec; >> ++ time_t time_s = (time_t) ts_sec_abs; >> ++ >> ++ if (is_negative) { >> ++ fprintf(stderr, "[warning] Fallback to >> [sec.ns] for printing negative time value. Use --clock-seconds.\n"); >> ++ goto seconds; >> ++ } >> + >> + if (!opt_clock_gmt) { >> + struct tm *res; >> +@@ -377,12 +434,12 @@ void ctf_print_timestamp_real(FILE *fp, >> + } >> + /* 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); >> ++ tm.tm_hour, tm.tm_min, tm.tm_sec, >> ts_nsec_abs); >> + goto end; >> + } >> + seconds: >> +- fprintf(fp, "%3" PRIu64 ".%09" PRIu64, >> +- ts_sec, ts_nsec); >> ++ fprintf(fp, "%s%" PRId64 ".%09" PRIu64, >> ++ is_negative ? "-" : "", ts_sec_abs, ts_nsec_abs); >> + >> + end: >> + return; >> +@@ -401,7 +458,7 @@ void ctf_print_timestamp_cycles(FILE *fp, >> + >> + void ctf_print_timestamp(FILE *fp, >> + struct ctf_stream_definition *stream, >> +- uint64_t timestamp) >> ++ int64_t timestamp) >> + { >> + if (opt_clock_cycles) { >> + ctf_print_timestamp_cycles(fp, stream, timestamp); >> +diff --git a/formats/ctf/events-private.h b/formats/ctf/events- >> private.h >> +index 9bea75d4..c47fd7d8 100644 >> +--- a/formats/ctf/events-private.h >> ++++ b/formats/ctf/events-private.h >> +@@ -35,20 +35,20 @@ >> + #include <babeltrace/clock-internal.h> >> + >> + static inline >> +-uint64_t ctf_get_real_timestamp(struct ctf_stream_definition >> *stream, >> +- uint64_t timestamp) >> ++int64_t ctf_get_real_timestamp(struct ctf_stream_definition >> *stream, >> ++ uint64_t ts_cycles) >> + { >> +- uint64_t ts_nsec; >> ++ int64_t ts_nsec; >> + struct ctf_trace *trace = stream->stream_class->trace; >> + struct trace_collection *tc = trace->parent.collection; >> +- uint64_t tc_offset; >> ++ int64_t tc_offset; >> + >> + if (tc->clock_use_offset_avg) >> + tc_offset = tc->single_clock_offset_avg; >> + else >> + tc_offset = clock_offset_ns(trace- >>> parent.single_clock); >> + >> +- ts_nsec = clock_cycles_to_ns(stream->current_clock, >> timestamp); >> ++ ts_nsec = clock_cycles_to_ns(stream->current_clock, >> ts_cycles); >> + ts_nsec += tc_offset; /* Add offset */ >> + return ts_nsec; >> + } >> +diff --git a/formats/ctf/events.c b/formats/ctf/events.c >> +index bd195b93..c5aefd82 100644 >> +--- a/formats/ctf/events.c >> ++++ b/formats/ctf/events.c >> +@@ -315,18 +315,19 @@ int bt_ctf_event_get_handle_id(const struct >> bt_ctf_event *ctf_event) >> + return ret; >> + } >> + >> +-uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event) >> ++int bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event, >> int64_t *timestamp) >> + { >> + const struct ctf_event_definition *event; >> + >> +- if (!ctf_event) >> +- return -1ULL; >> ++ if (!ctf_event || !timestamp) >> ++ return -1; >> + >> + event = ctf_event->parent; >> + if (event && event->stream->has_timestamp) >> +- return event->stream->real_timestamp; >> ++ *timestamp = event->stream->real_timestamp; >> + else >> +- return -1ULL; >> ++ return -1; >> ++ return 0; >> + } >> + >> + uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *ctf_event) >> +diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c >> b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c >> +index 8d348d66..dd8374fc 100644 >> +--- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c >> ++++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c >> +@@ -219,7 +219,6 @@ int get_unary_signed(struct bt_list_head *head, >> int64_t *value) >> + >> + bt_list_for_each_entry(node, head, siblings) { >> + if (node->type != NODE_UNARY_EXPRESSION >> +- || node->u.unary_expression.type != >> UNARY_UNSIGNED_CONSTANT >> + || (node->u.unary_expression.type != >> UNARY_UNSIGNED_CONSTANT && node->u.unary_expression.type != >> UNARY_SIGNED_CONSTANT) >> + || node->u.unary_expression.link != >> UNARY_LINK_UNKNOWN >> + || i != 0) >> +diff --git a/include/babeltrace/babeltrace-internal.h >> b/include/babeltrace/babeltrace-internal.h >> +index 6f8e2006..3e137e4c 100644 >> +--- a/include/babeltrace/babeltrace-internal.h >> ++++ b/include/babeltrace/babeltrace-internal.h >> +@@ -178,8 +178,8 @@ struct trace_collection { >> + GPtrArray *array; /* struct bt_trace_descriptor */ >> + GHashTable *clocks; /* struct ctf_clock */ >> + >> +- uint64_t single_clock_offset_avg; >> +- uint64_t offset_first; >> ++ int64_t single_clock_offset_avg; >> ++ int64_t offset_first; >> + int64_t delta_offset_first_sum; >> + int offset_nr; >> + int clock_use_offset_avg; >> +@@ -208,8 +208,8 @@ extern int opt_all_field_names, >> + opt_clock_force_correlate, >> + opt_debug_info_full_path; >> + >> +-extern uint64_t opt_clock_offset; >> +-extern uint64_t opt_clock_offset_ns; >> ++extern int64_t opt_clock_offset; >> ++extern int64_t opt_clock_offset_ns; >> + extern int babeltrace_ctf_console_output; >> + extern char *opt_debug_info_dir; >> + extern char *opt_debug_info_target_prefix; >> +diff --git a/include/babeltrace/clock-internal.h >> b/include/babeltrace/clock-internal.h >> +index cd6bdbae..86954b78 100644 >> +--- a/include/babeltrace/clock-internal.h >> ++++ b/include/babeltrace/clock-internal.h >> +@@ -49,7 +49,7 @@ uint64_t clock_cycles_to_ns(struct ctf_clock >> *clock, uint64_t cycles) >> + * mantissa. >> + */ >> + static inline >> +-uint64_t clock_offset_ns(struct ctf_clock *clock) >> ++int64_t clock_offset_ns(struct ctf_clock *clock) >> + { >> + return clock->offset_s * 1000000000ULL >> + + clock_cycles_to_ns(clock, clock->offset); >> +diff --git a/include/babeltrace/ctf-ir/clock-internal.h >> b/include/babeltrace/ctf-ir/clock-internal.h >> +index 75677707..f1e896b6 100644 >> +--- a/include/babeltrace/ctf-ir/clock-internal.h >> ++++ b/include/babeltrace/ctf-ir/clock-internal.h >> +@@ -42,7 +42,7 @@ struct bt_ctf_clock { >> + uint64_t precision; >> + int64_t offset_s; /* Offset in seconds */ >> + int64_t offset; /* Offset in ticks */ >> +- uint64_t value; /* Current clock value */ >> ++ int64_t value; /* Current clock value */ >> + uuid_t uuid; >> + int uuid_set; >> + int absolute; >> +diff --git a/include/babeltrace/ctf/events.h >> b/include/babeltrace/ctf/events.h >> +index c81d8852..15830a30 100644 >> +--- a/include/babeltrace/ctf/events.h >> ++++ b/include/babeltrace/ctf/events.h >> +@@ -109,10 +109,12 @@ const char *bt_ctf_event_name(const struct >> bt_ctf_event *event); >> + uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *event); >> + >> + /* >> +- * bt_ctf_get_timestamp: returns the timestamp of the event >> offsetted >> +- * with the system clock source (in ns) or -1ULL on error >> ++ * bt_ctf_get_timestamp: get the timestamp of the event offsetted >> ++ * with the system clock source (in ns) in *timestamp. >> ++ * >> ++ * Return 0 on success, or -1ULL on error. >> + */ >> +-uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *event); >> ++int bt_ctf_get_timestamp(const struct bt_ctf_event *event, int64_t >> *timestamp); >> + >> + /* >> + * bt_ctf_get_field_list: obtain the list of fields for compound >> type >> +diff --git a/include/babeltrace/ctf/types.h >> b/include/babeltrace/ctf/types.h >> +index 0bc003c8..4b626b39 100644 >> +--- a/include/babeltrace/ctf/types.h >> ++++ b/include/babeltrace/ctf/types.h >> +@@ -46,8 +46,8 @@ >> + struct bt_stream_callbacks; >> + >> + struct packet_index_time { >> +- uint64_t timestamp_begin; >> +- uint64_t timestamp_end; >> ++ int64_t timestamp_begin; >> ++ int64_t timestamp_end; >> + }; >> + >> + struct packet_index { >> +@@ -253,7 +253,7 @@ int ctf_pos_get_event(struct ctf_stream_pos >> *pos) >> + } >> + >> + void ctf_print_timestamp(FILE *fp, struct ctf_stream_definition >> *stream, >> +- uint64_t timestamp); >> ++ int64_t timestamp); >> + int ctf_append_trace_metadata(struct bt_trace_descriptor *tdp, >> + FILE *metadata_fp); >> + void ctf_print_discarded_lost(FILE *fp, struct >> ctf_stream_definition *stream); >> +diff --git a/include/babeltrace/format.h >> b/include/babeltrace/format.h >> +index dea8e0e5..bf33a239 100644 >> +--- a/include/babeltrace/format.h >> ++++ b/include/babeltrace/format.h >> +@@ -73,10 +73,12 @@ struct bt_format { >> + struct bt_context *ctx); >> + void (*set_handle)(struct bt_trace_descriptor *descriptor, >> + struct bt_trace_handle *handle); >> +- uint64_t (*timestamp_begin)(struct bt_trace_descriptor >> *descriptor, >> +- struct bt_trace_handle *handle, enum >> bt_clock_type type); >> +- uint64_t (*timestamp_end)(struct bt_trace_descriptor >> *descriptor, >> +- struct bt_trace_handle *handle, enum >> bt_clock_type type); >> ++ int (*timestamp_begin)(struct bt_trace_descriptor >> *descriptor, >> ++ struct bt_trace_handle *handle, enum >> bt_clock_type type, >> ++ int64_t *timestamp); >> ++ int (*timestamp_end)(struct bt_trace_descriptor >> *descriptor, >> ++ struct bt_trace_handle *handle, enum >> bt_clock_type type, >> ++ int64_t *timestamp); >> + int (*convert_index_timestamp)(struct bt_trace_descriptor >> *descriptor); >> + }; >> + >> +diff --git a/include/babeltrace/trace-handle-internal.h >> b/include/babeltrace/trace-handle-internal.h >> +index 5e9c1c6a..924c730c 100644 >> +--- a/include/babeltrace/trace-handle-internal.h >> ++++ b/include/babeltrace/trace-handle-internal.h >> +@@ -46,10 +46,10 @@ struct bt_trace_handle { >> + struct bt_trace_descriptor *td; >> + struct bt_format *format; >> + char path[PATH_MAX]; >> +- uint64_t real_timestamp_begin; >> +- uint64_t real_timestamp_end; >> +- uint64_t cycles_timestamp_begin; >> +- uint64_t cycles_timestamp_end; >> ++ int64_t real_timestamp_begin; >> ++ int64_t real_timestamp_end; >> ++ int64_t cycles_timestamp_begin; >> ++ int64_t cycles_timestamp_end; >> + }; >> + >> + /* >> +diff --git a/include/babeltrace/trace-handle.h >> b/include/babeltrace/trace-handle.h >> +index 96e4a81b..55c850f8 100644 >> +--- a/include/babeltrace/trace-handle.h >> ++++ b/include/babeltrace/trace-handle.h >> +@@ -53,20 +53,25 @@ struct bt_ctf_event; >> + const char *bt_trace_handle_get_path(struct bt_context *ctx, int >> handle_id); >> + >> + /* >> +- * bt_trace_handle_get_timestamp_begin : returns the creation time >> (in >> +- * nanoseconds or cycles depending on type) of the buffers of a >> trace >> +- * or -1ULL on error. >> ++ * bt_trace_handle_get_timestamp_begin : get the creation time (in >> ++ * nanoseconds or cycles depending on type) of the buffers of a >> trace. >> ++ * >> ++ * Returns 0 on success, -1 on error. >> + */ >> +-uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context >> *ctx, >> +- int handle_id, enum bt_clock_type type); >> ++int bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, >> ++ int handle_id, enum bt_clock_type type, >> ++ int64_t *timestamp); >> + >> + /* >> +- * bt_trace_handle_get_timestamp_end : returns the destruction >> timestamp >> +- * (in nanoseconds or cycles depending on type) of the buffers of a >> trace >> +- * or -1ULL on error. >> ++ * bt_trace_handle_get_timestamp_end : get the destruction time >> ++ * (in nanoseconds or cycles depending on type) of the buffers of a >> ++ * trace. >> ++ * >> ++ * Returns 0 on success, -1 on error. >> + */ >> +-uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx, >> +- int handle_id, enum bt_clock_type type); >> ++int bt_trace_handle_get_timestamp_end(struct bt_context *ctx, >> ++ int handle_id, enum bt_clock_type type, >> ++ int64_t *timestamp); >> + >> + /* >> + * bt_ctf_event_get_handle_id : get the handle id associated with >> an event >> +diff --git a/lib/context.c b/lib/context.c >> +index 87901b3c..34a1bc82 100644 >> +--- a/lib/context.c >> ++++ b/lib/context.c >> +@@ -139,18 +139,38 @@ int bt_context_add_trace(struct bt_context >> *ctx, const char *path, >> + goto error_collection_del; >> + } >> + >> +- if (fmt->timestamp_begin) >> +- handle->real_timestamp_begin = fmt- >>> timestamp_begin(td, >> +- handle, BT_CLOCK_REAL); >> +- if (fmt->timestamp_end) >> +- handle->real_timestamp_end = fmt->timestamp_end(td, >> handle, >> +- BT_CLOCK_REAL); >> +- if (fmt->timestamp_begin) >> +- handle->cycles_timestamp_begin = fmt- >>> timestamp_begin(td, >> +- handle, BT_CLOCK_CYCLES); >> +- if (fmt->timestamp_end) >> +- handle->cycles_timestamp_end = fmt->timestamp_end(td, >> handle, >> +- BT_CLOCK_CYCLES); >> ++ if (fmt->timestamp_begin) { >> ++ ret = fmt->timestamp_begin(td, handle, >> BT_CLOCK_REAL, >> ++ &handle->real_timestamp_begin); >> ++ if (ret < 0 && ret != -ENOENT) { >> ++ ret = -1; >> ++ goto error_collection_del; >> ++ } >> ++ } >> ++ if (fmt->timestamp_end) { >> ++ ret = fmt->timestamp_end(td, handle, BT_CLOCK_REAL, >> ++ &handle->real_timestamp_end); >> ++ if (ret < 0 && ret != -ENOENT) { >> ++ ret = -1; >> ++ goto error_collection_del; >> ++ } >> ++ } >> ++ if (fmt->timestamp_begin) { >> ++ ret = fmt->timestamp_begin(td, handle, >> BT_CLOCK_CYCLES, >> ++ &handle->cycles_timestamp_begin); >> ++ if (ret < 0 && ret != -ENOENT) { >> ++ ret = -1; >> ++ goto error_collection_del; >> ++ } >> ++ } >> ++ if (fmt->timestamp_end) { >> ++ ret = fmt->timestamp_end(td, handle, >> BT_CLOCK_CYCLES, >> ++ &handle->cycles_timestamp_end); >> ++ if (ret < 0 && ret != -ENOENT) { >> ++ �� ret = -1; >> ++ goto error_collection_del; >> ++ } >> ++ } >> + >> + /* Add new handle to container */ >> + g_hash_table_insert(ctx->trace_handles, >> +diff --git a/lib/trace-handle.c b/lib/trace-handle.c >> +index d5b906aa..8f11c7cc 100644 >> +--- a/lib/trace-handle.c >> ++++ b/lib/trace-handle.c >> +@@ -66,54 +66,57 @@ const char *bt_trace_handle_get_path(struct >> bt_context *ctx, int handle_id) >> + return handle->path; >> + } >> + >> +-uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context >> *ctx, >> +- int handle_id, enum bt_clock_type type) >> ++int bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, >> ++ int handle_id, enum bt_clock_type type, >> ++ int64_t *timestamp) >> + { >> + struct bt_trace_handle *handle; >> +- uint64_t ret; >> + >> +- if (!ctx) >> +- return -1ULL; >> ++ int ret = 0; >> ++ >> ++ if (!ctx || !timestamp) >> ++ return -1; >> + >> + handle = g_hash_table_lookup(ctx->trace_handles, >> + (gpointer) (unsigned long) handle_id); >> + if (!handle) { >> +- ret = -1ULL; >> ++ ret = -1; >> + goto end; >> + } >> + if (type == BT_CLOCK_REAL) { >> +- ret = handle->real_timestamp_begin; >> ++ *timestamp = handle->real_timestamp_begin; >> + } else if (type == BT_CLOCK_CYCLES) { >> +- ret = handle->cycles_timestamp_begin; >> ++ *timestamp = handle->cycles_timestamp_begin; >> + } else { >> +- ret = -1ULL; >> ++ ret = -1; >> + } >> + >> + end: >> + return ret; >> + } >> + >> +-uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx, >> +- int handle_id, enum bt_clock_type type) >> ++int bt_trace_handle_get_timestamp_end(struct bt_context *ctx, >> ++ int handle_id, enum bt_clock_type type, >> ++ int64_t *timestamp) >> + { >> + struct bt_trace_handle *handle; >> +- uint64_t ret; >> ++ int ret = 0; >> + >> +- if (!ctx) >> +- return -1ULL; >> ++ if (!ctx || !timestamp) >> ++ return -1; >> + >> + handle = g_hash_table_lookup(ctx->trace_handles, >> + (gpointer) (unsigned long) handle_id); >> + if (!handle) { >> +- ret = -1ULL; >> ++ ret = -1; >> + goto end; >> + } >> + if (type == BT_CLOCK_REAL) { >> +- ret = handle->real_timestamp_end; >> ++ *timestamp = handle->real_timestamp_end; >> + } else if (type == BT_CLOCK_CYCLES) { >> +- ret = handle->cycles_timestamp_end; >> ++ *timestamp = handle->cycles_timestamp_end; >> + } else { >> +- ret = -1ULL; >> ++ ret = -1; >> + } >> + >> + end: >> +diff --git a/tests/lib/test_ctf_writer.c >> b/tests/lib/test_ctf_writer.c >> +index 53613c91..29d76df8 100644 >> +--- a/tests/lib/test_ctf_writer.c >> ++++ b/tests/lib/test_ctf_writer.c >> +@@ -45,7 +45,7 @@ >> + #define SEQUENCE_TEST_LENGTH 10 >> + #define PACKET_RESIZE_TEST_LENGTH 100000 >> + >> +-static uint64_t current_time; >> ++static int64_t current_time; >> + >> + void validate_metadata(char *parser_path, char *metadata_path) >> + { >> +@@ -695,8 +695,8 @@ int main(int argc, char **argv) >> + const char *clock_name = "test_clock"; >> + const char *clock_description = "This is a test clock"; >> + const uint64_t frequency = 1000000000; >> +- const uint64_t offset_s = 1351530929945824323; >> +- const uint64_t offset = 1234567; >> ++ const int64_t offset_s = 1351530929945824323; >> ++ const int64_t offset = 1234567; >> + const uint64_t precision = 10; >> + char *metadata_string; >> + struct bt_ctf_writer *writer; >> +diff --git a/tests/lib/test_seek.c b/tests/lib/test_seek.c >> +index 3c78e8ad..04beaf97 100644 >> +--- a/tests/lib/test_seek.c >> ++++ b/tests/lib/test_seek.c >> +@@ -33,7 +33,7 @@ >> + #include <tap/tap.h> >> + #include "common.h" >> + >> +-#define NR_TESTS 29 >> ++#define NR_TESTS 36 >> + >> + void run_seek_begin(char *path, uint64_t expected_begin) >> + { >> +@@ -42,8 +42,8 @@ void run_seek_begin(char *path, uint64_t >> expected_begin) >> + struct bt_ctf_event *event; >> + struct bt_iter_pos newpos; >> + int ret; >> +- uint64_t timestamp_begin; >> +- uint64_t timestamp_seek_begin; >> ++ int64_t timestamp_begin; >> ++ int64_t timestamp_seek_begin; >> + unsigned int nr_seek_begin_test; >> + >> + nr_seek_begin_test = 5; >> +@@ -67,7 +67,7 @@ void run_seek_begin(char *path, uint64_t >> expected_begin) >> + ok(event, "Event valid"); >> + >> + /* Validate that the first timestamp is right */ >> +- timestamp_begin = bt_ctf_get_timestamp(event); >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp_begin) == 0); >> + >> + ok1(timestamp_begin == expected_begin); >> + >> +@@ -81,8 +81,8 @@ void run_seek_begin(char *path, uint64_t >> expected_begin) >> + >> + ok(event, "Event valid"); >> + >> +- timestamp_seek_begin = bt_ctf_get_timestamp(event); >> +- >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp_seek_begin) == 0); >> ++ >> + ok1(timestamp_begin == timestamp_seek_begin); >> + >> + bt_context_put(ctx); >> +@@ -96,7 +96,7 @@ void run_seek_last(char *path, uint64_t >> expected_last) >> + struct bt_ctf_event *event; >> + struct bt_iter_pos newpos; >> + int ret; >> +- uint64_t timestamp_last; >> ++ int64_t timestamp_last; >> + unsigned int nr_seek_last_tests; >> + >> + nr_seek_last_tests = 6; >> +@@ -129,7 +129,7 @@ void run_seek_last(char *path, uint64_t >> expected_last) >> + >> + ok(event, "Event valid at last position"); >> + >> +- timestamp_last = bt_ctf_get_timestamp(event); >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp_last) == 0); >> + >> + ok1(timestamp_last == expected_last); >> + >> +@@ -152,7 +152,7 @@ void run_seek_time_at_last(char *path, uint64_t >> expected_last) >> + struct bt_ctf_event *event; >> + struct bt_iter_pos newpos; >> + int ret; >> +- uint64_t timestamp_last; >> ++ int64_t timestamp_last; >> + unsigned int nr_seek_time_at_last_tests; >> + >> + nr_seek_time_at_last_tests = 6; >> +@@ -188,7 +188,7 @@ void run_seek_time_at_last(char *path, uint64_t >> expected_last) >> + >> + ok(event, "Event valid at last position"); >> + >> +- timestamp_last = bt_ctf_get_timestamp(event); >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp_last) == 0); >> + >> + ok1(timestamp_last == expected_last); >> + >> +@@ -213,7 +213,7 @@ void run_seek_cycles(char *path, >> + struct bt_ctf_event *event; >> + struct bt_iter_pos newpos; >> + int ret; >> +- uint64_t timestamp; >> ++ int64_t timestamp; >> + >> + unsigned int nr_seek_cycles_tests; >> + >> +@@ -247,7 +247,7 @@ void run_seek_cycles(char *path, >> + >> + ok(event, "Event valid at last position"); >> + >> +- timestamp = bt_ctf_get_timestamp(event); >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0); >> + >> + ok1(timestamp == expected_last); >> + >> +@@ -270,7 +270,7 @@ void run_seek_cycles(char *path, >> + >> + ok(event, "Event valid at first position"); >> + >> +- timestamp = bt_ctf_get_timestamp(event); >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0); >> + >> + ok1(timestamp == expected_begin); >> + >> +@@ -284,7 +284,7 @@ void run_seek_cycles(char *path, >> + >> + ok(event, "Event valid at last position"); >> + >> +- timestamp = bt_ctf_get_timestamp(event); >> ++ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0); >> + >> + ok1(timestamp == expected_last); >> + >> +-- >> +2.25.1 >> + >> diff --git a/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb >> b/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb >> index 9e5d3a7a97..86664b14ba 100644 >> --- a/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb >> +++ b/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb >> @@ -9,6 +9,7 @@ DEPENDS = "glib-2.0 util-linux popt bison-native >> flex-native" >> >> SRC_URI = "git://git.efficios.com/babeltrace.git;branch=stable-1.5 \ >> file://run-ptest \ >> + >> file://0001-Handle-negative-time-and-offset-from-Epoch.patch \ >> " >> SRCREV = "054a54ae10b01a271afc4f19496c041b10fb414c" >> UPSTREAM_CHECK_GITTAGREGEX = "v(?P<pver>1(\.\d+)+)$" >> >> -=-=-=-=-=-=-=-=-=-=-=- >> Links: You receive all messages sent to this group. >> View/Reply Online (#162952): >> https://lists.openembedded.org/g/openembedded-core/message/162952 >> Mute This Topic: https://lists.openembedded.org/mt/89657972/3616702 >> Group Owner: openembedded-core+owner@lists.openembedded.org >> Unsubscribe: >> https://lists.openembedded.org/g/openembedded-core/unsub [ >> anuj.mittal@intel.com] >> -=-=-=-=-=-=-=-=-=-=-=- >>
diff --git a/meta/recipes-kernel/lttng/babeltrace/0001-Handle-negative-time-and-offset-from-Epoch.patch b/meta/recipes-kernel/lttng/babeltrace/0001-Handle-negative-time-and-offset-from-Epoch.patch new file mode 100644 index 0000000000..37ca698bd8 --- /dev/null +++ b/meta/recipes-kernel/lttng/babeltrace/0001-Handle-negative-time-and-offset-from-Epoch.patch @@ -0,0 +1,853 @@ +From 78f62745313a51ebdaa64d4c59131ef87ef00917 Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> +Date: Wed, 22 Apr 2020 03:00:02 +0000 +Subject: [PATCH] Handle negative time and offset from Epoch + +Handle cases where a trace have a negative offset from Epoch. +If Epoch is arbitrary (e.g. embedded system starting at 0, without any +network access), the "0" can be used as correlation point between +various components, and some components could start before the +correlation point. Therefore, especially in traces where the time is +meant to be shown in nanoseconds or cycles from the correlation point, +it also makes sense to have a negative time value. + +It introduces API-breaking changes in the C and Python APIs, since we +need to be able to return negative time values, which were previously +used as errors (-1ULL). + +The --offset and --offset-ns command line parameters can now take +negative offset (seconds and nanoseconds) values too. + +The [sec.ns] format is used as fallback so we don't attempt to pass +a negative time value to POSIX time-formatting APIs. + +This also fixes an inaccurate return value in an error path of +bt_ctf_event_populate_event_header(). + +Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> +Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com> + +Upstream-Status: Backport [https://git.efficios.com/?p=babeltrace.git;a=commit;h=61cf588beae752e5ddfc60b6b5310f769ac9e852] + +Signed-off-by: He Zhe <zhe.he@windriver.com> +--- + converter/babeltrace.c | 4 +- + formats/ctf-text/ctf-text.c | 2 +- + formats/ctf/ctf.c | 115 +++++++++++++----- + formats/ctf/events-private.h | 10 +- + formats/ctf/events.c | 11 +- + .../metadata/ctf-visitor-generate-io-struct.c | 1 - + include/babeltrace/babeltrace-internal.h | 8 +- + include/babeltrace/clock-internal.h | 2 +- + include/babeltrace/ctf-ir/clock-internal.h | 2 +- + include/babeltrace/ctf/events.h | 8 +- + include/babeltrace/ctf/types.h | 6 +- + include/babeltrace/format.h | 10 +- + include/babeltrace/trace-handle-internal.h | 8 +- + include/babeltrace/trace-handle.h | 25 ++-- + lib/context.c | 44 +++++-- + lib/trace-handle.c | 39 +++--- + tests/lib/test_ctf_writer.c | 6 +- + tests/lib/test_seek.c | 28 ++--- + 18 files changed, 209 insertions(+), 120 deletions(-) + +diff --git a/converter/babeltrace.c b/converter/babeltrace.c +index ef783ed4..2ac16179 100644 +--- a/converter/babeltrace.c ++++ b/converter/babeltrace.c +@@ -375,7 +375,7 @@ static int parse_options(int argc, char **argv) + goto end; + } + errno = 0; +- opt_clock_offset = strtoull(str, &endptr, 0); ++ opt_clock_offset = strtoll(str, &endptr, 0); + if (*endptr != '\0' || str == endptr || errno != 0) { + fprintf(stderr, "[error] Incorrect --clock-offset argument: %s\n", str); + ret = -EINVAL; +@@ -400,7 +400,7 @@ static int parse_options(int argc, char **argv) + goto end; + } + errno = 0; +- opt_clock_offset_ns = strtoull(str, &endptr, 0); ++ opt_clock_offset_ns = strtoll(str, &endptr, 0); + if (*endptr != '\0' || str == endptr || errno != 0) { + fprintf(stderr, "[error] Incorrect --clock-offset-ns argument: %s\n", str); + ret = -EINVAL; +diff --git a/formats/ctf-text/ctf-text.c b/formats/ctf-text/ctf-text.c +index 16f156de..e001a548 100644 +--- a/formats/ctf-text/ctf-text.c ++++ b/formats/ctf-text/ctf-text.c +@@ -43,7 +43,7 @@ + #include <unistd.h> + #include <stdlib.h> + +-#define NSEC_PER_SEC 1000000000ULL ++#define NSEC_PER_SEC 1000000000LL + + int opt_all_field_names, + opt_scope_field_names, +diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c +index 1ba9017f..3c774188 100644 +--- a/formats/ctf/ctf.c ++++ b/formats/ctf/ctf.c +@@ -70,7 +70,7 @@ + */ + #define WRITE_PACKET_LEN (getpagesize() * 8 * CHAR_BIT) + +-#define NSEC_PER_SEC 1000000000ULL ++#define NSEC_PER_SEC 1000000000LL + + #define INDEX_PATH "./index/%s.idx" + +@@ -79,8 +79,8 @@ int opt_clock_cycles, + opt_clock_date, + opt_clock_gmt; + +-uint64_t opt_clock_offset; +-uint64_t opt_clock_offset_ns; ++int64_t opt_clock_offset; ++int64_t opt_clock_offset_ns; + + extern int yydebug; + char *opt_debug_info_dir; +@@ -114,11 +114,13 @@ void ctf_set_handle(struct bt_trace_descriptor *descriptor, + static + int ctf_close_trace(struct bt_trace_descriptor *descriptor); + static +-uint64_t ctf_timestamp_begin(struct bt_trace_descriptor *descriptor, +- struct bt_trace_handle *handle, enum bt_clock_type type); ++int ctf_timestamp_begin(struct bt_trace_descriptor *descriptor, ++ struct bt_trace_handle *handle, enum bt_clock_type type, ++ int64_t *timestamp); + static +-uint64_t ctf_timestamp_end(struct bt_trace_descriptor *descriptor, +- struct bt_trace_handle *handle, enum bt_clock_type type); ++int ctf_timestamp_end(struct bt_trace_descriptor *descriptor, ++ struct bt_trace_handle *handle, enum bt_clock_type type, ++ int64_t *timestamp); + static + int ctf_convert_index_timestamp(struct bt_trace_descriptor *tdp); + +@@ -167,17 +169,20 @@ void bt_ctf_hook(void) + } + + static +-uint64_t ctf_timestamp_begin(struct bt_trace_descriptor *descriptor, +- struct bt_trace_handle *handle, enum bt_clock_type type) ++int ctf_timestamp_begin(struct bt_trace_descriptor *descriptor, ++ struct bt_trace_handle *handle, enum bt_clock_type type, ++ int64_t *timestamp) + { + struct ctf_trace *tin; +- uint64_t begin = ULLONG_MAX; +- int i, j; ++ int64_t begin = LLONG_MAX; ++ int i, j, ret; + + tin = container_of(descriptor, struct ctf_trace, parent); + +- if (!tin) ++ if (!tin || !timestamp) { ++ ret = -EINVAL; + goto error; ++ } + + /* for each stream_class */ + for (i = 0; i < tin->streams->len; i++) { +@@ -198,8 +203,10 @@ uint64_t ctf_timestamp_begin(struct bt_trace_descriptor *descriptor, + parent); + stream_pos = &cfs->pos; + +- if (!stream_pos->packet_index) ++ if (!stream_pos->packet_index) { ++ ret = -EINVAL; + goto error; ++ } + + if (stream_pos->packet_index->len <= 0) + continue; +@@ -214,29 +221,38 @@ uint64_t ctf_timestamp_begin(struct bt_trace_descriptor *descriptor, + if (index->ts_cycles.timestamp_begin < begin) + begin = index->ts_cycles.timestamp_begin; + } else { ++ ret = -EINVAL; + goto error; + } + } + } + +- return begin; ++ if (begin == LLONG_MAX) { ++ ret = -ENOENT; ++ goto error; ++ } ++ *timestamp = begin; ++ return 0; + + error: +- return -1ULL; ++ return ret; + } + + static +-uint64_t ctf_timestamp_end(struct bt_trace_descriptor *descriptor, +- struct bt_trace_handle *handle, enum bt_clock_type type) ++int ctf_timestamp_end(struct bt_trace_descriptor *descriptor, ++ struct bt_trace_handle *handle, enum bt_clock_type type, ++ int64_t *timestamp) + { + struct ctf_trace *tin; +- uint64_t end = 0; +- int i, j; ++ int64_t end = LLONG_MIN; ++ int i, j, ret; + + tin = container_of(descriptor, struct ctf_trace, parent); + +- if (!tin) ++ if (!tin || !timestamp) { ++ ret = -EINVAL; + goto error; ++ } + + /* for each stream_class */ + for (i = 0; i < tin->streams->len; i++) { +@@ -257,8 +273,10 @@ uint64_t ctf_timestamp_end(struct bt_trace_descriptor *descriptor, + parent); + stream_pos = &cfs->pos; + +- if (!stream_pos->packet_index) ++ if (!stream_pos->packet_index) { ++ ret = -EINVAL; + goto error; ++ } + + if (stream_pos->packet_index->len <= 0) + continue; +@@ -273,15 +291,21 @@ uint64_t ctf_timestamp_end(struct bt_trace_descriptor *descriptor, + if (index->ts_cycles.timestamp_end > end) + end = index->ts_cycles.timestamp_end; + } else { ++ ret = -EINVAL; + goto error; + } + } + } + +- return end; ++ if (end == LLONG_MIN) { ++ ret = -ENOENT; ++ goto error; ++ } ++ *timestamp = end; ++ return 0; + + error: +- return -1ULL; ++ return ret; + } + + /* +@@ -328,7 +352,9 @@ void ctf_print_timestamp_real(FILE *fp, + struct ctf_stream_definition *stream, + uint64_t timestamp) + { +- uint64_t ts_sec = 0, ts_nsec; ++ int64_t ts_sec = 0, ts_nsec; ++ uint64_t ts_sec_abs, ts_nsec_abs; ++ bool is_negative; + + ts_nsec = timestamp; + +@@ -341,9 +367,40 @@ void ctf_print_timestamp_real(FILE *fp, + ts_sec += ts_nsec / NSEC_PER_SEC; + ts_nsec = ts_nsec % NSEC_PER_SEC; + ++ if (ts_sec >= 0 && ts_nsec >= 0) { ++ is_negative = false; ++ ts_sec_abs = ts_sec; ++ ts_nsec_abs = ts_nsec; ++ } else if (ts_sec > 0 && ts_nsec < 0) { ++ is_negative = false; ++ ts_sec_abs = ts_sec - 1; ++ ts_nsec_abs = NSEC_PER_SEC + ts_nsec; ++ } else if (ts_sec == 0 && ts_nsec < 0) { ++ is_negative = true; ++ ts_sec_abs = ts_sec; ++ ts_nsec_abs = -ts_nsec; ++ } else if (ts_sec < 0 && ts_nsec > 0) { ++ is_negative = true; ++ ts_sec_abs = -(ts_sec + 1); ++ ts_nsec_abs = NSEC_PER_SEC - ts_nsec; ++ } else if (ts_sec < 0 && ts_nsec == 0) { ++ is_negative = true; ++ ts_sec_abs = -ts_sec; ++ ts_nsec_abs = ts_nsec; ++ } else { /* (ts_sec < 0 && ts_nsec < 0) */ ++ is_negative = true; ++ ts_sec_abs = -ts_sec; ++ ts_nsec_abs = -ts_nsec; ++ } ++ + if (!opt_clock_seconds) { + struct tm tm; +- time_t time_s = (time_t) ts_sec; ++ time_t time_s = (time_t) ts_sec_abs; ++ ++ if (is_negative) { ++ fprintf(stderr, "[warning] Fallback to [sec.ns] for printing negative time value. Use --clock-seconds.\n"); ++ goto seconds; ++ } + + if (!opt_clock_gmt) { + struct tm *res; +@@ -377,12 +434,12 @@ void ctf_print_timestamp_real(FILE *fp, + } + /* 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); ++ tm.tm_hour, tm.tm_min, tm.tm_sec, ts_nsec_abs); + goto end; + } + seconds: +- fprintf(fp, "%3" PRIu64 ".%09" PRIu64, +- ts_sec, ts_nsec); ++ fprintf(fp, "%s%" PRId64 ".%09" PRIu64, ++ is_negative ? "-" : "", ts_sec_abs, ts_nsec_abs); + + end: + return; +@@ -401,7 +458,7 @@ void ctf_print_timestamp_cycles(FILE *fp, + + void ctf_print_timestamp(FILE *fp, + struct ctf_stream_definition *stream, +- uint64_t timestamp) ++ int64_t timestamp) + { + if (opt_clock_cycles) { + ctf_print_timestamp_cycles(fp, stream, timestamp); +diff --git a/formats/ctf/events-private.h b/formats/ctf/events-private.h +index 9bea75d4..c47fd7d8 100644 +--- a/formats/ctf/events-private.h ++++ b/formats/ctf/events-private.h +@@ -35,20 +35,20 @@ + #include <babeltrace/clock-internal.h> + + static inline +-uint64_t ctf_get_real_timestamp(struct ctf_stream_definition *stream, +- uint64_t timestamp) ++int64_t ctf_get_real_timestamp(struct ctf_stream_definition *stream, ++ uint64_t ts_cycles) + { +- uint64_t ts_nsec; ++ int64_t ts_nsec; + struct ctf_trace *trace = stream->stream_class->trace; + struct trace_collection *tc = trace->parent.collection; +- uint64_t tc_offset; ++ int64_t tc_offset; + + if (tc->clock_use_offset_avg) + tc_offset = tc->single_clock_offset_avg; + else + tc_offset = clock_offset_ns(trace->parent.single_clock); + +- ts_nsec = clock_cycles_to_ns(stream->current_clock, timestamp); ++ ts_nsec = clock_cycles_to_ns(stream->current_clock, ts_cycles); + ts_nsec += tc_offset; /* Add offset */ + return ts_nsec; + } +diff --git a/formats/ctf/events.c b/formats/ctf/events.c +index bd195b93..c5aefd82 100644 +--- a/formats/ctf/events.c ++++ b/formats/ctf/events.c +@@ -315,18 +315,19 @@ int bt_ctf_event_get_handle_id(const struct bt_ctf_event *ctf_event) + return ret; + } + +-uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event) ++int bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event, int64_t *timestamp) + { + const struct ctf_event_definition *event; + +- if (!ctf_event) +- return -1ULL; ++ if (!ctf_event || !timestamp) ++ return -1; + + event = ctf_event->parent; + if (event && event->stream->has_timestamp) +- return event->stream->real_timestamp; ++ *timestamp = event->stream->real_timestamp; + else +- return -1ULL; ++ return -1; ++ return 0; + } + + uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *ctf_event) +diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +index 8d348d66..dd8374fc 100644 +--- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c ++++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +@@ -219,7 +219,6 @@ int get_unary_signed(struct bt_list_head *head, int64_t *value) + + bt_list_for_each_entry(node, head, siblings) { + if (node->type != NODE_UNARY_EXPRESSION +- || node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT + || (node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT && node->u.unary_expression.type != UNARY_SIGNED_CONSTANT) + || node->u.unary_expression.link != UNARY_LINK_UNKNOWN + || i != 0) +diff --git a/include/babeltrace/babeltrace-internal.h b/include/babeltrace/babeltrace-internal.h +index 6f8e2006..3e137e4c 100644 +--- a/include/babeltrace/babeltrace-internal.h ++++ b/include/babeltrace/babeltrace-internal.h +@@ -178,8 +178,8 @@ struct trace_collection { + GPtrArray *array; /* struct bt_trace_descriptor */ + GHashTable *clocks; /* struct ctf_clock */ + +- uint64_t single_clock_offset_avg; +- uint64_t offset_first; ++ int64_t single_clock_offset_avg; ++ int64_t offset_first; + int64_t delta_offset_first_sum; + int offset_nr; + int clock_use_offset_avg; +@@ -208,8 +208,8 @@ extern int opt_all_field_names, + opt_clock_force_correlate, + opt_debug_info_full_path; + +-extern uint64_t opt_clock_offset; +-extern uint64_t opt_clock_offset_ns; ++extern int64_t opt_clock_offset; ++extern int64_t opt_clock_offset_ns; + extern int babeltrace_ctf_console_output; + extern char *opt_debug_info_dir; + extern char *opt_debug_info_target_prefix; +diff --git a/include/babeltrace/clock-internal.h b/include/babeltrace/clock-internal.h +index cd6bdbae..86954b78 100644 +--- a/include/babeltrace/clock-internal.h ++++ b/include/babeltrace/clock-internal.h +@@ -49,7 +49,7 @@ uint64_t clock_cycles_to_ns(struct ctf_clock *clock, uint64_t cycles) + * mantissa. + */ + static inline +-uint64_t clock_offset_ns(struct ctf_clock *clock) ++int64_t clock_offset_ns(struct ctf_clock *clock) + { + return clock->offset_s * 1000000000ULL + + clock_cycles_to_ns(clock, clock->offset); +diff --git a/include/babeltrace/ctf-ir/clock-internal.h b/include/babeltrace/ctf-ir/clock-internal.h +index 75677707..f1e896b6 100644 +--- a/include/babeltrace/ctf-ir/clock-internal.h ++++ b/include/babeltrace/ctf-ir/clock-internal.h +@@ -42,7 +42,7 @@ struct bt_ctf_clock { + uint64_t precision; + int64_t offset_s; /* Offset in seconds */ + int64_t offset; /* Offset in ticks */ +- uint64_t value; /* Current clock value */ ++ int64_t value; /* Current clock value */ + uuid_t uuid; + int uuid_set; + int absolute; +diff --git a/include/babeltrace/ctf/events.h b/include/babeltrace/ctf/events.h +index c81d8852..15830a30 100644 +--- a/include/babeltrace/ctf/events.h ++++ b/include/babeltrace/ctf/events.h +@@ -109,10 +109,12 @@ const char *bt_ctf_event_name(const struct bt_ctf_event *event); + uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *event); + + /* +- * bt_ctf_get_timestamp: returns the timestamp of the event offsetted +- * with the system clock source (in ns) or -1ULL on error ++ * bt_ctf_get_timestamp: get the timestamp of the event offsetted ++ * with the system clock source (in ns) in *timestamp. ++ * ++ * Return 0 on success, or -1ULL on error. + */ +-uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *event); ++int bt_ctf_get_timestamp(const struct bt_ctf_event *event, int64_t *timestamp); + + /* + * bt_ctf_get_field_list: obtain the list of fields for compound type +diff --git a/include/babeltrace/ctf/types.h b/include/babeltrace/ctf/types.h +index 0bc003c8..4b626b39 100644 +--- a/include/babeltrace/ctf/types.h ++++ b/include/babeltrace/ctf/types.h +@@ -46,8 +46,8 @@ + struct bt_stream_callbacks; + + struct packet_index_time { +- uint64_t timestamp_begin; +- uint64_t timestamp_end; ++ int64_t timestamp_begin; ++ int64_t timestamp_end; + }; + + struct packet_index { +@@ -253,7 +253,7 @@ int ctf_pos_get_event(struct ctf_stream_pos *pos) + } + + void ctf_print_timestamp(FILE *fp, struct ctf_stream_definition *stream, +- uint64_t timestamp); ++ int64_t timestamp); + int ctf_append_trace_metadata(struct bt_trace_descriptor *tdp, + FILE *metadata_fp); + void ctf_print_discarded_lost(FILE *fp, struct ctf_stream_definition *stream); +diff --git a/include/babeltrace/format.h b/include/babeltrace/format.h +index dea8e0e5..bf33a239 100644 +--- a/include/babeltrace/format.h ++++ b/include/babeltrace/format.h +@@ -73,10 +73,12 @@ struct bt_format { + struct bt_context *ctx); + void (*set_handle)(struct bt_trace_descriptor *descriptor, + struct bt_trace_handle *handle); +- uint64_t (*timestamp_begin)(struct bt_trace_descriptor *descriptor, +- struct bt_trace_handle *handle, enum bt_clock_type type); +- uint64_t (*timestamp_end)(struct bt_trace_descriptor *descriptor, +- struct bt_trace_handle *handle, enum bt_clock_type type); ++ int (*timestamp_begin)(struct bt_trace_descriptor *descriptor, ++ struct bt_trace_handle *handle, enum bt_clock_type type, ++ int64_t *timestamp); ++ int (*timestamp_end)(struct bt_trace_descriptor *descriptor, ++ struct bt_trace_handle *handle, enum bt_clock_type type, ++ int64_t *timestamp); + int (*convert_index_timestamp)(struct bt_trace_descriptor *descriptor); + }; + +diff --git a/include/babeltrace/trace-handle-internal.h b/include/babeltrace/trace-handle-internal.h +index 5e9c1c6a..924c730c 100644 +--- a/include/babeltrace/trace-handle-internal.h ++++ b/include/babeltrace/trace-handle-internal.h +@@ -46,10 +46,10 @@ struct bt_trace_handle { + struct bt_trace_descriptor *td; + struct bt_format *format; + char path[PATH_MAX]; +- uint64_t real_timestamp_begin; +- uint64_t real_timestamp_end; +- uint64_t cycles_timestamp_begin; +- uint64_t cycles_timestamp_end; ++ int64_t real_timestamp_begin; ++ int64_t real_timestamp_end; ++ int64_t cycles_timestamp_begin; ++ int64_t cycles_timestamp_end; + }; + + /* +diff --git a/include/babeltrace/trace-handle.h b/include/babeltrace/trace-handle.h +index 96e4a81b..55c850f8 100644 +--- a/include/babeltrace/trace-handle.h ++++ b/include/babeltrace/trace-handle.h +@@ -53,20 +53,25 @@ struct bt_ctf_event; + const char *bt_trace_handle_get_path(struct bt_context *ctx, int handle_id); + + /* +- * bt_trace_handle_get_timestamp_begin : returns the creation time (in +- * nanoseconds or cycles depending on type) of the buffers of a trace +- * or -1ULL on error. ++ * bt_trace_handle_get_timestamp_begin : get the creation time (in ++ * nanoseconds or cycles depending on type) of the buffers of a trace. ++ * ++ * Returns 0 on success, -1 on error. + */ +-uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, +- int handle_id, enum bt_clock_type type); ++int bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, ++ int handle_id, enum bt_clock_type type, ++ int64_t *timestamp); + + /* +- * bt_trace_handle_get_timestamp_end : returns the destruction timestamp +- * (in nanoseconds or cycles depending on type) of the buffers of a trace +- * or -1ULL on error. ++ * bt_trace_handle_get_timestamp_end : get the destruction time ++ * (in nanoseconds or cycles depending on type) of the buffers of a ++ * trace. ++ * ++ * Returns 0 on success, -1 on error. + */ +-uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx, +- int handle_id, enum bt_clock_type type); ++int bt_trace_handle_get_timestamp_end(struct bt_context *ctx, ++ int handle_id, enum bt_clock_type type, ++ int64_t *timestamp); + + /* + * bt_ctf_event_get_handle_id : get the handle id associated with an event +diff --git a/lib/context.c b/lib/context.c +index 87901b3c..34a1bc82 100644 +--- a/lib/context.c ++++ b/lib/context.c +@@ -139,18 +139,38 @@ int bt_context_add_trace(struct bt_context *ctx, const char *path, + goto error_collection_del; + } + +- if (fmt->timestamp_begin) +- handle->real_timestamp_begin = fmt->timestamp_begin(td, +- handle, BT_CLOCK_REAL); +- if (fmt->timestamp_end) +- handle->real_timestamp_end = fmt->timestamp_end(td, handle, +- BT_CLOCK_REAL); +- if (fmt->timestamp_begin) +- handle->cycles_timestamp_begin = fmt->timestamp_begin(td, +- handle, BT_CLOCK_CYCLES); +- if (fmt->timestamp_end) +- handle->cycles_timestamp_end = fmt->timestamp_end(td, handle, +- BT_CLOCK_CYCLES); ++ if (fmt->timestamp_begin) { ++ ret = fmt->timestamp_begin(td, handle, BT_CLOCK_REAL, ++ &handle->real_timestamp_begin); ++ if (ret < 0 && ret != -ENOENT) { ++ ret = -1; ++ goto error_collection_del; ++ } ++ } ++ if (fmt->timestamp_end) { ++ ret = fmt->timestamp_end(td, handle, BT_CLOCK_REAL, ++ &handle->real_timestamp_end); ++ if (ret < 0 && ret != -ENOENT) { ++ ret = -1; ++ goto error_collection_del; ++ } ++ } ++ if (fmt->timestamp_begin) { ++ ret = fmt->timestamp_begin(td, handle, BT_CLOCK_CYCLES, ++ &handle->cycles_timestamp_begin); ++ if (ret < 0 && ret != -ENOENT) { ++ ret = -1; ++ goto error_collection_del; ++ } ++ } ++ if (fmt->timestamp_end) { ++ ret = fmt->timestamp_end(td, handle, BT_CLOCK_CYCLES, ++ &handle->cycles_timestamp_end); ++ if (ret < 0 && ret != -ENOENT) { ++ ret = -1; ++ goto error_collection_del; ++ } ++ } + + /* Add new handle to container */ + g_hash_table_insert(ctx->trace_handles, +diff --git a/lib/trace-handle.c b/lib/trace-handle.c +index d5b906aa..8f11c7cc 100644 +--- a/lib/trace-handle.c ++++ b/lib/trace-handle.c +@@ -66,54 +66,57 @@ const char *bt_trace_handle_get_path(struct bt_context *ctx, int handle_id) + return handle->path; + } + +-uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, +- int handle_id, enum bt_clock_type type) ++int bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, ++ int handle_id, enum bt_clock_type type, ++ int64_t *timestamp) + { + struct bt_trace_handle *handle; +- uint64_t ret; + +- if (!ctx) +- return -1ULL; ++ int ret = 0; ++ ++ if (!ctx || !timestamp) ++ return -1; + + handle = g_hash_table_lookup(ctx->trace_handles, + (gpointer) (unsigned long) handle_id); + if (!handle) { +- ret = -1ULL; ++ ret = -1; + goto end; + } + if (type == BT_CLOCK_REAL) { +- ret = handle->real_timestamp_begin; ++ *timestamp = handle->real_timestamp_begin; + } else if (type == BT_CLOCK_CYCLES) { +- ret = handle->cycles_timestamp_begin; ++ *timestamp = handle->cycles_timestamp_begin; + } else { +- ret = -1ULL; ++ ret = -1; + } + + end: + return ret; + } + +-uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx, +- int handle_id, enum bt_clock_type type) ++int bt_trace_handle_get_timestamp_end(struct bt_context *ctx, ++ int handle_id, enum bt_clock_type type, ++ int64_t *timestamp) + { + struct bt_trace_handle *handle; +- uint64_t ret; ++ int ret = 0; + +- if (!ctx) +- return -1ULL; ++ if (!ctx || !timestamp) ++ return -1; + + handle = g_hash_table_lookup(ctx->trace_handles, + (gpointer) (unsigned long) handle_id); + if (!handle) { +- ret = -1ULL; ++ ret = -1; + goto end; + } + if (type == BT_CLOCK_REAL) { +- ret = handle->real_timestamp_end; ++ *timestamp = handle->real_timestamp_end; + } else if (type == BT_CLOCK_CYCLES) { +- ret = handle->cycles_timestamp_end; ++ *timestamp = handle->cycles_timestamp_end; + } else { +- ret = -1ULL; ++ ret = -1; + } + + end: +diff --git a/tests/lib/test_ctf_writer.c b/tests/lib/test_ctf_writer.c +index 53613c91..29d76df8 100644 +--- a/tests/lib/test_ctf_writer.c ++++ b/tests/lib/test_ctf_writer.c +@@ -45,7 +45,7 @@ + #define SEQUENCE_TEST_LENGTH 10 + #define PACKET_RESIZE_TEST_LENGTH 100000 + +-static uint64_t current_time; ++static int64_t current_time; + + void validate_metadata(char *parser_path, char *metadata_path) + { +@@ -695,8 +695,8 @@ int main(int argc, char **argv) + const char *clock_name = "test_clock"; + const char *clock_description = "This is a test clock"; + const uint64_t frequency = 1000000000; +- const uint64_t offset_s = 1351530929945824323; +- const uint64_t offset = 1234567; ++ const int64_t offset_s = 1351530929945824323; ++ const int64_t offset = 1234567; + const uint64_t precision = 10; + char *metadata_string; + struct bt_ctf_writer *writer; +diff --git a/tests/lib/test_seek.c b/tests/lib/test_seek.c +index 3c78e8ad..04beaf97 100644 +--- a/tests/lib/test_seek.c ++++ b/tests/lib/test_seek.c +@@ -33,7 +33,7 @@ + #include <tap/tap.h> + #include "common.h" + +-#define NR_TESTS 29 ++#define NR_TESTS 36 + + void run_seek_begin(char *path, uint64_t expected_begin) + { +@@ -42,8 +42,8 @@ void run_seek_begin(char *path, uint64_t expected_begin) + struct bt_ctf_event *event; + struct bt_iter_pos newpos; + int ret; +- uint64_t timestamp_begin; +- uint64_t timestamp_seek_begin; ++ int64_t timestamp_begin; ++ int64_t timestamp_seek_begin; + unsigned int nr_seek_begin_test; + + nr_seek_begin_test = 5; +@@ -67,7 +67,7 @@ void run_seek_begin(char *path, uint64_t expected_begin) + ok(event, "Event valid"); + + /* Validate that the first timestamp is right */ +- timestamp_begin = bt_ctf_get_timestamp(event); ++ ok1(bt_ctf_get_timestamp(event, ×tamp_begin) == 0); + + ok1(timestamp_begin == expected_begin); + +@@ -81,8 +81,8 @@ void run_seek_begin(char *path, uint64_t expected_begin) + + ok(event, "Event valid"); + +- timestamp_seek_begin = bt_ctf_get_timestamp(event); +- ++ ok1(bt_ctf_get_timestamp(event, ×tamp_seek_begin) == 0); ++ + ok1(timestamp_begin == timestamp_seek_begin); + + bt_context_put(ctx); +@@ -96,7 +96,7 @@ void run_seek_last(char *path, uint64_t expected_last) + struct bt_ctf_event *event; + struct bt_iter_pos newpos; + int ret; +- uint64_t timestamp_last; ++ int64_t timestamp_last; + unsigned int nr_seek_last_tests; + + nr_seek_last_tests = 6; +@@ -129,7 +129,7 @@ void run_seek_last(char *path, uint64_t expected_last) + + ok(event, "Event valid at last position"); + +- timestamp_last = bt_ctf_get_timestamp(event); ++ ok1(bt_ctf_get_timestamp(event, ×tamp_last) == 0); + + ok1(timestamp_last == expected_last); + +@@ -152,7 +152,7 @@ void run_seek_time_at_last(char *path, uint64_t expected_last) + struct bt_ctf_event *event; + struct bt_iter_pos newpos; + int ret; +- uint64_t timestamp_last; ++ int64_t timestamp_last; + unsigned int nr_seek_time_at_last_tests; + + nr_seek_time_at_last_tests = 6; +@@ -188,7 +188,7 @@ void run_seek_time_at_last(char *path, uint64_t expected_last) + + ok(event, "Event valid at last position"); + +- timestamp_last = bt_ctf_get_timestamp(event); ++ ok1(bt_ctf_get_timestamp(event, ×tamp_last) == 0); + + ok1(timestamp_last == expected_last); + +@@ -213,7 +213,7 @@ void run_seek_cycles(char *path, + struct bt_ctf_event *event; + struct bt_iter_pos newpos; + int ret; +- uint64_t timestamp; ++ int64_t timestamp; + + unsigned int nr_seek_cycles_tests; + +@@ -247,7 +247,7 @@ void run_seek_cycles(char *path, + + ok(event, "Event valid at last position"); + +- timestamp = bt_ctf_get_timestamp(event); ++ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0); + + ok1(timestamp == expected_last); + +@@ -270,7 +270,7 @@ void run_seek_cycles(char *path, + + ok(event, "Event valid at first position"); + +- timestamp = bt_ctf_get_timestamp(event); ++ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0); + + ok1(timestamp == expected_begin); + +@@ -284,7 +284,7 @@ void run_seek_cycles(char *path, + + ok(event, "Event valid at last position"); + +- timestamp = bt_ctf_get_timestamp(event); ++ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0); + + ok1(timestamp == expected_last); + +-- +2.25.1 + diff --git a/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb b/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb index 9e5d3a7a97..86664b14ba 100644 --- a/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb +++ b/meta/recipes-kernel/lttng/babeltrace_1.5.8.bb @@ -9,6 +9,7 @@ DEPENDS = "glib-2.0 util-linux popt bison-native flex-native" SRC_URI = "git://git.efficios.com/babeltrace.git;branch=stable-1.5 \ file://run-ptest \ + file://0001-Handle-negative-time-and-offset-from-Epoch.patch \ " SRCREV = "054a54ae10b01a271afc4f19496c041b10fb414c" UPSTREAM_CHECK_GITTAGREGEX = "v(?P<pver>1(\.\d+)+)$"
Backport a patch from upstream to handle negative time and offset from Epoch Signed-off-by: He Zhe <zhe.he@windriver.com> --- ...-negative-time-and-offset-from-Epoch.patch | 853 ++++++++++++++++++ meta/recipes-kernel/lttng/babeltrace_1.5.8.bb | 1 + 2 files changed, 854 insertions(+) create mode 100644 meta/recipes-kernel/lttng/babeltrace/0001-Handle-negative-time-and-offset-from-Epoch.patch