Tcl Source Code

View Ticket
Login
Ticket UUID: 86dd172271f35ac4f08b15c440fa94ce7c6022c1
Title: interp.test fails if clock is set to year 2040 (even on 64 bit machines)
Type: Bug Version: 8.6.13
Submitter: kanavin Created on: 2023-08-07 11:44:44
Subsystem: 20. [interp] Assigned To: jan.nijtmans
Priority: 5 Medium Severity: Important
Status: Closed Last Modified: 2024-01-08 14:43:55
Resolution: Fixed Closed By: jan.nijtmans
    Closed on: 2024-01-08 14:43:55
Description:

When system date is set to 2040 (e.g. post-2038), interp.test starts producing failures, this is the output. I suspect there's a 32 bit integer in use for time somewhere? Note that this happens on 64 bit x86_64 machine, so the issue seems specific to tcl.

FAIL: interp.test
Tests running in interp:  /usr/lib/tcl/ptest/tcltest
Tests located in:  /usr/lib/tcl/ptest/tests
Tests running in:  /usr/lib/tcl/ptest
Temporary files stored in /usr/lib/tcl/ptest
Test files run in separate interpreters
Running tests that match:  *
Skipping test files that match:  l.*.test
Only running test files that match:  interp.test
Tests began at Thu Feb 02 00:01:54 GMT 2040
interp.test


==== interp-34.3 basic test of limits - pure bytecode loop FAILED
==== Contents of test case:

    set i [interp create]
    $i eval {
	proc foobar {} {
	    while {1} {
		# No bytecode at all here...
	    }
	}
    }
    # We use a time limit here; command limits don't trap this case
    $i limit time -seconds [expr {[clock seconds]+2}]
    $i eval foobar

---- Result was:
seconds must be at least 0
---- Result should have been (exact matching):
time limit exceeded
==== interp-34.3 FAILED



==== interp-34.3.1 basic test of limits - pure inside-command loop FAILED
==== Contents of test case:

    set i [interp create]
    $i eval {
	proc foobar {} {
	    set while while
	    $while {1} {
		# No bytecode at all here...
	    }
	}
    }
    # We use a time limit here; command limits don't trap this case
    $i limit time -seconds [expr {[clock seconds] + 2}]
    $i eval foobar

---- Result was:
seconds must be at least 0
---- Result should have been (exact matching):
time limit exceeded
==== interp-34.3.1 FAILED



==== interp-34.8 time limits trigger in vwaits FAILED
==== Contents of test case:

    set i [interp create]
    interp limit $i time -seconds [expr {[clock seconds] + 1}] -granularity 1
    $i eval {
	set x {}
	vwait x
    }

---- Result was:
seconds must be at least 0
---- Result should have been (exact matching):
limit exceeded
==== interp-34.8 FAILED



==== interp-34.9 time limits trigger in blocking after FAILED
==== Contents of test case:

    set i [interp create]
    set t0 [clock seconds]
    interp limit $i time -seconds [expr {$t0 + 1}] -granularity 1
    set code [catch {
	$i eval {after 10000}
    } msg]
    set t1 [clock seconds]
    interp delete $i
    list $code $msg [expr {($t1-$t0) < 3 ? "OK" : $t1-$t0}]

---- Test generated error; Return code was: 1
---- Return code should have been one of: 0 2
---- errorInfo: seconds must be at least 0
    while executing
"interp limit $i time -seconds [expr {$t0 + 1}] -granularity 1"
    ("uplevel" body line 4)
    invoked from within
"uplevel 1 $script"
---- errorCode: TCL OPERATION INTERP BADVALUE
==== interp-34.9 FAILED



==== interp-34.11 time limit extension in callbacks FAILED
==== Contents of test case:

    set i [interp create]
    set t0 [clock seconds]
    $i limit time -seconds [expr {$t0 + 1}] -granularity 1  -command "cb1 $i [expr {$t0 + 2}]"
    set ::result {}
    lappend ::result [catch {
	$i eval {
	    for {set i 0} {$i<30} {incr i} {
		after 100
	    }
	}
    } msg] $msg
    set t1 [clock seconds]
    lappend ::result [expr {$t1-$t0>=2 ? "ok" : "$t0,$t1"}]
    interp delete $i
    return $::result

