1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/CarGuo-GSYFlutterBook

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Flutter-iOS184.md 11 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 10.03.2025 00:06 5767d61

Не производите обновление, Flutter Debug в iOS 18.4 beta не работает, выдает ошибку mprotect failed: Permission denied

Если недавно какой-либо разработчик обновил своё устройство iOS до версии 18.4 beta, то с большой вероятностью он столкнётся с ошибкой Permission denied, когда будет запускать приложение в режиме отладки:../../../flutter/third_party/dart/runtime/vm/virtual_memory_posix.cc: 428: ошибка: mprotect завершился с ошибкой: 13 (Отказано в доступе) версия=3.6.0 (стабильная) (Чт Дек 5 07:46:24 2024 -0800) на "ios_arm64" pid=3252, thread=259, isolate_group=vm-isolate(0x107205400), isolate=vm-isolate(0x107369000) os=ios, arch=arm64, comp=no, sim=no isolate_instructions=108e375a0, vm_instructions=108e375a0 fp=16bb19560, sp=16bb19540, pc=109889864 pc 0x0000000109889864 fp 0x000000016bb19560 Dart_DumpNativeStackTrace+0x18 pc 0x000000010943aeb8 fp 0x000000016bb19580 dart::Assert::Fail(char const*, ...) const+0x30 pc 0x0000000109536100 fp 0x000000016bb19a30 dart::Code::FinalizeCode(dart::FlowGraphCompiler*, dart::compiler::Assembler*, dart::Code::PoolAttachment, bool, dart::CodeStatistics*)+0x82c pc 0x00000001095f51c8 fp 0x000000016bb1a040 dart::StubCode::Init()+0x31c pc 0x0000000109485c30 fp 0x000000016bb1ab00 dart::Dart::DartInit(Dart_InitializeParams const*)+0x2a9c pc 0x0000000109870310 fp 0x000000016bb1ab20 Dart_Initialize+0x3c pc 0x0000000108f1aaf4 fp 0x000000016bb1b0f0 flutter::DartVM::Create(flutter::Settings const&, fml::RefPtr<flutter::DartSnapshot const>, fml::RefPtr<flutter::DartSnapshot const>, std::_fl::shared_ptr<flutter::IsolateNameServer>)+0x1d60 pc 0x00000001093f17dc fp 0x000000016bb1b850 flutter::Shell::Create(flutter::PlatformData const&, flutter::TaskRunners const&, flutter::Settings, std::_fl::function<std::_fl::unique_ptr<flutter::PlatformView, std::_fl::default_delete<flutter::PlatformView>> (flutter::Shell&)>> const&, std::_fl::function<std::_fl::unique_ptr<flutter::Rasterizer, std::_fl::default_delete<flutter::Rasterizer>> (flutter::Shell&)>> const&, bool)+0x310 pc 0x0000000108e3b060 fp 0x000000016bb1c5c0 -[FlutterEngine createShell:libraryURI:initialRoute:]+0x934 pc 0x0000000108e42c4c fp 0x000000016bb1c630 -[FlutterViewController sharedSetupWithProject:initialRoute:]+0x1cc pc 0x0000000108e42a58 fp 0x000000016bb1c660 -[FlutterViewController awakeFromNib]+0x58Из логов видно, что проблема связана с недостаточными правами доступа при попытке Dart VM инициализировать внутренние файлы для JIT компиляции. Основная идея заключается в том, что по данным текущей версии iOS 18.4 beta, Apple усилила ограничения на возможность приложений менять права доступа к памяти во время выполнения, то есть причина ошибки mprotect failed: 13 (Permission denied).

mprotect расшифровывается как "memory protect", используется для изменения атрибутов защиты страниц памяти, позволяя приложению динамически изменять права доступа к определенной области памяти, например, с RX (только чтение и выполнение) на RW (чтение и запись).

Иллюстрация

