greshake / i3status-rust

Very resourcefriendly and feature-rich replacement for i3status, written in pure Rust
GNU General Public License v3.0
2.88k stars 475 forks source link

Random crash after running for a while #27

Closed Svenito closed 7 years ago

Svenito commented 7 years ago

I run i3status fine but after some time it crashes. I've run it with a debug build of the latest master (1517618d) to provide a detailed stacktrace

thread 'main' panicked at 'other was less than the current instant', /checkout/src/libstd/sys/unix/time.rs:276
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
             at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at /checkout/src/libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at /checkout/src/libstd/sys_common/backtrace.rs:60
             at /checkout/src/libstd/panicking.rs:355
   3: std::panicking::default_hook
             at /checkout/src/libstd/panicking.rs:371
   4: std::panicking::rust_panic_with_hook
             at /checkout/src/libstd/panicking.rs:549
   5: std::panicking::begin_panic
             at /checkout/src/libstd/panicking.rs:511
   6: <std::time::Instant as core::ops::Sub>::sub
             at /checkout/src/libstd/sys/unix/time.rs:276
             at /checkout/src/libcore/result.rs:706
             at /checkout/src/libstd/sys/unix/time.rs:275
             at /checkout/src/libstd/time/mod.rs:184
             at /checkout/src/libstd/time/mod.rs:249
   7: i3status_rs::scheduler::UpdateScheduler::do_scheduled_updates
             at src/scheduler.rs:84
   8: i3status_rs::main
             at src/main.rs:181
   9: __rust_maybe_catch_panic
             at /checkout/src/libpanic_unwind/lib.rs:98
  10: std::rt::lang_start
             at /checkout/src/libstd/panicking.rs:433
             at /checkout/src/libstd/panic.rs:361
             at /checkout/src/libstd/rt.rs:56
  11: main
  12: __libc_start_main
  13: _start

System

LSB Version:    :core-4.1-amd64:core-4.1-noarch:cxx-4.1-amd64:cxx-4.1-noarch:desktop-4.1-amd64:desktop-4.1-noarch:languages-4.1-amd64:languages-4.1-noarch:printing-4.1-amd64:printing-4.1-noarch
Distributor ID: CentOS
Description:    CentOS Linux release 7.3.1611 (Core) 
Release:        7.3.1611
Codename:       Core
greshake commented 7 years ago

The line mentioned by the backtrace:

83: if t.update_time > Instant::now() {
84:        thread::sleep(t.update_time - Instant::now());
85: }

I've also experienced these crashes but could never observe one in debug mode.

greshake commented 7 years ago

The subtraction calls effectively duration_since, which is documented with:

    /// Returns the amount of time elapsed from another instant to this one.
    ///
    /// # Panics
    ///
    /// This function will panic if `earlier` is later than `self`, which should
    /// only be possible if `earlier` was created after `self`. Because
    /// `Instant` is monotonic, the only time that this should happen should be
    /// a bug.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use std::time::{Duration, Instant};
    /// use std::thread::sleep;
    ///
    /// let now = Instant::now();
    /// sleep(Duration::new(1, 0));
    /// let new_now = Instant::now();
    /// println!("{:?}", new_now.duration_since(now));
    /// ```
Svenito commented 7 years ago

Yeah, same reaction I had. Some sort of weird clock skew or something? Let me know if want any more whelp debugging this. I just run it in the background while I work, so can capture debug

greshake commented 7 years ago

This has to be a stdlib bug, right? Instant::now() is always created after t.update_time. Only corner case, which should still work, is if t.update_time was created in a different thread.

greshake commented 7 years ago

Sorry, I'm an idiot. The condition breaks in the nanosecond tick between the if and the subtraction. Should be fixed now.

Svenito commented 7 years ago

Awesome. Will test as soon as I have time. Thanks