---- Test generated error; Return code was: 1
---- Return code should have been one of: 0 2
---- errorInfo: seconds must be at least 0
    while executing
"$i limit time -seconds [expr {$t0 + 1}] -granularity 1  -command "cb1 $i [expr {$t0 + 2}]""
    ("uplevel" body line 4)
    invoked from within
"uplevel 1 $script"
---- errorCode: TCL OPERATION INTERP BADVALUE
==== interp-34.11 FAILED



==== interp-34.12 time limit extension in callbacks FAILED
==== Contents of test case:

    set i [interp create]
    set t0 [clock seconds]
    set ::times "[expr {$t0 + 2}] [expr {$t0 + 100}]"
    $i limit time -seconds [expr {$t0 + 1}] -granularity 1 -command "cb1 $i"
    set ::result {}
    lappend ::result [catch {
	$i eval {
	    for {set i 0} {$i<30} {incr i} {
		after 100
	    }
	}
    } msg] $msg
    set t1 [clock seconds]
    lappend ::result [expr {$t1-$t0>=2 ? "ok" : "$t0,$t1"}]
    interp delete $i
    return $::result

---- Test generated error; Return code was: 1
---- Return code should have been one of: 0 2
---- errorInfo: seconds must be at least 0
    while executing
"$i limit time -seconds [expr {$t0 + 1}] -granularity 1 -command "cb1 $i""
    ("uplevel" body line 5)
    invoked from within
"uplevel 1 $script"
---- errorCode: TCL OPERATION INTERP BADVALUE
==== interp-34.12 FAILED



==== interp-34.13 time limit granularity and vwait: Bug 2891362 FAILED
==== Contents of test case:

    $i limit time -seconds [clock add [clock seconds] 1 second]
    $i eval {
	after 2000 set x timeout
	vwait x
	return $x
    }

---- Result was:
seconds must be at least 0
---- Result should have been (exact matching):
limit exceeded
==== interp-34.13 FAILED


Tests ended at Thu Feb 02 00:01:55 GMT 2040
all.tcl:	Total	351	Passed	337	Skipped	7	Failed	7
Sourced 1 Test Files.
Files with failing tests: interp.test
Number of tests skipped for each constraint:
	7	knownBug
User Comments: jan.nijtmans added on 2024-01-08 14:43:55:

Fixed for 9.0


kanavin added on 2023-08-28 08:48:15:
I need to add a bit of background information: in scope of Yocto project (distribution toolkit for Linux-based embedded systems) I am testing whether a complete system keeps working if system date is set to 2040, both on 64 bit and 32 bit targets. 'Keeps working' means as well running as many component-specific test suites as possible, including tcl, as of currently released version.

This ticket is the outcome of that work: on 64 bit systems interp.test starts failing as shown, and on 32 bit systems a few additional failures start to happen (I didn't document them separately, but they do occur). 

With the two attached patches all failures are resolved. I'm happy to have the issues resolved elsewhere, or I can do additional work to merge them. As long as the issues are both known, and eventually fixed.

jan.nijtmans added on 2023-08-27 16:16:03:

This ticket cannot be closed yet: Build is failing on Windows with --enable-symbols=(mem|all). Don't know yet why.


jan.nijtmans added on 2023-08-26 20:38:42:

> The patch for tcl.h proposes an ABI change (on systems with 32-bit long). It can be considered for Tcl 9, but not 8.6 or 8.7.

I think Tcl_Time.sec _must_ be updated to "long long" in Tcl 9.0, otherwise we can never be sure that 2038-related bugs won't show up on 32-bit platforms.

Therefore: [19499b816370cd3f]

Thanks!


chrstphrchvz added on 2023-08-23 16:10:22:

The patch for tclInterp.c resembles changes which were already made for [3e8074aea7]. I believe this ticket is a duplicate.


chrstphrchvz added on 2023-08-23 16:03:25:

The patch for tcl.h proposes an ABI change (on systems with 32-bit long). It can be considered for Tcl 9, but not 8.6 or 8.7.


Attachments: