Qualcomm: перезапуск устройства HTC One M7 через WebGL и мерцающие прямоугольники

[Из серии статей об ошибках компилятора шейдеров графического процессора.]

[Предыдущая остановка: NVIDIA]

Мы использовали GLFuzz для тестирования устройства с графическим процессором Qualcomm: телефона HTC One M7 под управлением Android с графическим процессором Adreno 320. GLFuzz обнаружил много проблем, включая перезапуск устройства. Мы сообщили о проблемах ниже в Qualcomm, но пока не получили никакого ответа.

Вы видите мерцающий прямоугольник?

Проверьте, не возникает ли в вашем телефоне мерцающий прямоугольник, посетив эту веб-страницу. Наш HTC One M7 умеет.

Перезагрузка телефона

Подобно нашим предыдущим сообщениям о синем экране смерти на рабочем столе AMD и зависании пользовательского интерфейса на рабочем столе NVIDIA, мы можем вызвать сбой и перезапуск телефона HTC через веб-страницу, которая используется через WebGL. GLFuzz создал несколько шейдеров, которые вызывают перезапуск устройства. Это работает как в стандартном браузере, так и в Chrome. Это видео показывает проблему:

Как показано, пользовательский интерфейс обычно перестает отвечать на запросы в течение нескольких секунд до того, как телефон выйдет из строя. Телефон не всегда вылетает; иногда происходит сбой просто процесса браузера, хотя при повторном открытии браузера страница сразу же перезагружается, что увеличивает вероятность перезапуска устройства.

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

В интересах ответственного раскрытия информации мы не будем раскрывать фрагментные шейдеры, вызывающие сбои устройства.

Откуда взялся этот мерцающий желтый прямоугольник !?

Для тех, кто не читал наше введение, наше тестовое приложение визуализирует плоский прямоугольник, заполняющий экран, и затемняет его с помощью предоставленного фрагментного шейдера. Например, мы протестировали фрагментный шейдер с GLSLSandbox.com, который создает это изображение на нашем устройстве HTC с графическим процессором Qualcomm:

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

Появился странный желтый прямоугольник, и, похоже, GLFuzz обнаружил ошибку компилятора.

В этом случае GLFuzz добавил семь невыполнимых операторов возврата в вариантный шейдер формы:

if(injectionSwitch.x > injectionSwitch.y) { return X;}

и один с формой:

if(false || (injectionSwitch.x > injectionSwitch.y)) { return X;}

где X - буквальное значение (например, vec2 (1.0)). Напомним, что «инъекцияSwitch.x› инъекцияSwitch.y »будет ложью во время выполнения, потому что инъекцияSwitch получает значение (0.0, 1.0 ), поэтому эти инъекции не должны иметь никакого значения.

Это удивительно большое количество инъекций по сравнению с другими примерами, которые мы видели. Параметр «false ||» также интересен, поскольку вы ожидаете, что компилятор его оптимизирует. Удаление любой из инъекций (включая «false ||») приводит к исчезновению желтого прямоугольника (и, следовательно, проблемы).

Примечательно, что желтый прямоугольник тоже мерцает, несмотря на то, что изображение должно быть статичным! Проверить это:

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

Шейдеры совместимы с WebGL, поэтому вы можете легко просматривать их в своем браузере. Сообщите нам, если вы заметите какие-либо проблемы на своих устройствах:

Https://github.com/mc-imperial/shader-compiler-bugs/issues/9

Печально известная красная космическая сцена

Один из протестированных шейдеров создает изображение космической сцены на большинстве настольных платформ:

Тем не менее, мы обнаружили, что многие устройства Android, включая HTC One M7, отображают этот шейдер как красное изображение:

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

Однако в случае сцены с красным пространством GLFuzz создал вариант, который отображает черное изображение:

Таким образом, изображение отличается как от предполагаемого, так и от исходного изображения на HTC One M7. GLFuzz изменил следующий оператор исходного шейдера:

vec4 newCol = (forCol2 + vec4(backCol2, 1.0)) * 1.0;

на следующее (в варианте шейдера):

vec4 newCol = (forCol2 + vec4(backCol2, 1.0)) * (1.0 + injectionSwitch.x);

Напомним, что инъекцияSwitch.x всегда будет 0,0 во время выполнения, поэтому эта инъекция не должна иметь никакого значения для визуализированного изображения.

Шейдеры совместимы с WebGL, поэтому вы можете легко просматривать их в своем браузере. Сообщите нам, если вы заметите какие-либо проблемы на своих устройствах:

Https://github.com/mc-imperial/shader-compiler-bugs/issues/27

Хорошо, на этом мы завершаем наш обзор ошибок компилятора шейдеров в драйверах от семи основных разработчиков графических процессоров - AMD, Apple, ARM, Imagination, Intel, NVIDIA и Qualcomm!

Мы надеемся, что вам понравились публикации, и по многочисленным просьбам мы скоро опубликуем еще несколько историй о фаззинге драйверов Mesa с открытым исходным кодом.