Смерть, налоги и безудержно разрастающиеся браузерные движки — вот три вещи, в которых можно быть твёрдо уверенным. Актуально это было и на начало 2020 года, когда я осознал, что из-за безжалостного роста Chromium рано или поздно мы будем создавать файлы PDB (отладочных символов Windows), превосходящие предел формата PDB в 4 ГиБ.
В феврале 2020 года я зарегистрировал баг Visual Studio с просьбой увеличения этого предела, и спустя три года и три дня мы дёрнули рубильник, и теперь Chromium может создавать PDB большего размера. На тот момент PDB для Chrome занимал 95% от 4 ГиБ, а многие тестовые двоичные файлы уже преодолели этот порог, так что это было сделано вовремя.
Формат PDB основан на страницах; он допускает до двух в двадцатой степени (2^20, или 1 048 576) страниц, а стандартный размер страницы равен 4 КиБ. Умножив эти два числа, мы получим максимальный размер 4 ГиБ. Максимальное количество страниц нельзя увеличить, зато можно увеличить размер страниц. На самом деле, разработчики формата PDB всегда признавали необходимость в разных размерах страниц, но, по сути, ни один инструмент никогда не поддерживал размер страницы, отличающийся от 4 КиБ.
Для поддержки более крупных PDB нужно было «всего-то» обновить несколько инструментов, чтобы они поддерживали страницы большего размера. Этими инструментами были:
- Отладчик Visual Studio
- link.exe – компоновщик Microsoft
- lld-link – компоновщик, используемый Chromium
- windbg и другие отладчики (kd.exe, ntsd.exe и так далее)
- dbghelp.dll (используется для загрузки символов)
- pdbstr.exe (используется для индексации исходников)
- symstore.exe (используется для загрузки на серверы символов)
- msdia140.dll (COM API для загрузки символов)
- Windows Performance Analyzer (WPA, программа для просмотра трассировок ETW)
- Возможно, другие инструменты
Всё просто!
Согласно комментариям под багом, внутреннее исправление было выпущено Microsoft в августе 2021 года. К декабрю это исправление было реализовано в обновлениях Visual Studio 2019 и в только что выпущенной Visual Studio 2022, а lld-link тоже поддерживал его. После того, как компоновщики начали поддерживать страницы большего размера, мы добавили параметр сборки use_large_pdbs, который переключал размер страницы PDB на 8 КиБ. Однако поначалу этот параметр по умолчанию необходимо было отключать из-за отсутствия полной поддержки инструментами.
В идеале обновления других инструментов должны были выйти осенью 2021 года, но… этого не произошло. Я обратился к командам разработчиков Windbg и WPA: у меня сложилось впечатление (хотя я могу ошибаться), что они не осознавали, что нужно выкатить обновления, пока я им об этом не сказал.
У windbg (и множества связанных с ним инструментов) и WPA есть множество каналов релизов, поэтому сложно сказать, когда впервые были выпущены исправления в этих инструментах. В версиях Microsoft Store и в nuget поддержка больших PDB появилась где-то в 2022 году, однако выпускать обновления для всех версий всех этих инструментов целесообразно стало лишь после выпуска Windows 11 22H2 SDK осенью 2022 года.
Ещё одним мешающим нам аспектом была Windows 7. У новых версий dbghelp.dll возникали проблемы с работой в Windows 7. Поэтому пока мы выполняли тесты в Windows 7, нам приходилось генерировать PDB, работавшие со старыми версиями dbghelp.dll. Версия 109 браузера Chrome — это последняя версия с поддержкой Windows 7, поэтому сразу после того, как мы создали ветвь этой версии, я мог начать над поддержкой больших PDB в основной ветви.
Во время работы над исправлением я столкнулся со множеством загадочных сбоев — это можно понять по тому, что моя первая публичная попытка создать изменение для перехода на большие PDB датируется 28 декабря, более чем за месяц до реализации изменения. Первая проблема заключалась в том, что один тест упорно отказывался загружать обновлённые файлы PDB. Постепенно мне удалось сузить проблему до неудачной попытки теста загрузить новую версию dbghelp.dll. Затем я потратил много времени, разбираясь с тем, какой импорт DLL вызывал проблемы, но потом осознал… что новая dbghelp.dll не была развёрнута на тестовых машинах. Сложно загрузить DLL, которой нет. Очень забавно, что мы не разворачивали dbghelp.dll на тестовых машинах несколько лет, но системная версия была достаточно хороша, поэтому это было неважно и этот баг раньше не замечали. Я развернул классную диагностику снэпшотов загрузчика (на основе этого инструмента), но в конечном итоге это оказалось лишней тратой времени, ведь причиной было отсутствие DLL.
Другой загадочный сбой происходил только на наших официальных сборщиках, что сильно усложнило тестирование. Этот сбой был вызван загрузкой неверной версии msdia140.dll. Почти идеальная параллель с первой проблемой: мы никогда не разворачивали msdia140.dll должным образом. Я всё ещё не знаю, откуда она загружалась ранее, однако скопировав нужную версию в выходную папку, мы решили проблему.
Наконец, спустя 37 дней и 38 наборов патчей после загрузки первой версии моего изменения я его реализовал. Новый предел размера PDB составляет 8 ГиБ, но когда нам понадобится, мы снова сможем удвоить размер страницы.
Подобные изменения с лёгкостью могут приводить к авариям — сложно предусмотреть все скрытые зависимости или места сбоев, поэтому я был доволен, когда развернул изменение и не услышал после этого практически никаких отрицательных отзывов. Пара людей пожаловалась, что разные инструменты не могут загружать символы Chrome Canary, однако во всех случаях проблему решало обновление необходимых инструментов до последнего Windows 11 SDK. Стоит заметить, что по умолчанию Windows SDK не устанавливает отладчики и Windows Performance Toolkit (в который входит WPA), поэтому если вам необходимы эти инструменты, их нужно выбрать при установке, в противном случае у вас останутся старые версии.
Большинство людей не работает с Chromium, но если вы работаете с Chrome, то когда-нибудь вам может понадобиться возможность профилировать или отлаживать официальные сборки. Можно настроить свои инструменты, чтобы они указывали на сервер символов Chrome, и тогда символы и исходники будут загружаться по требованию, но только если вы работаете с инструментами, совместимыми с большими PDB. Я знаю, что некоторые игровые студии тоже столкнулись с ограничением в 4 ГиБ, поэтому таким разработчикам тоже нужны самые новые инструменты.
Я обновил UIforETW так, чтобы при запуске она устанавливала последнюю версию WPA. Последний релиз (сейчас это 1.58) можно найти здесь.