隐藏的BUG探讨——从“Y2K”问题到“2038”年问题

前几天在饱览书籍的过程中,饶有兴致的注意到一个在历史上曾经叱咤过全球的严重计算机BUG,于是记录下来,等待以后入坑

什么是千年虫(Y2K)问题千年虫-百度百科

计算机2000年问题,又叫做“千年虫”、“电脑千禧年千年虫问题”或“千年危机”。缩写为“Y2K”。是指在某些使用了计算机程序的智能系统(包括计算机系统、自动控制芯片等)中,由于其中的年份只使用两位十进制数来表示,因此当系统进行(或涉及到)跨世纪的日期处理运 算时(如多个日期之间的计算或比较等),就会出现错误的结果,进而引发各种各样的系统功 能紊乱甚至崩溃。因此从根本上说千年虫是一种程序处理日期上的bug(计算机程序故障),而非病毒。

举个例子

千年虫是在计算机中对于年份和日期的表示方式不完整而引起的程序出错,它包含三个方面的内容:
1. 由于只使用了两位数来表示年份,会引起跨世纪的日期计算得出错误结果,比如用02减去98会得-96,而用2002减去1998结果是4。
2. 由于特殊日期(9/9/99)和计算机中特殊定义的字符串相冲突而有可能引起操作错误。
3. 闰年问题,即能否正确计算2000年是闰年,2月份有29日这一天。
根据以上三个方面的表现,我们可以肯定地说,千年虫在所有使用了智能程序进行有关日期的处理和操作的地方都有可能发作。
举个例子来说,对于一部星期一至星期五工作时间开放、星期六、日下班时间关闭的定时开关电梯来说,由于它能够定时开关,电梯里必定有智能程序,同时智能程序中也必定有和日期有关的操作,才能够计算出一年中每个月的每一天是星期几,那么当2000年来临时,如果这部电梯因为只使用了两位数来表示年份,就会将2000年识别为1900年,从而带来其中的日历计算错误,造成电梯的自动功能紊乱。

千年虫主要集中发作于两个方面: 一个是配备比较早(大约在80年代中期以前投入使用)的主机上的应用系统,如在IBM 4381,IBM AS/400等机型上运行的应用程序。这些机器系统国际上都应用的相当早,因此其上面的应用程序经过十余年的开发和发展其规模已经非常庞大,比如美国的AT&T电讯公司,其内部就有超过3.6亿行的应用程序需要检测是否存在2000年问题,这确实是很大的工作量,因此给解决2000年问题造成了极大的麻烦。 千年虫另外一个容易发作的方面是嵌入式设备。所谓嵌入式设备,就是指设备中使用了智能芯片的系统,由于智能芯片价格低廉,目前嵌入式设备已变成无处不在,由生产线、大量的自动化仪器仪表、汽车、电梯、警报系统、消防检测器到医疗设备,以至电话交换机、空调机、交通灯、恒温器等,可谓渗透到日常生活每个角落。这些设备中应用的程序往往都已经固化到元器件中,因此一旦产品只使用了两位数来表示年份,就会引发2000年问题,而要替换这些芯片,又往往不得不把整个系统都替换,这会造成资金和操作上的困难,使解决2000年问题更加麻烦,也是无法按时解决2000年问题的隐患之一。
这里写图片描述

这里写图片描述
机器时钟
在微机硬件中有一个实时系统时钟,它依靠微机主板上的纽扣电池作为电源和动力,时刻保持运转,这样微机在关机时也能够保持时间前进。这个实时系统时钟的时间数值是保存到主板BIOS中的存储器(CMOS)中的。当微机启动时,微机操作系统从BIOS的那个时间存储器里读取当前时间,包括四位数的年份以及月份、日、小时、分钟、秒等,从此,只要不关机,操作系统的时钟就会以微机外接电源(不再是主板上的纽扣电池)为动力单独向前运转,并保存在微机的内存中(不再是BIOS中的存储器)。
微型计算机的Y2K问题
微机的2000年问题主要表现在,尽管RTC—实时系统时钟中使用了四位数来表示年份,但其年份数据的前两位(世纪信息,如“19”,“20”等)并不和后两位发生联系,也就是说,当后两位从“99”变为“00”时,并不能向前进位使前两位数由“19”变为“20”,这样,RTC中1999年的下一年便应该是1900年,从而引发了2000年问题。 而对于目前应用的操作系统(如DOS 5.0以上版本、Windows 3.x 、Windows95、 Windows 98以及 Linux 、SCO Unix、Windows NT)时钟来说,其年份都是用四位数来表示的,因此不会存在2000年问题。但目前的问题是操作系统中附带的一些小实用程序、工具或函数调用,有可能因为年份表示不完整而引起千年虫发作。

