Найти в Дзене
Цифровая Переплавка

🐞 «Охота на баг»: Как два дня искали самую невероятную ошибку в Google Docs

Оглавление

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

📌 Начало: внезапный сбой в Google Docs

Однажды утром команда Google Docs столкнулась со странной ситуацией: количество ошибок в приложении резко возросло, хотя явных жалоб от пользователей не поступало. Ошибка была критической и странной — она происходила только в Chrome, только начиная с определённой версии браузера и не была привязана к каким-либо изменениям в самом Google Docs.

Команде предстояло ответить на вопросы:

  • 🧐 Почему ошибка проявляется так выборочно?
  • 🤔 Почему её почти невозможно воспроизвести?
  • 🔍 Почему стандартные методы поиска не работают?

⚙️ Технические детали: от простых догадок к безумию

Автор статьи, бывший сотрудник команды Google Docs Джейкоб Войтко, решил разобраться лично. Его первая мысль была о проблемах компиляции JavaScript-кода с помощью Closure Compiler (популярного инструмента, используемого Google Docs). Чтобы исключить эту версию, он начал тестировать проблему на некомпилированной версии кода — и всё равно получил ту же ошибку. Значит, дело не в компиляторе.

🔥 Первый успех: воспроизведение ошибки

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

Тут важный нюанс: у текста в разных стилях менялась ширина строк, что могло косвенно влиять на внутреннюю логику рендера страниц. Это натолкнуло на мысль, что дело связано с подсчётами размеров и кешированием значений в специальном движке Google Docs, который отрисовывал всё на странице через абсолютное позиционирование элементов, а не через обычный HTML.

🚧 Кошмар отладки: логика и кеширование

Код Google Docs тех времён был невероятно сложным — каждое изменение приводило к перерасчёту всего документа. В результате любые ошибки в промежуточных данных постепенно накапливались и приводили к неожиданным завершением программы.

Проблема оказалась в вычислениях, связанных с подсчётом ширины элементов, где в коде была функция Math.abs(). И вот тут началась настоящая магия: оказалось, что именно эта функция иногда возвращала отрицательные значения (!). Если вы знаете JavaScript, вы понимаете, насколько это невозможно — ведь суть Math.abs() — всегда возвращать положительное значение.

🎩 Волшебство или баг браузера?

Команда долго не могла поверить в реальность происходящего. Была вызвана техлид, известная своей способностью буквально компилировать JavaScript-код «в голове». Даже она сначала не поверила, но спустя несколько минут анализа кода признала — Math.abs() реально возвращает отрицательные числа в Chrome.

Оказалось, что проблема была не в Google Docs, а в движке V8, на котором работает JavaScript в Chrome. Во время оптимизации разработчики V8 допустили невероятную ошибку: на супер-оптимизированном пути исполнения кода они случайно превратили функцию Math.abs() в функцию, возвращающую исходное значение, вместо абсолютного!

🚑 Как проблему решили?

Баг уже был исправлен в самом V8, но версия браузера с ошибкой ещё широко использовалась пользователями. Поэтому команда добавила временный костыль — ручную проверку версии браузера и альтернативную реализацию функции прямо в коде Google Docs. А также огромный комментарий в коде с объяснением и ссылками, чтобы в будущем этот костыль можно было спокойно убрать.

🤯 Уроки из невероятной истории

  • 🎲 Баги бывают совершенно абсурдными. Иногда логика не поможет, и нужно проверять даже невозможное.
  • 👥 Не стесняйтесь просить помощи коллег. Джейкоб справился лишь благодаря опыту и взгляду других сотрудников.
  • 📚 Документируйте странные решения. Ваше будущее «я» скажет спасибо, когда наткнётся на костыль в коде.

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

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

📌 Источник: