OS X / macOS的任何版本是否容易受到2038年问题的影响?


5

大约在2000年,Apple 发布了一份新闻稿,称自1984年以来,每台Mac都会避免Y2K问题,并且可以处理未来几千年的日期。

好消息是,自1984年推出以来,Macintosh计算机已经能够过渡到2000年。实际上,Mac OS和大多数Mac应用程序可以正确处理内部生成的日期,直到29,940年。

当Mac OS 9是最新的操作系统时,就发表了这个声明。

从那时起,OS X(现在称为macOS)是主要的操作系统,它源自Unix。这是否意味着任何版本都容易受到2038年问题的影响,这个问题与影响类Unix系统的Y2K问题相当?或者苹果公司关于与29,940兼容的声明是否仍然适用?


我怀疑你将在2038
--MicroMachine 2016年

@fabriced 人们仍然使用16岁的Mac OS 9,甚至更早(文章提到一些研究人员正在进行DNA合成,他们仍使用System 7.5)。想象人们在22年内仍会使用当前版本的OS X并不难。无论如何,我仍然很好奇苹果公司提出的关于Macs兼容29,940的声明是否仍然适用于OS X,因为其他Unix系统在2038
Thunderforge

我自己使用Mac OS 9,但根据Apple的说法,它是一台过时的机器,因此使用时应自担风险(并且存在数据风险)。对于过时的机器(优化充电器等)来强迫其用户向上,Apple已经变得更加积极。一种方法是将计算机上的日期更改为2038.
MicroMachine 2016年

Answers:


5

OS X 10.6“Snow Leopard”之前的所有版本都有2038年的问题。大多数安装的10.6和所有安装的10.7“Lion”修复了问题的主要原因。它几乎消失了,但是2038年的bug可能会在一些应用程序中存活下来。

我的旧PowerPC Mac运行OS X 10.4.11“Tiger”。我在系统偏好设置中输入了日期和时间,并尝试在2038年之后输入日期,但它将日期重置为2037年12月31日。它知道2038年出现了问题。

OS X 10.4.11中的日期和时间的屏幕截图

OS X是通过BSD从Unix派生的。OS X应用程序使用BSD系统调用来打开文件和连接到互联网。BSD历史悠久,其中一些系统调用来自20世纪80年代。其中一个系统调用是gettimeofday()首次出现在4.1cBSD中。加州大学伯克利分校于1982年发布了4.1cBSD,比2038年前发布了半个多世纪。时间gettimeofday()是一个整数类型time_t。它计算秒数,其中零是1970-01-01 00:00:00 UTC的Unix纪元。

在我的旧PowerPC Mac中,time_t是一个带符号的32位整数。这导致了2038年的问题。带符号的32位time_t范围为-2147483648到2147483647.这只能保持从1901-12-13 20:45:52 UTC到2038-01-19 03:14:07 UTC的时间。当这个溢出时,gettimeofday()将把日期从2038年1月19日星期一翻到1901年12月13星期五

修复是从32位转换time_t到64位time_t。对于OS X,这种转换伴随着从32位指针到64位指针的另一次转换,但64位指针需要64位处理器。Apple仅提供64位time_t64位处理器。32位处理器可以处理64位time_t,但Apple从未提供过该功能。

自OS X 10.0“Cheetah”以来,Apple的编译器支持32位处理器上的64位整数,当时time_t有32位且off_t有64位。在Unix和BSD中,off_t是文件的大小,还是整个磁盘的大小。32位off_t会将OS X限制为2 GiB以下的磁盘。Apple定义off_t为64位,因此OS X适用于较大的磁盘。Apple time_t在10.0中定义为32位,因此time_t需要稍后转换为64位。

对于我的旧PowerPC Mac,头文件<ppc/_types.h>定义__darwin_time_tlong。对于Intel Mac,标题<i386/_types.h>也是如此。在OS X中,long与指针具有相同的大小。因此,当指针变为64位时,long也变为64位,并且time_t也变为64位,从而解决了2038年问题的主要原因。

Apple的64位转换指南称,“在OS X v10.6之前,操作系统附带的所有应用程序都是32位应用程序。从v10.6开始,操作系统附带的应用程序通常是64位应用程序“。我从维基百科知道,10.6需要英特尔处理器,10.7需要64位英特尔处理器。在32位英特尔处理器上运行10.6的Mac必须具有32位应用程序。我的结论是,大多数运行10.6的Mac和运行10.7的所有Mac都有64位应用程序,64位指针和64位time_t。苹果在2011年发布了10.7,远在2038年1月之前。

使用64位time_t,2038年的bug几乎消失了,但它可能会在一些应用程序中存活下来。旧的32位应用程序可能仍在较新的系统上运行。此外,64位应用程序可能包含编码错误或过时的设计,导致它们将64位转换time_t为32位。这对所有系统都是一个问题,而不仅仅是macOS。


