Skip to content

flutter run attaches LLDB to app extension process instead of main app on iOS 17+ #183263

Description

@Silfalion

Steps to reproduce

  1. Create a Flutter app with an iOS app extension (e.g., WidgetKit widget extension)
  2. Run flutter run -v --flavor <flavor> on a physical iOS 17+ device
  3. Observe that LLDB sometimes attaches to the extension process instead of the main app

Expected results

LLDB should always attach to the main app process (e.g., MainApp[DEV]).

Actual results

LLDB intermittently attaches to the extension process (e.g., somethingExtension), causing flutter run to fail or behave incorrectly.

This is a race condition. When iOS launches both the main app and its extension, both processes appear in devicectl device info processes. Flutter picks the first match, which may be the extension.

Root cause

In packages/flutter_tools/lib/src/ios/core_devices.dart (around line 122-130), the process discovery uses .contains(installationURL) to match the launched process:

final IOSCoreDeviceRunningProcess? launchedProcess = processes
    .where(
      (IOSCoreDeviceRunningProcess process) =>
          process.executable != null && process.executable!.contains(installationURL),
    )
    .firstOrNull;

The installationURL is the app bundle path, e.g.:

/private/var/containers/Bundle/Application/<UUID>/MainApp[DEV].app/

Both the main app and extension processes match this path because the extension lives inside the app bundle:

PID 4211  .../MainApp[DEV].app/PlugIns/somethingExtension.appex/...
PID 4212  .../MainApp[DEV].app/MainApp[DEV]

.firstOrNull picks whichever appears first in the process list. When the extension process has a lower PID (spawned first by iOS), it wins — and LLDB attaches to the wrong process.

Proposed fix

Filter out app extension processes (.appex) from the process matching:

final IOSCoreDeviceRunningProcess? launchedProcess = processes
    .where(
      (IOSCoreDeviceRunningProcess process) =>
          process.executable != null &&
          process.executable!.contains(installationURL) &&
          !process.executable!.contains('.appex'),
    )
    .firstOrNull;

Environment

  • Flutter 3.41.4 (stable)
  • Xcode 16.3
  • iOS 18.x physical device (wireless debugging)
  • macOS 15.3 (arm64)
  • App has WidgetKit extension embedded via "Embed Foundation Extensions" build phase

Code sample

Code sample

This bug requires a WidgetKit extension embedded in the app bundle, which cannot be set up via flutter create. The reproduction project was generated with Very Good CLI, then a WidgetKit widget extension was added through Xcode.

See the repository linked below for the full project and detailed root cause analysis:
https://github.com/Silfalion/small_test

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.41.4, on macOS 26.3 25D125 darwin-arm64, locale en-DZ)
[!] Android toolchain - develop for Android devices (Android SDK version 36.1.0-rc1)
    ✗ Flutter requires Android SDK 36 and the Android BuildTools 28.0.3
      To update the Android SDK visit https://flutter.dev/to/macos-android-setup for detailed instructions.
[✓] Xcode - develop for iOS and macOS (Xcode 26.3)
[✓] Chrome - develop for the web
[✓] Connected device (3 available)
[✓] Network resources

! Doctor found issues in 1 category.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listhas reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-iosiOS applications specificallyteam-iosOwned by iOS platform teamtoolAffects the "flutter" command-line tool. See also t: labels.triaged-iosTriaged by iOS platform team

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions