Fix: handle negative clock offset for lttng-ust metadata
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 8 Feb 2016 22:13:25 +0000 (17:13 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 11 Feb 2016 20:42:56 +0000 (15:42 -0500)
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.

This patch should be applied to master and stable-2.7.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/bin/lttng-sessiond/ust-metadata.c

index 984d5f813ccf9277e6e221b7299f8f80a7d50954..276dc7a4414043f9c177abe75bf11a85b50c2c5f 100644 (file)
@@ -604,11 +604,17 @@ int _lttng_event_header_declare(struct ust_registry_session *session)
        );
 }
 
+/*
+ * The offset between monotonic and realtime clock can be negative if
+ * the system sets the REALTIME clock to 0 after boot.
+ * Currently handle this by flooring the offset at 0.
+ */
 static
 int measure_single_clock_offset(struct offset_sample *sample)
 {
-       uint64_t offset, monotonic[2], measure_delta, realtime;
+       uint64_t monotonic_avg, monotonic[2], measure_delta, realtime;
        uint64_t tcf = trace_clock_freq();
+       int64_t offset;
        struct timespec rts = { 0, 0 };
        int ret;
 
@@ -626,15 +632,15 @@ int measure_single_clock_offset(struct offset_sample *sample)
                 */
                return 0;
        }
-       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;
        } else {
                realtime += (uint64_t) rts.tv_nsec * tcf / NSEC_PER_SEC;
        }
-       offset = realtime - offset;
-       sample->offset = offset;
+       offset = (int64_t) realtime - monotonic_avg;
+       sample->offset = max(offset, 0);
        sample->measure_delta = measure_delta;
        return 0;
 }
This page took 0.028442 seconds and 5 git commands to generate.