А почему Flutter требует mprotect в режиме отладки? Это связано с тем, что Dart VM использует JIT (Just-In-Time) компиляцию для выполнения кода в режиме отладки, но с версии Dart 2.0 прямое выполнение кода из исходников больше не поддерживается, поэтому все Dart-коды теперь компилируются в специальную форму бинарного файла Kernel AST, который мы также называем двоичным файлом .dill.

То есть даже если вы запускаете Dart в режиме JIT, вы всё равно работаете с бинарным Kernel-dill файлом, хотя сам Kernel AST не содержит парсер и оптимизатор:

Проще говоря, это просто преобразование исходного кода в унифицированный и платформонезависимый промежуточный формат.Поэтому когда Flutter выполняется в режиме отладки, он запускает незакрепленный бинарный файл через JIT, и ему требуется возможность немедленной загрузки (горячая загрузка). Это значит, что Dart VM должна генерировать машинный код на основе Kernel-бинарного файла во время выполнения, и эта операция требует системного вызова mprotect.

Например, часть связана со StubCode, которая сильно зависит от динамической генерации кода во время выполнения в текущем режиме JIT.

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

Почему же в режимах выпуска и профиля проблем нет? Очень просто, потому что код уже полностью собран в машинный код, и все необходимые для его выполнения части включены в снимок, так что дополнительные манипуляции не нужны.Тогда обратимся к новому ограничению iOS 18.4, которое усиливает контроль над возможностью приложений менять права доступа к памяти во время выполнения. Конкретнее говоря:

Система больше не позволяет незаконченным подписью кодом двоичных файлов проходить JIT-компиляцию и выполнять напрямую; ранее это было возможно, так как это был "безопасный уязвимость", поскольку предыдущий механизм позволял разработчикам обходить некоторые требования подписи на реальном устройстве; теперь новая безопасная политика iOS 18.4 запрещает эту поддержку генерации неотмеченного динамического кода.Итак, вы должны примерно понять причину проблемы. В настоящее время представители Flutter сообщили: пока они не исправят эту проблему, рекомендуется не обновляться до iOS 18.4 бета-версии.

Основные направления решения проблемы:

  • Использование поддержки интерпретируемого кода в режиме отладки Flutter
  • Поддержка dart:ffi при использовании интерпретируемого кода
  • Устранение возможных проблем с производительностью, связанных с интерпретируемым кодом

Анализ текущих подходов к решению проблемы:

  • Добавление поддержки конфигурации simarm64 (симулятор для ARM64), чтобы Dart VM мог интерпретировать созданный код
  • Возобновление выполнения Dart-байткода
  • Гибридный режим выполнения, где приложение компилируется через AOT/JIT с подписями, а только модифицированный код интерпретируется

На самом деле третий пункт «гибридный режим выполнения» довольно интересен, так как это аналогично методу горячей замены в рамках проекта Shorebird для iOS: приложение выполняется полностью через AOT, а только патчи горячей замены интерпретируются, то есть Shorebird внедрил свой собственный интерпретатор в Dart VM. Поэтому можно заметить, что основатель Flutter Эрик активно взаимодействует с командой Dart/Flutter:

Действительно, Эрик очень беспокоится относительно этой части работы Dart VM, поскольку Shorebird как сторонний проект сталкивается со значительной работой по интеграции этих изменений. Если же решение команды Dart будет максимально совместимо с Shorebird, это будет лучшим вариантом:

На данный момент хорошей новостью является то, что если ваше реальное устройство не обновлено до iOS 18.4 бета-версии, то никаких проблем возникнуть не должно. Вероятнее всего, команда Flutter/Dart сможет исправить эту проблему до официального выпуска iOS 18.4, так как уже определены пути решения.

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

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/CarGuo-GSYFlutterBook.git
git@api.gitlife.ru:oschina-mirror/CarGuo-GSYFlutterBook.git
oschina-mirror
CarGuo-GSYFlutterBook
CarGuo-GSYFlutterBook
master