crash after clock reset

Bug #1028026 reported by pipping
36
This bug affects 7 people
Affects Status Importance Assigned to Milestone
SBCL
Fix Released
Medium
Unassigned

Bug Description

As already mentioned here: https://github.com/sabetts/stumpwm/issues/7#issuecomment-7091478 (albeit not by me), the following procedure will make sbcl 1.0.57 crash:

  1. run (get-internal-real-time) in sbcl (keep sbcl running).
  2. turn the clock back an hour.
  3. call (get-internal-real-time) again.

Revision history for this message
nixie (onixie) wrote :

It seems like there are some type error that causes debugger run into a loop.
After --disable-debugger I got the following error messages and backtrace.

* unhandled TYPE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
                                  {1002971023}>:
  The value -1960034 is not of type UNSIGNED-BYTE.

0: (SB-DEBUG::MAP-BACKTRACE
    #<CLOSURE (LAMBDA # :IN BACKTRACE) {1003E21DDB}>
    :START
    0
    :COUNT
    128)
1: (BACKTRACE 128 #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDERR* {1000169AE3}>)
2: (SB-DEBUG::DEBUGGER-DISABLED-HOOK
    #<TYPE-ERROR expected-type: UNSIGNED-BYTE datum: -1960034>
    #<unavailable argument>)
3: (SB-DEBUG::RUN-HOOK
    *INVOKE-DEBUGGER-HOOK*
    #<TYPE-ERROR expected-type: UNSIGNED-BYTE datum: -1960034>)
4: (INVOKE-DEBUGGER #<TYPE-ERROR expected-type: UNSIGNED-BYTE datum: -1960034>)
5: (ERROR TYPE-ERROR :DATUM -1960034 :EXPECTED-TYPE UNSIGNED-BYTE)
6: (SB-KERNEL::OBJECT-NOT-TYPE-ERROR-HANDLER
    #<unavailable argument>
    #.(SB-SYS:INT-SAP #X7FFFF6CDF1A0)
    #<SB-ALIEN-INTERNALS:ALIEN-VALUE :SAP #X7FFFF6CDEB80 :TYPE (*
                                                                (STRUCT
                                                                 SB-VM::OS-CONTEXT-T-STRUCT))>
    (84 21))
7: (SB-KERNEL:INTERNAL-ERROR
    #.(SB-SYS:INT-SAP #X7FFFF6CDEB80)
    #<unavailable argument>)
8: ("foreign function: call_into_lisp")
9: ("foreign function: funcall2")
10: ("foreign function: interrupt_internal_error")
11: ("foreign function: handle_trap")
12: ("foreign function: #x412C33")
13: (GET-INTERNAL-REAL-TIME)
14: (SB-SYS:DECODE-TIMEOUT NIL)
15: (SB-SYS:WAIT-UNTIL-FD-USABLE 0 :INPUT NIL T)
16: (SB-IMPL::REFILL-INPUT-BUFFER
     #<SB-SYS:FD-STREAM for "standard input" {10029713B3}>)
17: (SB-IMPL::INPUT-CHAR/UTF-8
     #<SB-SYS:FD-STREAM for "standard input" {10029713B3}>
     NIL
     #:EOF-OBJECT)
18: ((LAMBDA (&REST REST) :IN SB-IMPL::GET-EXTERNAL-FORMAT)
     #<SB-SYS:FD-STREAM for "standard input" {10029713B3}>
     NIL
     #:EOF-OBJECT)
19: (READ-CHAR
     #<SB-SYS:FD-STREAM for "standard input" {10029713B3}>
     NIL
     #:EOF-OBJECT
     #<unused argument>)
20: (READ-CHAR
     #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDIN* {10001B3173}>
     NIL
     #:EOF-OBJECT
     #<unused argument>)
21: (SB-IMPL::%READ-PRESERVING-WHITESPACE
     #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDIN* {10001B3173}>
     NIL
     (NIL)
     T)
22: (SB-IMPL::%READ-PRESERVING-WHITESPACE
     #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDIN* {10001B3173}>
     NIL
     (NIL)
     NIL)
23: (READ #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDIN* {10001B3173}> NIL (NIL) NIL)
24: (SB-IMPL::REPL-READ-FORM-FUN
     #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDIN* {10001B3173}>
     #<unavailable argument>)
25: (SB-IMPL::REPL-FUN NIL)
26: ((LAMBDA () :IN SB-IMPL::TOPLEVEL-REPL))
27: (SB-IMPL::%WITH-REBOUND-IO-SYNTAX
     #<CLOSURE (LAMBDA # :IN SB-IMPL::TOPLEVEL-REPL) {1003E1248B}>)
28: (SB-IMPL::TOPLEVEL-REPL NIL)
29: (SB-IMPL::TOPLEVEL-INIT)
30: ((FLET #:WITHOUT-INTERRUPTS-BODY-237819 :IN SAVE-LISP-AND-DIE))
31: ((LABELS SB-IMPL::RESTART-LISP :IN SAVE-LISP-AND-DIE))

unhandled condition in --disable-debugger mode, quitting

Revision history for this message
nixie (onixie) wrote :

The type error happens in function GET-INTERNAL-REAL-TIME

The value of 'now' variable is declared as unsigned-byte (which according to CLHS I think this is appropriate),
but when calculating its new value, the result from subtracting seconds might be negative one. (if setting the system time to the past).

I create a patch of this fix.
Thanks for the review and advice. :)

From 84a1161018bec29e50bca2806fdc35be93fe8249 Mon Sep 17 00:00:00 2001
From: Nixie <email address hidden>
Date: Fri, 27 Jul 2012 07:11:11 +0800
Subject: [PATCH] Rejuvenate the internal real time in case we return to the past

Fixes lp#1028026
---
 src/code/unix.lisp | 18 +++++++++++-------
 1 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/src/code/unix.lisp b/src/code/unix.lisp
index 7a1a628..fbc679a 100644
--- a/src/code/unix.lisp
+++ b/src/code/unix.lisp
@@ -1174,13 +1174,17 @@ the UNIX epoch (January 1st 1970.)"
     ;; --MG
     (defun get-internal-real-time ()
       (multiple-value-bind (sec msec) (system-real-time-values)
- (unless (and (= msec c-msec) (= sec c-sec))
- (setf now (+ (* (- sec e-sec)
- sb!xc:internal-time-units-per-second)
- (- msec e-msec))
- c-msec msec
- c-sec sec))
- now)))
+ (if (or (< sec e-sec)
+ (and (= sec e-sec) (< msec e-msec)))
+ (progn (reinit-internal-real-time)
+ (setf now 0))
+ (unless (and (= msec c-msec) (= sec c-sec))
+ (setf now (+ (* (- sec e-sec)
+ sb!xc:internal-time-units-per-second)
+ (- msec e-msec))
+ c-msec msec
+ c-sec sec)))
+ now)))

   (defun system-internal-run-time ()
     (multiple-value-bind (ignore utime-sec utime-usec stime-sec stime-usec)
--
1.7.3.4

Revision history for this message
nixie (onixie) wrote :
Stas Boukarev (stassats)
Changed in sbcl:
status: New → Confirmed
importance: Undecided → Medium
Revision history for this message
Juho Snellman (jsnell+bugs) wrote : Re: [Bug 1028026] Re: crash after clock reset

I'm not sure that's the right approach. It'd be nicer to just use a
proper monotonic clock (e.g. POSIX clock_gettime() with
CLOCK_MONOTONIC).

--
Juho Snellman

Revision history for this message
Lutz Euler (lutz-euler) wrote :

I like Juho's suggestion from #4.
Does this mean that one needs to call sysconf at SBCL
startup time to find out whether CLOCK_MONOTONIC
is supported and else fall back to the approach from #2?

Revision history for this message
nixie (onixie) wrote :

CLOCK_MONOTONIC would be nicer on supported platform.

I test against some other CL implementations.
Some give meaningless overflowed unsigned result, some just return negative elapse which breaks CL standard.
So I think reset the elapse to 0 can be a kind of better remedy.

Changed in sbcl:
assignee: nobody → David Lichteblau (david-lichteblau)
Stas Boukarev (stassats)
Changed in sbcl:
assignee: David Lichteblau (david-lichteblau) → nobody
Revision history for this message
Ub User (ubcock) wrote :

This bug also affects the Win32 version of GET-INTERNAL-REAL-TIME in win32.lisp.

Revision history for this message
James Kalenius (aeshtaer) wrote :

I got a similar error on macOS Sierra 10.12.6 with SBCL 1.3.18.105-f0b6b7c23, unintentionally while building something. scymtym suggested it could have been NTP setting the clock back, which seems plausible.

Backtrace attached. Just posting on the off chance it helps.

Revision history for this message
Douglas Katzman (dougk) wrote :
Changed in sbcl:
status: Confirmed → Fix Committed
Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.