Содержание статьи
Дорога до сих пор
Год назад Chrome объявил о начальной поддержке
для встроенной отладки WebAssembly в Chrome DevTools.
Мы продемонстрировали базовую поддержку степпинга и поговорили о возможностях.
использование информации DWARF вместо
исходные карты открываются для нас в будущем:
- Разрешение имен переменных
- Художественные шрифты
- Оценка выражений в исходных языках
- … и многое другое!
Сегодня мы рады продемонстрировать, как обещанные функции воплощаются в жизнь.
и прогресс, достигнутый командами Emscripten и Chrome DevTools
в этом году, в частности, для приложений C и C ++.
Прежде чем мы начнем, имейте в виду, что это все еще бета-версия.
нового опыта, вам нужно использовать последнюю версию всех инструментов
на свой страх и риск, и если у вас возникнут проблемы, сообщите о них
https://bugs.chromium.org/p/chromium/issues/entry?template=DevTools+issue.
Давайте начнем с того же простого примера на C, что и в прошлый раз:
#include
void assert_less (int x, int y) {
if (x> = y) {
abort ();
}
}
int main () {
assert_less (10, 20);
assert_less (30, 20);
}
Для его компиляции мы используем последний
Emscripten
и передайте флаг -g
как и в исходном сообщении, чтобы включить отладку
информация:
emcc -g temp.c -o temp.html
Теперь мы можем обслуживать сгенерированную страницу с HTTP-сервера localhost (для
например, с подачей), и
откройте его в последней версии Chrome
Канарейка .
На этот раз нам также понадобится вспомогательное расширение, которое интегрируется с Chrome.
DevTools и помогает понять всю отладочную информацию
закодировано в файле WebAssembly. Пожалуйста, установите его, перейдя по этой
ссылка: goo.gle/wasm-debugging-extension
Вы также захотите включить отладку WebAssembly в DevTools.
Эксперименты . Откройте Chrome DevTools, щелкните значок шестеренки ( ⚙ ) в
в правом верхнем углу панели DevTools перейдите на панель Experiments
и отметьте Отладка WebAssembly: Включить поддержку DWARF .
Когда вы закроете Настройки DevTools предложит перезагрузить себя
чтобы применить настройки, давайте сделаем это. Это для разового
установка.
Теперь мы можем вернуться к панели Источники включить Пауза на
исключения (значок ⏸), затем установите флажок Пауза при обнаружении исключений и
перезагрузить страницу. Вы должны увидеть, что DevTools приостановлен на исключении:
По умолчанию останавливается на связующем коде, созданном Emscripten, но на
справа вы можете увидеть представление Стек вызовов представляющее трассировку стека
ошибка и может перейти к исходной строке C, которая вызвала
прервать
:
Теперь, если вы посмотрите в виде Scope вы увидите исходные имена
и значения переменных в коде C / C ++, и больше не нужно указывать
что означают искаженные имена, такие как $ localN
и как они соотносятся с
исходный код, который вы написали.
Это относится не только к примитивным значениям, таким как целые числа, но и к составным
такие типы, как структуры, классы, массивы и т. д., тоже!
Поддержка расширенного типа
Давайте рассмотрим более сложный пример, чтобы показать это. Этот
время, мы нарисуем Мандельброт
фрактал с
следующий код C ++:
#include
#include
int main () {
// Запускаем SDL.
int width = 600, height = 600;
SDL_Init (SDL_INIT_VIDEO);
SDL_Window * окно;
SDL_Renderer * рендерер;
SDL_CreateWindowAndRenderer (ширина, высота, SDL_WINDOW_OPENGL, & окно,
& рендерер);
// Создаем палитру со случайными цветами.
перечисление {MAX_ITER_COUNT = 256};
SDL_Color palette [MAX_ITER_COUNT];
srand (время (0));
for (int i = 0; i <MAX_ITER_COUNT; ++ i) {
palette [i] = {
.r = (uint8_t) rand (),
.g = (uint8_t) rand (),
.b = (uint8_t) rand (),
.a = 255,
};
}
// Вычислить и нарисовать множество Мандельброта.
std :: complex центр (0,5, 0,5);
двойная шкала = 4,0;
for (int y = 0; y <height; y ++) {
for (int x = 0; x <width; x ++) {
std :: complex точка ((двойная) x / ширина, (двойная) y / высота);
std :: complex c = (точка - центр) * масштаб;
std :: complex z (0, 0);
int я = 0;
для (; i < MAX_ITER_COUNT - 1; i++) {
z = z * z + c;
if (abs(z) > 2.0)
сломать;
}
SDL_Color color = палитра [i];
SDL_SetRenderDrawColor (средство визуализации, color.r, color.g, color.b, color.a);
SDL_RenderDrawPoint (средство визуализации, x, y);
}
}
// Отрисовываем все, что мы нарисовали, на холсте.
SDL_RenderPresent (средство визуализации);
// SDL_Quit ();
}
Как видите, это приложение все еще довольно маленькое — это одно
файл, содержащий 50 строк кода, но на этот раз я также использую некоторые
внешние API, например SDL
библиотека для
графика а также комплекс
номера из
Стандартная библиотека C ++.
Я собираюсь скомпилировать его с тем же флагом -g
что и выше, чтобы включить
отладочная информация, а также я попрошу Emscripten предоставить SDL2
библиотека и разрешить произвольный размер памяти:
emcc -g mandelbrot.cc -o mandelbrot.html -s USE_SDL = 2 -s ALLOW_MEMORY_GROWTH = 1
Когда я захожу на созданную страницу в браузере, я вижу красивый
фрактальная форма со случайными цветами:
Когда я снова открываю DevTools, я вижу исходный файл C ++. Этот
время, однако, у нас нет ошибки в коде (уф!), поэтому давайте установим
вместо этого некоторая точка останова в начале нашего кода.
Когда мы снова перезагружаем страницу, отладчик останавливается прямо внутри нашего
Источник C ++:
Мы уже видим все наши переменные справа, но только ширину
и высота
инициализированы в данный момент, так что особо
осмотреть.
Давайте установим еще одну точку останова внутри нашего основного цикла Мандельброта и продолжим
казнь, чтобы пропустить немного вперед.
На этом этапе наша палитра
была заполнена случайными цветами,
и мы можем расширять как сам массив, так и отдельные
SDL_Color
строит и проверяет их компоненты, чтобы убедиться, что
все выглядит хорошо (например, всегда установлен альфа-канал
до полной непрозрачности). Точно так же мы можем развернуть и проверить реальные и
мнимые части комплексного числа, хранящиеся в переменной center
.
Если вы хотите получить доступ к глубоко вложенному свойству, которое иначе трудно
перейдите в вид Область вы можете использовать консоль
оценка тоже! Однако обратите внимание, что более сложные выражения C ++ не
пока поддерживается.
Давайте возобновим казнь несколько раз, и мы увидим, как внутренний x
также изменится — либо снова взглянув в представление Scope добавив
имя переменной в список наблюдения, оценивая его в консоли или
при наведении курсора на переменную в исходном коде:
Отсюда мы можем переходить или переходить операторы C ++ и наблюдать, как
другие переменные тоже меняются:
Хорошо, все это отлично работает, когда доступна отладочная информация, но
что, если мы хотим отладить код, который не был создан с помощью отладки
варианты?
Отладка Raw WebAssembly
Например, мы попросили Emscripten предоставить предварительно созданную библиотеку SDL для
нам, вместо того, чтобы собирать его сами из исходников, поэтому — по крайней мере
в настоящее время отладчик не может найти связанные источники.
Давайте сделаем шаг еще раз, чтобы перейти к SDL_RenderDrawColor
:
Мы вернулись к исходному опыту отладки WebAssembly.
Теперь это выглядит немного пугающе, и большинство веб-разработчиков не хотят
когда-либо нужно иметь дело, но иногда вы можете захотеть отладить
библиотека, созданная без отладочной информации — будь то потому, что это
3 сторонняя библиотека, которую вы не контролируете, или потому что вы
столкнулся с одной из тех ошибок, которые возникают только в производственной среде.
Чтобы помочь в этих случаях, мы внесли некоторые улучшения в основные
опыт отладки тоже.
Прежде всего, если вы раньше использовали необработанную отладку WebAssembly, вы могли
обратите внимание, что вся разборка теперь отображается в одном файле — нет
больше догадываюсь, какая функция Sources запись wasm-53834e3e /
возможно, соответствует.
wasm-53834e3e-7
Схема генерации нового имени
Мы также улучшили имена в режиме разборки. Раньше вы видели
просто числовые индексы или, в случае функций, вообще без имени.
Теперь мы генерируем имена аналогично другим инструментам дизассемблирования.
используя подсказки из названия WebAssembly
раздел ,
пути импорта / экспорта и, наконец, если все остальное не удается, создание
они основаны на типе и индексе элемента, например $ func123
. Вы можете
посмотрите, как на скриншоте выше это уже помогает немного
более удобочитаемые трассировки стека и разборка.
Когда нет информации о типе, может быть трудно проверить
любые значения, кроме примитивов — например, будут отображаться указатели
как обычные целые числа, без возможности узнать, что за ними хранится в
память.
Проверка памяти
Раньше вы могли только расширить объект памяти WebAssembly —
представлен env.memory
в представлении Scope — искать
отдельные байты. Это сработало в некоторых тривиальных сценариях, но не
особенно удобно расширять и не позволяло повторно интерпретировать данные
в форматах, отличных от байтовых значений. Мы добавили новую функцию, чтобы помочь
с этим тоже: линейный инспектор памяти.
Если щелкнуть правой кнопкой мыши по env.memory
вы должны увидеть новый
опция называется Проверить память :
После щелчка откроется Инспектор памяти в
который вы можете проверять в памяти WebAssembly в шестнадцатеричном и ASCII представлениях,
переходить к конкретным адресам, а также интерпретировать данные в
разные форматы:
Расширенные сценарии и предостережения
Профилирование кода WebAssembly
Когда вы открываете DevTools, код WebAssembly «привязывается» к
неоптимизированная версия для включения отладки. Эта версия намного медленнее,
это означает, что вы не можете полагаться на console.time
performance.now
и другие методы измерения скорости вашего кода, пока DevTools
открытые, так как числа, которые вы получите, не будут отражать реальную производительность
вообще.
Вместо этого вы должны использовать DevTools Performance
панель
который запустит код на полной скорости и предоставит вам
подробная разбивка времени, затраченного на выполнение различных функций:
Кроме того, вы можете запустить приложение с закрытым DevTools и
откройте их после завершения, чтобы осмотреть Консоль .
В будущем мы будем улучшать сценарии профилирования, но пока это
будьте осторожны. Если вы хотите узнать больше о WebAssembly
многоуровневые сценарии, ознакомьтесь с нашей документацией по компиляции WebAssembly
трубопровод .
Сборка и отладка на разных машинах (включая Docker / host)
При сборке в Docker, виртуальной машине или на удаленном сервере сборки
вы, вероятно, столкнетесь с ситуациями, когда пути к исходным файлам
используемые во время сборки, не совпадают с путями в вашей файловой системе, где
Chrome DevTools запущены. В этом случае файлы будут отображаться в
Панель источников но не загружается.
Чтобы решить эту проблему, мы реализовали функцию сопоставления путей в
параметры расширения C / C ++. Вы можете использовать его для переназначения произвольных путей и
помочь DevTools найти источники.
Например, если проект на вашем хост-компьютере находится в пути
C: src my_project
но был построен внутри контейнера Docker, где
этот путь был представлен как / mnt / c / src / my_project
вы можете переназначить
его обратно во время отладки, указав эти пути в качестве префиксов:
Первая совпавшая приставка «выигрывает». Если вы знакомы с другим C ++
отладчикам, эта опция аналогична команде set substitute-path
в GDB или параметр target.source-map
в LLDB.
Отладка оптимизированных сборок
Как и с любыми другими языками, отладка работает лучше всего, если оптимизация
отключен. Оптимизация может встраивать функции одна в другую, менять порядок
код, или удалить части кода вообще — и все это имеет
шанс запутать отладчик и, следовательно, вас как пользователя.
Если вы не возражаете против более ограниченных возможностей отладки и все же хотите
отладить оптимизированную сборку, тогда большая часть оптимизаций будет работать как
ожидается, за исключением встраивания функций. Мы планируем заняться оставшимися
проблемы в будущем, но пока используйте -fno-inline
чтобы
отключите его при компиляции с любой оптимизацией уровня -O
например:
emcc -g temp.c -o temp.html -O3 -fno-inline
Разделение отладочной информации
Информация об отладке сохраняет множество деталей вашего кода, определенных
типы, переменные, функции, области действия и местоположения — все, что может
быть полезным отладчику. В результате он часто может быть больше, чем
сам код.
Чтобы ускорить загрузку и компиляцию модуля WebAssembly, вы можете
хотите выделить эту отладочную информацию в отдельный WebAssembly
файл. Для этого в Emscripten передайте флаг -gseparate-dwarf =…
с
желаемое имя файла:
emcc -g temp.c -o temp.html -gseparate-dwarf = temp.debug.wasm
В этом случае основное приложение сохранит только имя файла
temp.debug.wasm
а вспомогательное расширение сможет найти и
загружать его при открытии DevTools.
В сочетании с оптимизацией, описанной выше, эта функция может
даже использоваться для доставки почти оптимизированных производственных сборок вашего
приложение, а затем отладить их с помощью локального файла. В этом случае,
нам также потребуется переопределить сохраненный URL, чтобы расширение
найдите дополнительный файл, например:
emcc -g temp.c -o temp.html -O3 -fno-inline -gseparate-dwarf = temp.debug.wasm -s SEPARATE_DWARF_URL = file: // [local path to temp.debug.wasm]
Продолжение следует…
Уф, много нового!
Благодаря всем этим новым интеграциям Chrome DevTools становится жизнеспособным,
мощный отладчик не только для JavaScript, но и для приложений C и C ++,
упрощает использование приложений, встроенных в различные
технологий и перенести их в общую кроссплатформенную сеть.
Однако наше путешествие еще не закончено. Некоторые вещи, которыми мы будем
работаем с этого момента:
- Устранение острых углов при отладке.
- Добавлена поддержка средств форматирования пользовательского типа.
- Работа над улучшением
профилирование для приложений WebAssembly. - Добавлена поддержка покрытия кода, чтобы упростить поиск
неиспользованный код. - Улучшение поддержки выражений при вычислении консоли.
- Добавлена поддержка других языков.
- … и многое другое!
Тем временем, пожалуйста, помогите нам, попробовав текущую бета-версию на своем собственном коде и сообщив обо всех обнаруженных
вопросы к
https://bugs.chromium.org/p/chromium/issues/entry?template=DevTools+issue.
Следите за новостями в будущем!
Отзыв
Была ли эта страница полезной?
Да
Что было лучше всего на этой странице?
Это помогло мне достичь моих целей
создать проблему.
Там была вся необходимая мне информация
создать проблему.
У него была точная информация
создать проблему.
Легко читать
создать проблему.
Что-то еще
создать проблему.
Нет
Что было хуже всего на этой странице?
Это не помогло мне достичь моих целей
создать проблему.
Отсутствовала нужная мне информация
создать проблему.
Он содержал неточную информацию
создать проблему.
Было трудно читать
создать проблему.
Что-то еще
создать проблему.
Чтобы обсудить новые функции и изменения в этом сообщении или что-либо еще, связанное с DevTools:
Ознакомьтесь с инженерными материалами DevTools
Ниже приводится список всего, что было освещено в серии Chrome DevTools Engineering Blog .