Почему айфоны зависают при установке даты 01.01.1970

Блогер Tom Scott в своем новом видео объясняет причину поломки айфонов и айпадов после установки даты 1 января 1970 года:

Я не собирался снимать еще одно видео о багах iPhone, но недавно найденная «ошибка 1970 года» довольно интересна, и о таких я, кажется, не рассказывал.

В двух словах, это почти наверняка недополнение целого числа, вызванное эпохой Unix. Тем, кто понял смысл сказанного — это видео без надобности.

Остальные — пристегнитесь, и поехали!

Первое января 1970 года — особенный день для компьютеров. В 70-х, когда операционная система UNIX и ее друзья только создавались, программистам нужен был простой способ хранить дату и время без мороки с неудобными человеческими понятиями дней, часов и минут.

Им нужны были идущие часы, которыми легко пользоваться в расчетах. И самые простые такие часы — обычное целое число, в котором записано, сколько секунд прошло с 1 января 1970 года.

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

Я уже снимал видео об этом, поэтому не буду задерживаться, но все сводится к тому, что полночь 1 января 1970 года — дата, о которой идет речь — это 0. В этом первая улика.

Вторая улика: ошибка происходит только на новых 64-битных айфонах. Слово «64-битный» описывает то, как процессор хранит числа. В распоряжении процессора 64 двоичных цифры вместо 32-х, что дает ему, например, работать с большими числами на уровне самого процессора без хитрых программных приемов.

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

Начнем с 4 битов, чтобы понять, как это работает.

0000 — это 0, после этого мы считаем в двоичной системе:

0001 — 1,

0010 -2 ,

0011 -3

и так далее, пока не дойдем до 1111 — 15. Это самое большое число, которое можно сохранить в 4 битах. Больше этого посчитать не выйдет.

Но что будет, если попробовать? Мы получим так называемое переполнение целого. После 15 пойдет… снова 0. Значение прокручивается, и мы начинаем сначала, как старый, аналоговый автомобильный одометр.

С 4 битами это, очевидно, будет проблемой, но с 64 битами неприятности начнутся с числами больше 15 квинтиллионов, так что, скорее всего, все будет в порядке.

Но, если максимальное хранимое число плюс один дает нам ноль, что дает ноль минус один?

Такая ошибка называется недополнением целого. В такой формат не получится записать отрицательное число. Уменьшив число ниже нуля, мы не получим -1, мы снова прокрутимся и придем к максимальному значению.

Из-за этого в оригинальной версии игры «Civilization» Ганди был сволочью. Он начинал игру с уровнем агрессии 1. По ходу игры уровень агрессии снижался, и никто не написал проверку, не дающую ему упасть ниже нуля. Вместо этого он прокручивался, становился максимальным, и ни с того ни с сего Ганди объявлял войны направо и налево. К счастью, только в игре.

Конечно, есть вариант этого формата, могущий хранить отрицательные числа, но если бы Apple его использовали, этой проблемы, скорее всего, не было бы.

В конце концов, зачем вообще нужно отрицательное значение времени? Ведь никто в своем уме не будет ставить часы на iPhone на время раньше 1970 года! Поскольку это невозможно.

Если дойти до начала календаря, он останавливается на 1 января 1970 года, на нуле, потому что кто-то в Apple сказал: «Стоп, нет, это плохая мысль, это может довести до беды.»

Поэтому эта самая эпоха Unix, как ее называют, эта нулевая точка ограничивает календарь.

Но, если поставить время телефона близко к нулю, одна из проверок в коде системы — возможно, посчитать время работы батареи, может быть, вычисление времени последнего звонка — что именно, никто еще точно не знает, но что бы эта проверка не делала, она получает время раньше, чем 1 января 1970 года, которое должно бы быть просто отрицательным, но нет.

Оно прокручено, в нем дата в двадцать раз больше, чем ожидаемое время жизни Вселенной, и мне кажется, что программа не очень хорошо справится с отображением этой даты.

Что бы это ни было, оно вызывает «недокументированное поведение», а если неформально — система падает.

Я должен сказать, что как и каждая моя попытка разобраться в баге продукта Apple, это всего лишь предположение — вряд ли они в какой-то момент расскажут, что именно случилось, и, скорее всего, проблема немного глубже и сложнее.

Существует другой тип двоичного целого числа, называемый знаковым числом, который справляется с отрицательными числами. Но это уже совсем другая история.

Даже если причина не в этом — надеюсь, вы сможете избежать такой ошибки в коде в будущем.

Почему айфоны зависают при установке даты 01.01.1970: 3 комментария

  1. У меня в телефоне появилась фотография, сделанная 1 января 1970 года, что это значит ?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *