From dcb93448766003b5d8d19a57e2dd44efa8ea0035 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 8 Feb 2016 16:38:46 -0500 Subject: [PATCH] Fix: handle negative clock offset In the unlikely situation where a system sets its hardware clock (CLOCK_REALTIME) to 0 (Epoch) after boot, the difference monotonic - realtime becomes negative. Fixup this situation by returning a 0 offset in this case. This ensures that trace viewer implementations (e.g. babeltrace) which currently cannot handle the negative offset (known bug) still work with the generated traces. Signed-off-by: Mathieu Desnoyers --- lttng-events.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lttng-events.c b/lttng-events.c index f0f5d0f8..bd6f44d9 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -2023,12 +2023,15 @@ int _lttng_event_header_declare(struct lttng_session *session) * taken at start of trace. * Yes, this is only an approximation. Yes, we can (and will) do better * in future versions. + * Return 0 if offset is negative. It may happen if the system sets + * the REALTIME clock to 0 after boot. */ static uint64_t measure_clock_offset(void) { - uint64_t offset, monotonic[2], realtime; + uint64_t monotonic_avg, monotonic[2], realtime; uint64_t tcf = trace_clock_freq(); + int64_t offset; struct timespec rts = { 0, 0 }; unsigned long flags; @@ -2039,7 +2042,7 @@ uint64_t measure_clock_offset(void) monotonic[1] = trace_clock_read64(); local_irq_restore(flags); - offset = (monotonic[0] + monotonic[1]) >> 1; + monotonic_avg = (monotonic[0] + monotonic[1]) >> 1; realtime = (uint64_t) rts.tv_sec * tcf; if (tcf == NSEC_PER_SEC) { realtime += rts.tv_nsec; @@ -2049,7 +2052,9 @@ uint64_t measure_clock_offset(void) do_div(n, NSEC_PER_SEC); realtime += n; } - offset = realtime - offset; + offset = (int64_t) realtime - monotonic_avg; + if (offset < 0) + return 0; return offset; } -- 2.34.1