Статьи

Отладка сбоя браузера IE7 (вручную git bisect)

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

Недавно у меня на столе появилось сообщение об ошибке, согласно которой наше веб-приложение ломало IE7. К счастью, IE7 составляет всего около 3% от нашей общей базы пользователей. По состоянию на май 2014 года доля рынка браузеров составляла всего около 0,2% , но у нас есть много корпоративных клиентов, которые медленнее переходят на новую версию. Несмотря на это, определенно ошибка высокой степени серьезности.

Кроме того, я нахожу сбои браузера смешными. Я знаю, что этот браузер был написан еще в темные века 2005 года, но все же. Если вы внедряете браузер, вы знаете, что в основном вы будете использовать случайную разметку и JavaScript от практически ненадежного пользователя. Вы бы подумали, что будете как можно дотошнее, чтобы поймать в ловушку все возможные исключения.

Но нет. В случае сбоя браузера вы не получите трассировку стека. Вы даже не получите страшную ошибку «Ожидаемый объект» (единственная самая бесполезная ошибка всех времен). Какие жалкие инструменты разработчика, которые Microsoft разработала в 2005 году, абсолютно бесполезны. Вместо этого все, что вы видите, это белый экран и следующее:

ie7 не отвечает

И так это начинается. В этом случае я предполагаю, что в какой-то момент в недавнем прошлом мы не ломали IE7. В противном случае мы бы, вероятно, получили этот отчет об ошибке ранее.

Первым делом всегда нужно получить воспроизводимость. Я могу воспроизвести мой надежный образ IE7 VirtualBox, предоставленный из xdissent / ievms . Зная, что меня ждет долгий путь, я также прилагаю некоторые усилия, чтобы мои воспроизводимые шаги были доведены до наименьшего самого быстрого самородка, который я могу. Во- первых, создать ярлык на рабочем столе Windows , под названием «очистить кэш», со следующей Цель: RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 255. По своему опыту я знаю, что если вы не очистите свой кэш между тестами, вы будете часами охотиться за фантомными файлами. Я делаю еще один ярлык с прямой ссылкой на страницу, которая вылетает на моем компьютере разработчика.

Я продолжаю тратить около часа, удаляя случайные фрагменты подозрительного кода, чтобы посмотреть, смогу ли я остановить его. Если мне это удастся, я начну вставлять часть удаленного кода обратно, пока он снова не выйдет из строя. Это медленный процесс. Иногда это помогает пойти в старую школу и поставить реальные alert()вызовы между подозрительными линиями. Наконец, я сужаю его до вызова require.js для импорта совершенно другого файла. По сути, я должен начать с нового файла.

Поэтому я меняю тактику и начинаю то, что по сути является бинарным поиском в нашей истории git, чтобы найти точный коммит, где это происходит. Примечание: если вы можете повторить вашу проблему исключительно в командной строке, вы должны использовать для этого git bisect . Я начинаю откатывать 10, 100, 1000 коммитов, пока не получу работающую сборку. Я должен вручную обновлять браузер каждый раз.

git checkout upstream/master~10
git checkout upstream/master~100
git checkout upstream/master~1000

При 1000 коммитах я снова получаю работающую сборку. Поэтому я пытаюсь 500 коммитов назад. Не работает. 750 коммитов. За работой. 625 коммитов и т. Д. После неожиданно нескольких итераций у меня остался небольшой набор потенциальных разрывных коммитов, которые я просматриваю вручную, пока не увижу это:

ie7 лишняя запятая

Исходя из своего опыта, я все время подозревал, что это может быть либо незакрытый тег HTML в шаблоне javascript, либо лишняя запятая. Я видел обе аварии старых версий IE. Что очень расстраивает, так это то, что это то, что ловит наша автоматизация:

>jshint bad_file.js
static/js/bad_file.js: line 611, col 45, Extra comma. (it breaks older versions of IE)

Но мы полагаемся на отдельных инженеров, которые устанавливают и запускают автоматизацию, на которую они также могут отказаться для отдельных коммитов и файлов. В любом случае, это было исправление в один символ примерно через 3 часа работы. В будущем я бы сэкономил время, просто запустив jshint для всего репо.