Проблема 2038 года - Year 2038 problem

Одно из возможных проявлений ошибки на конкретной машине: дата могла быть сброшена в 03:14:08 UTC 19 января 2038 года.

В Проблема 2038 года (также называемый Y2038, Эпохалипсис,[1][2] Y2k38 или Unix Y2K) относится к представлению времени во многих цифровых системах как количество секунд, прошедших с 00:00:00. универсальное глобальное время на 1 января 1970 г. и сохраняя его как 32-битное целое число со знаком. Такие реализации не могут кодировать время после 03:14:07 UTC 19 января 2038 года. Проблема 2000 года Проблема 2038 года вызвана недостаточной емкостью, используемой для отображения времени.

Причина

Последнее время с 1 января 1970 г., которое можно сохранить с помощью 32-битное целое число со знаком будет 03:14:07, вторник, 19 января 2038 г. (231-1 = 2 147 483 647 секунд после 1 января 1970 г.).[3]

Программы, которые пытаются увеличить время после этой даты, будут вызывать внутреннее сохранение значения как отрицательное число, которое эти системы интерпретируют как произошедшее в 20:45:52 в пятницу, 13 декабря 1901 года, а не 19 января 2038 года. это вызвано целочисленное переполнение, во время которого счетчик исчерпывает полезные биты цифры и вместо этого меняет знаковый бит. Это сообщает о максимально отрицательном числе и продолжает считать. вверх, к нулю, а затем снова вверх до положительных целых чисел. Ошибочные вычисления в таких системах могут вызвать проблемы у пользователей и других сторонних организаций.

Ранние проблемы

В мае 2006 г. появились сообщения о раннем проявлении проблемы Y2038 в AOLserver программного обеспечения. Программное обеспечение было разработано с кладж для обработки запроса к базе данных, время ожидания которого никогда не должно истекать. Вместо того, чтобы специально обрабатывать этот особый случай, первоначальный дизайн просто определял произвольный тайм-аут дата в будущем. В конфигурации по умолчанию для сервера указано, что время ожидания запроса должно истечь через один миллиард секунд. Один миллиард секунд (примерно 32 года) после 01:27:28 UTC 13 мая 2006 года превышает дату отсечения 2038 года. Таким образом, по прошествии этого времени вычисление тайм-аута переполнилось и вернуло дату, которая фактически была в прошлом, что привело к сбою программного обеспечения. Когда проблема была обнаружена, операторы AOLServer должны были отредактировать файл конфигурации и установить более низкое значение времени ожидания.[4][5]

Игроки игр или приложений, которые запрограммированы на введение периодов ожидания[6] сталкиваются с этой проблемой, когда игроки пытаются обойти период ожидания, установив дату на своих устройствах на дату после 19 января 2038 года, но не могут этого сделать, поскольку используется 32-битный формат времени Unix.

Уязвимые системы

Встроенные системы которые используют даты либо для вычислений, либо для ведения журнала диагностики, скорее всего, будут затронуты проблемой 2038 года.[7]

Многие транспортные системы от полета до автомобилей широко используют встроенные системы. В автомобильных системах это может быть антиблокировочная тормозная система (ABS), электронный контроль устойчивости (ESC / ESP), контроль тяги (TCS) и автоматический полный привод; самолет может использовать инерциальные системы наведения и приемники GPS.[примечание 1] Однако это не означает, что все эти системы будут страдать от проблемы Y2038, поскольку многие такие системы не требуют доступа к датам. Для тех, кто это делает, те системы, которые отслеживают только разницу между временем / датами, а не абсолютное время / дату, по характеру расчета не будут испытывать серьезных проблем. Это относится к автомобильной диагностике, основанной на законодательных стандартах, таких как CARB (Калифорнийский совет по воздушным ресурсам ).[8]

Еще одно важное применение встроенных систем - это устройства связи, включая сотовые телефоны и Интернет-устройства (маршрутизаторы, точки беспроводного доступа и т. Д.), Которые полагаются на сохранение точного времени и даты и все чаще основываются на операционных системах, подобных UNIX. Например, проблема Y2038 заставляет некоторые устройства работать с 32-битной Android сбой и не перезапуск при изменении времени на эту дату.[9]

Несмотря на современные 18–24-месячное обновление технологий компьютерных систем, встроенные системы рассчитаны на срок службы машины, компонентом которой они являются. Вполне возможно, что некоторые из этих систем могут все еще использоваться в 2038 году. Может быть непрактично или, в некоторых случаях, невозможно обновить программное обеспечение, работающее на этих системах, что в конечном итоге потребует замены, если 32-разрядные ограничения должны быть исправлены.

MySQL встроенные функции базы данных, такие как UNIX_TIMESTAMP () вернет 0 после 03:14:07 универсальное глобальное время 19 января 2038 г.[10]

Рано Mac OS X версии[11] подвержены проблеме 2038 года.

Структуры данных с проблемами времени

Многие структуры данных, которые используются сегодня, имеют 32-битные представления времени, встроенные в их структуру. Полный список этих структур данных практически невозможно составить, но есть хорошо известные структуры данных, у которых есть проблема времени Unix:

  • файловые системы (многие файловые системы используют только 32 бита для представления времени в inodes )
  • форматы двоичных файлов (в которых используются 32-битные поля времени)
  • базы данных (которые имеют 32-битные поля времени)
  • языки запросов к базе данных, например SQL который имеет UNIX_TIMESTAMP ()-подобные команды

Примеры систем, использующих структуры данных, которые могут содержать 32-битные представления времени, включают:

  • встроенные подсистемы управления и мониторинга завода, НПЗ
  • разные медицинские приборы
  • разные военные устройства

Любая система, использующая структуры данных, содержащие 32-битные представления времени, представляет риск. Степень риска зависит от режима отказа.

Метки времени протокола сетевого времени

В Сетевой протокол времени (NTP) имеет связанную проблему переполнения, которая проявляется в 2036 году, а не в 2038 году. 64-битные временные метки, используемые NTP, состоят из 32-битной части для секунд и 32-битной части для дробной секунды, что дает NTP время масштабировать это переворачивается каждые 232 секунд (136 лет) и теоретическое разрешение 2−32 секунды (233 пикосекунды). NTP использует эпоху 1 января 1900 года. Первое обновление происходит в 2036 году, до проблемы 2038 года в UNIX.

Реализации должны устранять неоднозначность времени NTP, используя информацию о приблизительном времени из других источников. Поскольку NTP работает только с различиями между отметками времени, а не с их абсолютными значениями, в расчетах циклический переход невидим, если отметки времени находятся в пределах 68 лет друг от друга. Однако после обхода клиенты все еще могут столкнуться с двумя проблемами:

  1. Они получают дату 1900-01-01 00: 00: 00UTC, а не 2036-02-07 06:28:15 (плюс или минус несколько дополнительных секунд) в качестве нового времени.
  2. Когда клиент пытается использовать это время и сохранить его в формате времени UNIX, как это делают многие встроенные системы, он потерпит неудачу, потому что время UNIX начинается 13 декабря 1901 года (32-битное целое число со знаком) или 1 января 1970 года (32-битное целое число без знака).[нужна цитата ]

Это означает, что для NTP опрокидывание будет невидимым для большинства работающих систем, поскольку они будут иметь правильное время с очень малым допуском. Однако системы, которые запускаются, должны знать дату в пределах не более 68 лет. С учетом большой допустимой ошибки не ожидается, что это будет слишком обременительным требованием. Один из предлагаемых способов - установить часы не раньше даты сборки системы или даты выпуска текущей версии программного обеспечения NTP. Во многих системах используются аппаратные часы с батарейным питанием, чтобы избежать этой проблемы.