还有马赫时间。OS X的内核将BSD与Mach混合在一起。大多数应用程序从BSD使用时间gettimeofday(),但有一种方法可以绕过BSD并从Mach获得时间。这更难:程序会调用mach_host_self()获取主机端口,然后host_get_clock_service()获取CALENDAR_CLOCK,最后clock_get_time()

在我的旧Mac上运行10.4“Tiger”,<mach/clock_types.h>将时间声明为unsigned int(内部struct mach_timespec)。这是一个无符号的32位整数,范围从0到4294967295,这是从1970-01-01 00:00:00 UTC到2106-02-07 06:28:15 UTC。这将交换2038年问题2106年的问题。它不能达到29,940年。

我怀疑host_get_clock_service()自10.0“Cheetah”以来已经过时了,因为Apple提供了更快的方式来获得时间。这些是gettimeofday()日历时间的BSD ,而Apple则是mach_absolute_time()单调时间。倾向于gettimeofday()将问题放在2038年,而不是2106。


对另一个答案的评论说,他们在10.4上没有发生错误,但是对你失败了。那为什么会这样?
Thunderforge 2016年

@IconDaemon引用10.4的结果,其中时钟停留在03:14:07并且从未前进到03:14:08。对我来说这看起来像2038年的问题。程序可能会将计数从双精度浮点数转换为32位整数。英特尔和PowerPC处理器似乎以不同方式处理此演员。我用这样的演员了一个C程序
kernigh 2016年

那么,13号星期五和2038年之间有联系吗?:)
DonielF

2

El Capitan不易受影响:

#!/usr/bin/perl
use POSIX;
$ENV{'TZ'} = "GMT";
for ($clock = 2147483641; $clock < 2147483651; $clock++)
{
print ctime($clock);
}

这个perl脚本提供以下输出:

Family-iMac:~ dude$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.11.6
BuildVersion:   15G1004
Family-iMac:~ dude$ /Users/dude/Desktop/2038.pl 
Tue Jan 19 03:14:01 2038
Tue Jan 19 03:14:02 2038
Tue Jan 19 03:14:03 2038
Tue Jan 19 03:14:04 2038
Tue Jan 19 03:14:05 2038
Tue Jan 19 03:14:06 2038
Tue Jan 19 03:14:07 2038
Tue Jan 19 03:14:08 2038
Tue Jan 19 03:14:09 2038
Tue Jan 19 03:14:10 2038

收集的信息和脚本从这个非常有趣的网站压缩到骨头。


虽然很高兴知道,但我希望能找到解决所有OS X版本的答案。
Thunderforge 2016年

重要的一点是,El Capitan不会受到这个奇怪的非问题的困扰,因为它是一个非常先进的操作系统。有关Tiger - Mac OS X 10.4的相同基准测试,请参阅此页面。人们可以放心地假设在Tiger之后发布的Mac OS X版本,一直到El Capitan及其他版本,都不会受到影响。我还没有Sierra的副本,但我认为它不会受到2038'问题'的影响。那里的任何人都想测试10.5.x,10.6.x,10.7.x,10.8.x,10.9.x和10.11.x以满足这张海报的好奇心吗?
IconDaemon 2016年

对于不太先进的操作系统来说,这不是一个奇怪的非问题:即使是iOS 6和Android 4.1也会遇到这种情况,由于这个错误,日期不能超过2038-01-19。很高兴知道10.4不容易受到影响。我想如果已知10.0是安全的(或者甚至是公共测试版,如果可能的话),那么这可能意味着它们都是安全的。
Thunderforge 2016年

如果您认为我的答案是正确的,那么请将其标记为有用!
IconDaemon 2016年

到目前为止它是正确的,但不完整。
Thunderforge 2016年

2

好吧,就El Capitan 10.11.6而言,答案并不像使用Perl脚本那么容易。

如果我们试试这个

macmladen@buk $ touch -t 205012121212 my
macmladen@buk $ ls -al
total 104
drwx------  7 root root    4096 Dec 25 13:42 .
drwxr-xr-x 23 root root    4096 Dec  4 17:06 ..
-rw-r--r--  1 root root       0 Dec 12  2050 my

因此,证明macOS在最低,系统层是安全的Y2038 bug。这意味着系统本身不会失败并且将正常工作。

但是,在应用程序级别上,情况并非总是如此。

尝试将日期推送到2040,系统首选项日期和时间通过将其设置为01.01.2038来响应(您必须取消选中自动设置)

在此输入图像描述

这意味着它取决于应用程序他们将如何对Y2038 bug做出反应。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.