Y2K问题给2000年造成的危害还是挺大的,随着时间的推移2038年问题也引起了人们的注意。。。。

2038年问题2038年问题-维基百科

和21世纪初的千年虫(the Millennium bug)问题类似,32位的Unix操作系统和Linux操作系统时间溢出问题又称为2038年问题(the Year 2038 problem)。如果你想知道什么是2038问题的话,你需要知道一些技术上的东西。这个bug是由用来写Unix/Linux的C语言引起的,C语言中用 time_t 来代表时间和日期,time_t 是整数(int)型的,它用来记载从1970年1月1日到2000年所经历的秒数。

在2038年的问题是在该时间值存储或计算为计算和数据存储的情况下的一个问题符号的32位整数,并且因为这个00:00:00数被解释为秒数UTC 1 1970年1月(在历元)。[1]这样的实现不能在19后3点14分07秒UTC编码倍2038年1月,类似但不完全类似于一个问题2000年问题(也被称为千年虫),其中2位的值代表数字年自1900年以来未能编码2000年或以后。大多数32位的 类Unix系统来存储和处理在这段时间Unix时间格式,因此2038年的问题是有时被称为Unix的千年虫的关联。

原理

在计算机应用上,2038年问题可能会导致某些软件在2038年无法正常工作。所有使用 POSIX (可移植性操作系统接口 )时间表示时间的程序都将受其影响,因为它们的时间起点是格林尼治时间1970年1月1日0时0分0秒(这个时间名叫 the Unix Epoch),它们用the Unix Epoch经过的秒数(忽略闰秒)来表示时间。这种时间表示法在类Unix(Unix-like)操作系统上是一个标准,并会影响以其C编程语言开发给其他大部份操作系统使用的软件。在大部分的32位操作系统上,此“time_t”数据模式使用一个有符号32位整数(signed int32)存储计算的秒数。依照此“time_t”标准,在此格式能被表示的最后时间是第2147483647秒(代表格林尼治时间2038年1月19日凌晨03:14:07)。下一秒,即格林尼治时间2038年1月19日凌晨03:14:08,由于32位整型溢出,时间将会被“绕回”(wrap around)成一个负数,变成了第 -2147483648 秒(代表格林尼治时间1901年12月13日20:45:52),造成应用程序发生严重的时间错误,而无法运行。

这里写图片描述

这里写图片描述

引文

The latest time that can be represented in Unix’s signed 32-bit integer time format is 03:14:07 UTC on Tuesday, 19 January 2038 (2,147,483,647 seconds after 1 January 1970).[2] Times beyond that will wrap around and be stored internally as a negative number, which these systems will interpret as having occurred on 13 December 1901 rather than 19 January 2038. This is caused by integer overflow. The counter runs out of usable digit bits, flips the sign bit instead, and reports a maximally negative number (continuing to count up, toward zero). Resulting erroneous calculations on such systems are likely to cause problems for users and other relying parties.
Programs that work with future dates will begin to run into problems sooner; for example a program that works with dates 20 years in the future will have to be fixed no later than 2018.

上面说到2038年问题将会逐渐的解决直到2018年,但是就目前的时间来推算,似乎还存在着很大的问题。

总结
满心期待的写下这篇博文,期待着有那么一天,我将能够亲手和这个可爱i的BUG交手,并且解决它。当然,所有的前提都是需要在漫长的岁月中等到2038年1月19日凌晨03:14:07