Даже в этом случае будущие версии NTP могут расширить представление времени до 128 бит: 64 бита для второй и 64 бит для дробной секунды. Текущий формат NTP4 поддерживает Номер Эры и Смещение эпохи, что при правильном использовании должно помочь решить проблемы с переносом даты. В соответствии с Миллс, "64-битного значения дроби достаточно, чтобы определить время, необходимое для фотон пройти электрон со скоростью света. 64-битного значения секунды достаточно, чтобы обеспечить однозначное представление времени до Вселенная тускнеет."[12][заметка 2]

Возможные решения

Универсального решения проблемы 2038 года не существует. Например, в Язык C, любые изменения в определении time_t тип данных приведет к совместимость кода проблемы в любом приложении, в котором представления даты и времени зависят от природы подписанного 32-битного time_t целое число. Например, изменение time_t в 32-битное целое число без знака, которое расширит диапазон до 2106 (в частности, 06:28:15 UTC в воскресенье, 7 февраля 2106 г.), отрицательно повлияет на программы, которые хранят, извлекают или манипулируют датами до 1970 года, как таковые даты представлены отрицательными числами. Увеличение размера time_t 64-битный тип в существующей системе вызовет несовместимые изменения в компоновке структур и бинарном интерфейсе функций.

Большинство операционных систем, предназначенных для работы на 64-битных аппаратное обеспечение уже используют подписанный 64-битный time_t целые числа. Использование 64-битного значения со знаком вводит новую дату переноса, которая более чем в двадцать раз превышает предполагаемую возраст вселенной: примерно через 292 миллиарда лет. Умение делать вычисления по датам ограничено тем, что tm_year использует 32-битное целое число со знаком, начиная с 1900 года. Это ограничивает год максимумом 2 147 485 547 (2 147 483 647 + 1900).[13]

FreeBSD использует 64-битный time_t для всех 32-битных и 64-битных архитектур, кроме 32-битного i386, в котором используется 32-битный беззнаковый time_t вместо.[14]

Начиная с NetBSD версия 6.0 (выпущена в октябре 2012 г.), в операционной системе NetBSD используется 64-разрядная time_t как для 32-битной, так и для 64-битной архитектуры. Приложения, скомпилированные для более ранней версии NetBSD с 32-разрядной time_t поддерживаются через уровень двоичной совместимости, но такие старые приложения все равно будут страдать от проблемы 2038 года.[15]

OpenBSD начиная с версии 5.5, выпущенной в мае 2014 г., также используется 64-разрядная time_t как для 32-битной, так и для 64-битной архитектуры. В отличие от NetBSD, нет уровня двоичной совместимости. Поэтому приложения, ожидающие 32-битной time_t и приложения, использующие что-либо отличное от time_t для хранения значений времени может сломаться.[16]

Linux изначально использовался 64-битный time_t только для 64-битных архитектур; чистый 32-битный ABI не был изменен из-за обратной совместимости.[17]Начиная с версии 5.6, 64-бит time_t также поддерживается на 32-битных архитектурах. Это было сделано в первую очередь ради встроенный Linux системы.[18]

В x32 ABI за Linux (который определяет среду для программ с 32-битными адресами, но с процессором в 64-битном режиме) использует 64-битный time_t. Поскольку это была новая среда, особых мер предосторожности в отношении совместимости не требовалось.[17]

Сетевая файловая система в версии 4 поля времени определены как struct nfstime4 {int64_t секунд; uint32_t nseconds;} с декабря 2000 г.[19] Значения больше нуля для поля секунд обозначают даты после 0-часа 1 января 1970 г. Значения меньше нуля для поля секунд обозначают даты до 0-часового 1 января 1970 г. В обоих случаях nseconds (наносекунды) ) добавляется к полю секунд для окончательного представления времени.

Были внесены альтернативные предложения (некоторые из которых уже используются), такие как хранение либо миллисекунды или же микросекунды с эпохи (обычно либо 1 января 1970 г., либо 1 января 2000 г.) в виде 64-битного целого числа со знаком, обеспечивая минимальный диапазон 300 000 лет при микросекундном разрешении.[20][21] В частности, использование Java повсюду 64-битных длинных целых чисел для представления времени в виде «миллисекунд с 1 января 1970 года» будет правильно работать в течение следующих 292 миллионов лет. Другие предложения для новых представлений времени обеспечивают другую точность, диапазоны и размеры (почти всегда шире 32 бит), а также решают другие связанные проблемы, такие как обработка високосные секунды. В частности, TAI64[22] это реализация Международное атомное время (TAI), текущий международный стандарт реального времени для определения секунды и системы отсчета.

Смотрите также

Примечания

  1. ^ У GPS есть проблема переполнения счетчика времени, известная как Перенос номера недели GPS.
  2. ^ 2−64 секунд примерно 54 зептосекунды или же 54×10−21 s (свет прошел бы 16,26 пикометра, или примерно 0,31 × Радиус Бора ) и 264 секунд примерно 585 миллиардов лет.

Рекомендации

  1. ^ Бергманн, Арнд (6 февраля 2020 г.). "Конец эры". Линаро.
  2. ^ Вагензей, Пол (28 июля 2017 г.). «Цифровой« Эпохалипсис »может остановить мир». Руководство Тома.
  3. ^ Диомидис Спинеллис (2006). Качество кода: взгляд на открытый исходный код. Серия эффективных программных продуктов в Книги о сафари в Интернете (иллюстрированный ред.). Adobe Press. п. 49. ISBN  978-0-321-16607-4.
  4. ^ «Будущее впереди». 28 июня 2006 г.. Получено 19 ноября 2006.
  5. ^ Странная проблема с "утечкой памяти" в AOLserver 3.4.2 / 3.x 12 мая 2006 г.
  6. ^ Фэйи, Майк (21 января 2013 г.). "Бесконечные жизни в Candy Crush Saga Это не обман, это путешествие во времени ». Котаку.
  7. ^ «Проблема 2038 года - это новая ошибка 2000 года?». Хранитель. 17 декабря 2014 г.. Получено 11 октября 2018.
  8. ^ «Методы / процедуры испытаний ARB». ARB.ca.gov. Калифорнийский совет по воздушным ресурсам.
  9. ^ «ZTE Blade под управлением Android 2.2 имеет 2038 проблем». Получено 20 ноября 2018.
  10. ^ «Ошибки MySQL: # 12654: 64-разрядная временная метка unix не поддерживается в функциях MySQL». bugs.mysql.com.
  11. ^ «unix - уязвима ли какая-либо версия OS X / macOS для проблемы 2038 года?». Спросите другое. Получено 12 октября 2019.
  12. ^ Университет Делавэра Презентация Дэвида Миллса на семинаре по цифровым системам, 26 апреля 2006 г.
  13. ^ Фелтс, Боб (17 апреля 2010 г.). «Конец времени». Stablecross.com. Получено 19 марта 2012.
  14. ^ https://www.freebsd.org/cgi/man.cgi?arch
  15. ^ «Анонс NetBSD 6.0». 17 октября 2012 г.. Получено 18 января 2016.
  16. ^ «Релиз OpenBSD 5.5 (1 мая 2014 г.)». 1 мая 2014 г.. Получено 18 января 2016.
  17. ^ а б Джонатан Корбет (14 августа 2013 г.). «Размышляя до 2038 года». LWN.net. В архиве из оригинала 4 марта 2016 г.. Получено 9 марта 2016.
  18. ^ «LKML: Арнд Бергманн: [GIT PULL] y2038: изменения ядра, драйверов и файловой системы». lkml.org. Получено 30 января 2020.
  19. ^ Хейнс, Томас; Новек, Дэвид, ред. (Март 2015 г.). «Структурированные типы данных». Протокол сетевой файловой системы (NFS) версии 4. сек. 2.2. Дои:10.17487 / RFC7530. RFC 7530.
  20. ^ «Время Унунуниума». Архивировано из оригинал 8 апреля 2006 г.. Получено 19 ноября 2006.
  21. ^ Sun Microsystems. "Документация Java API для System.currentTimeMillis ()". Получено 29 сентября 2017.
  22. ^ "TAI64".

внешняя ссылка