- Notifications
You must be signed in to change notification settings - Fork29.7k
Use LLDB as the default debugging method for iOS 17+ and Xcode 26+#173443
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Code Review
This pull request introduces LLDB as the default debugging method for iOS 17+ devices when using Xcode 16+. It adds a new feature flag,lldbDebugging, which is enabled by default. The implementation includes a fallback to the existing Xcode debugging method if LLDB fails. Extensive analytics have been added to track the different iOS deployment methods. The changes also include significant refactoring of the iOS device launching logic for better modularity and the addition of a new devicelab test to cover the Xcode debugging path. Overall, this is a solid improvement to the iOS debugging experience.
Uh oh!
There was an error while loading.Please reload this page.
| if (debuggingEnabled&&!isCoreDevice) ...<String>[ | ||
| '--enable-checked-mode', | ||
| '--verify-entry-points', | ||
| ], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This was specific to debugging through Xcode, so I moved it here:
flutter/packages/flutter_tools/lib/src/ios/devices.dart
Lines 1085 to 1090 inb02a1f4
| // Core Devices (iOS 17 devices) are debugged through Xcode so don't | |
| // include these flags, which are used to check if the app was launched | |
| // via Flutter CLI and `ios-deploy`. | |
| finalList<String> filteredLaunchArguments= launchArguments | |
| .where((String arg)=> arg!='--enable-checked-mode'&& arg!='--verify-entry-points') | |
| .toList(); |
| ); | ||
| finalbool launchSuccess= launchResult!=null&& launchResult.outcome=='success'; | ||
| return launchSuccess; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
The diff here sucks due to spacing.
The changes made here:
- Updated returns to return a
booland aIOSDeploymentMethod - If LLDB feature flag is enabled and Xcode 26+, use LLDB debugging
- Updated timeout warning message for Xcode debugging
- Filter out some arguments when Xcode debugging
Here's the function before:
flutter/packages/flutter_tools/lib/src/ios/devices.dart
Lines 894 to 1003 in796c62b
| Future<bool>_startAppOnCoreDevice({ | |
| requiredDebuggingOptions debuggingOptions, | |
| requiredIOSApp package, | |
| requiredList<String> launchArguments, | |
| requiredString? mainPath, | |
| requiredShutdownHooks shutdownHooks, | |
| @visibleForTestingDuration? discoveryTimeout, | |
| })async { | |
| if (!debuggingOptions.debuggingEnabled) { | |
| // Release mode | |
| // Install app to device | |
| finalbool installSuccess=await _coreDeviceControl.installApp( | |
| deviceId: id, | |
| bundlePath: package.deviceBundlePath, | |
| ); | |
| if (!installSuccess) { | |
| return installSuccess; | |
| } | |
| // Launch app to device | |
| finalbool launchSuccess=await _coreDeviceControl.launchApp( | |
| deviceId: id, | |
| bundleId: package.id, | |
| launchArguments: launchArguments, | |
| ); | |
| return launchSuccess; | |
| }else { | |
| _logger.printStatus( | |
| 'You may be prompted to give access to control Xcode. Flutter uses Xcode ' | |
| 'to run your app. If access is not allowed, you can change this through ' | |
| 'your Settings > Privacy & Security > Automation.', | |
| ); | |
| final launchTimeout= isWirelesslyConnected?45:30; | |
| final timer=Timer(discoveryTimeout??Duration(seconds: launchTimeout), () { | |
| _logger.printError( | |
| 'Xcode is taking longer than expected to start debugging the app. ' | |
| 'Ensure the project is opened in Xcode.', | |
| ); | |
| }); | |
| XcodeDebugProject debugProject; | |
| finalFlutterProject flutterProject=FlutterProject.current(); | |
| if (packageisPrebuiltIOSApp) { | |
| debugProject=await _xcodeDebug.createXcodeProjectWithCustomBundle( | |
| package.deviceBundlePath, | |
| templateRenderer: globals.templateRenderer, | |
| verboseLogging: _logger.isVerbose, | |
| ); | |
| }elseif (packageisBuildableIOSApp) { | |
| // Before installing/launching/debugging with Xcode, update the build | |
| // settings to use a custom configuration build directory so Xcode | |
| // knows where to find the app bundle to launch. | |
| finalDirectory bundle= _fileSystem.directory(package.deviceBundlePath); | |
| awaitupdateGeneratedXcodeProperties( | |
| project: flutterProject, | |
| buildInfo: debuggingOptions.buildInfo, | |
| targetOverride: mainPath, | |
| configurationBuildDir: bundle.parent.absolute.path, | |
| ); | |
| finalIosProject project= package.project; | |
| finalXcodeProjectInfo? projectInfo=await project.projectInfo(); | |
| if (projectInfo==null) { | |
| globals.printError('Xcode project not found.'); | |
| returnfalse; | |
| } | |
| if (project.xcodeWorkspace==null) { | |
| globals.printError('Unable to get Xcode workspace.'); | |
| returnfalse; | |
| } | |
| finalString? scheme= projectInfo.schemeFor(debuggingOptions.buildInfo); | |
| if (scheme==null) { | |
| projectInfo.reportFlavorNotFoundAndExit(); | |
| } | |
| _xcodeDebug.ensureXcodeDebuggerLaunchAction(project.xcodeProjectSchemeFile(scheme: scheme)); | |
| debugProject=XcodeDebugProject( | |
| scheme: scheme, | |
| xcodeProject: project.xcodeProject, | |
| xcodeWorkspace: project.xcodeWorkspace!, | |
| hostAppProjectName: project.hostAppProjectName, | |
| expectedConfigurationBuildDir: bundle.parent.absolute.path, | |
| verboseLogging: _logger.isVerbose, | |
| ); | |
| }else { | |
| // This should not happen. Currently, only PrebuiltIOSApp and | |
| // BuildableIOSApp extend from IOSApp. | |
| _logger.printError('IOSApp type ${package.runtimeType} is not recognized.'); | |
| returnfalse; | |
| } | |
| finalbool debugSuccess=await _xcodeDebug.debugApp( | |
| project: debugProject, | |
| deviceId: id, | |
| launchArguments: launchArguments, | |
| ); | |
| timer.cancel(); | |
| // Kill Xcode on shutdown when running from CI | |
| if (debuggingOptions.usingCISystem) { | |
| shutdownHooks.addShutdownHook(()=> _xcodeDebug.exit(force:true)); | |
| } | |
| return debugSuccess; | |
| } | |
| } |
and after:
flutter/packages/flutter_tools/lib/src/ios/devices.dart
Lines 955 to 1106 in261be4b
| Future<(bool,IOSDeploymentMethod)>_startAppOnCoreDevice({ | |
| requiredDebuggingOptions debuggingOptions, | |
| requiredIOSApp package, | |
| requiredList<String> launchArguments, | |
| requiredString? mainPath, | |
| requiredShutdownHooks shutdownHooks, | |
| @visibleForTestingDuration? discoveryTimeout, | |
| })async { | |
| if (!debuggingOptions.debuggingEnabled) { | |
| // Release mode | |
| // Install app to device | |
| finalbool installSuccess=await _coreDeviceControl.installApp( | |
| deviceId: id, | |
| bundlePath: package.deviceBundlePath, | |
| ); | |
| if (!installSuccess) { | |
| return (installSuccess,IOSDeploymentMethod.coreDeviceWithoutDebugger); | |
| } | |
| // Launch app to device | |
| finalIOSCoreDeviceLaunchResult? launchResult=await _coreDeviceControl.launchApp( | |
| deviceId: id, | |
| bundleId: package.id, | |
| launchArguments: launchArguments, | |
| ); | |
| finalbool launchSuccess= launchResult!=null&& launchResult.outcome=='success'; | |
| return (launchSuccess,IOSDeploymentMethod.coreDeviceWithoutDebugger); | |
| } | |
| IOSDeploymentMethod? deploymentMethod; | |
| // Xcode 16 introduced a way to start and attach to a debugserver through LLDB. | |
| // However, it doesn't work reliably until Xcode 26. | |
| // Use LLDB if Xcode version is greater than 26 and the feature is enabled. | |
| finalVersion? xcodeVersion= globals.xcode?.currentVersion; | |
| finalbool lldbFeatureEnabled= featureFlags.isLLDBDebuggingEnabled; | |
| if (xcodeVersion!=null&& xcodeVersion.major>=26&& lldbFeatureEnabled) { | |
| finalbool launchSuccess=await _coreDeviceLauncher.launchAppWithLLDBDebugger( | |
| deviceId: id, | |
| bundlePath: package.deviceBundlePath, | |
| bundleId: package.id, | |
| launchArguments: launchArguments, | |
| ); | |
| // If it succeeds to launch with LLDB, return, otherwise continue on to | |
| // try launching with Xcode. | |
| if (launchSuccess) { | |
| return (launchSuccess,IOSDeploymentMethod.coreDeviceWithLLDB); | |
| }else { | |
| deploymentMethod=IOSDeploymentMethod.coreDeviceWithXcodeFallback; | |
| _analytics.send( | |
| Event.appleUsageEvent( | |
| workflow:'ios-physical-deployment', | |
| parameter:IOSDeploymentMethod.coreDeviceWithLLDB.name, | |
| result:'launch failed', | |
| ), | |
| ); | |
| } | |
| } | |
| deploymentMethod??=IOSDeploymentMethod.coreDeviceWithXcode; | |
| // If LLDB is not available or fails, fallback to using Xcode. | |
| _logger.printStatus( | |
| 'You may be prompted to give access to control Xcode. Flutter uses Xcode ' | |
| 'to run your app. If access is not allowed, you can change this through ' | |
| 'your Settings > Privacy & Security > Automation.', | |
| ); | |
| final launchTimeout= isWirelesslyConnected?45:30; | |
| final timer=Timer(discoveryTimeout??Duration(seconds: launchTimeout), () { | |
| _logger.printError( | |
| 'Xcode is taking longer than expected to start debugging the app. ' | |
| 'If the issue persists, try closing Xcode and re-running your Flutter command.', | |
| ); | |
| }); | |
| XcodeDebugProject debugProject; | |
| finalFlutterProject flutterProject=FlutterProject.current(); | |
| if (packageisPrebuiltIOSApp) { | |
| debugProject=await _xcodeDebug.createXcodeProjectWithCustomBundle( | |
| package.deviceBundlePath, | |
| templateRenderer: globals.templateRenderer, | |
| verboseLogging: _logger.isVerbose, | |
| ); | |
| }elseif (packageisBuildableIOSApp) { | |
| // Before installing/launching/debugging with Xcode, update the build | |
| // settings to use a custom configuration build directory so Xcode | |
| // knows where to find the app bundle to launch. | |
| finalDirectory bundle= _fileSystem.directory(package.deviceBundlePath); | |
| awaitupdateGeneratedXcodeProperties( | |
| project: flutterProject, | |
| buildInfo: debuggingOptions.buildInfo, | |
| targetOverride: mainPath, | |
| configurationBuildDir: bundle.parent.absolute.path, | |
| ); | |
| finalIosProject project= package.project; | |
| finalXcodeProjectInfo? projectInfo=await project.projectInfo(); | |
| if (projectInfo==null) { | |
| globals.printError('Xcode project not found.'); | |
| return (false, deploymentMethod); | |
| } | |
| if (project.xcodeWorkspace==null) { | |
| globals.printError('Unable to get Xcode workspace.'); | |
| return (false, deploymentMethod); | |
| } | |
| finalString? scheme= projectInfo.schemeFor(debuggingOptions.buildInfo); | |
| if (scheme==null) { | |
| projectInfo.reportFlavorNotFoundAndExit(); | |
| } | |
| _xcodeDebug.ensureXcodeDebuggerLaunchAction(project.xcodeProjectSchemeFile(scheme: scheme)); | |
| debugProject=XcodeDebugProject( | |
| scheme: scheme, | |
| xcodeProject: project.xcodeProject, | |
| xcodeWorkspace: project.xcodeWorkspace!, | |
| hostAppProjectName: project.hostAppProjectName, | |
| expectedConfigurationBuildDir: bundle.parent.absolute.path, | |
| verboseLogging: _logger.isVerbose, | |
| ); | |
| }else { | |
| // This should not happen. Currently, only PrebuiltIOSApp and | |
| // BuildableIOSApp extend from IOSApp. | |
| _logger.printError('IOSApp type ${package.runtimeType} is not recognized.'); | |
| return (false, deploymentMethod); | |
| } | |
| // Core Devices (iOS 17 devices) are debugged through Xcode so don't | |
| // include these flags, which are used to check if the app was launched | |
| // via Flutter CLI and `ios-deploy`. | |
| finalList<String> filteredLaunchArguments= launchArguments | |
| .where((String arg)=> arg!='--enable-checked-mode'&& arg!='--verify-entry-points') | |
| .toList(); | |
| finalbool debugSuccess=await _xcodeDebug.debugApp( | |
| project: debugProject, | |
| deviceId: id, | |
| launchArguments: filteredLaunchArguments, | |
| ); | |
| timer.cancel(); | |
| // Kill Xcode on shutdown when running from CI | |
| if (debuggingOptions.usingCISystem) { | |
| shutdownHooks.addShutdownHook(()=> _xcodeDebug.exit(force:true)); | |
| } | |
| return (debugSuccess, deploymentMethod); | |
| } |
bkonyi left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
LGTM!
| // try launching with Xcode. | ||
| if (launchSuccess) { | ||
| return (launchSuccess,IOSDeploymentMethod.coreDeviceWithLLDB); | ||
| }else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Ubernit: is thiselse necessary?
3821790Uh oh!
There was an error while loading.Please reload this page.
flutteractionsbot commentedAug 8, 2025
Failed to create CP due to merge conflicts. |
…lutter#173443)This PR introduces a new feature flag called `lldb-debugging`, which isturned on by default. When this feature is turned on, if deploying to aphysical iOS 17+ device with Xcode 26+, it will use a mixture of`devicectl` and `lldb` to install, launch, and debug the app.If LLDB fails, it will fallback to use Xcode automation. If LLDB timesout, it will warn the user they may want to disable it. If LLDB isdisabled, it will use Xcode automation.This PR also adds analytics to track what deployment method is used andif it's successful.Part 2 and 3 offlutter#173416.Fixesflutter#144218.Fixesflutter#133465.- [x] I read the [Contributor Guide] and followed the process outlinedthere for submitting PRs.- [x] I read the [Tree Hygiene] wiki page, which explains myresponsibilities.- [x] I read and followed the [Flutter Style Guide], including [Featureswe expect every widget to implement].- [x] I signed the [CLA].- [x] I listed at least one issue that this PR fixes in the descriptionabove.- [x] I updated/added relevant documentation (doc comments with `///`).- [x] I added new tests to check the change I am making, or this PR is[test-exempt].- [x] I followed the [breaking change policy] and added [Data DrivenFixes] where supported.- [x] All existing and new tests are passing.If you need help, consider asking for advice on the #hackers-new channelon [Discord].**Note**: The Flutter team is currently trialing the use of [Gemini CodeAssist forGitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).Comments from the `gemini-code-assist` bot should not be taken asauthoritative feedback from the Flutter team. If you find its commentsuseful you can update your code accordingly, but if you are unsure ordisagree with the feedback, please feel free to wait for a Flutter teammember's review for guidance on which automated comments should beaddressed.<!-- Links -->[Contributor Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview[Tree Hygiene]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md[test-exempt]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests[Flutter Style Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md[Features we expect every widget to implement]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement[CLA]:https://cla.developers.google.com/[flutter/tests]:https://github.com/flutter/tests[breaking change policy]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes[Discord]:https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md[Data Driven Fixes]:https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
flutter/flutter@92a6bfb...38217902025-08-08 15619084+vashworth@users.noreply.github.com Use LLDB as the default debugging method for iOS 17+ and Xcode 26+ (flutter/flutter#173443)2025-08-08 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from i4vsuEGyP8Xeb5tiy... to HclTm0V8hgSpfqmtG... (flutter/flutter#173462)2025-08-08 Wdestroier@gmail.com Support launching a HTTPS URL (flutter/flutter#164720)2025-08-08 engine-flutter-autoroll@skia.org Roll Dart SDK from c48772a79e1f to 4b7b565eb468 (1 revision) (flutter/flutter#173454)2025-08-08 engine-flutter-autoroll@skia.org Roll Dart SDK from ba58b96a80d7 to c48772a79e1f (3 revisions) (flutter/flutter#173451)2025-08-07 127918074+salemiranloye@users.noreply.github.com Web dev proxy (flutter/flutter#172175)2025-08-07 engine-flutter-autoroll@skia.org Roll ICU from b929596baebf to 1b2e3e8a421e (7 revisions) (flutter/flutter#173436)2025-08-07 jhy03261997@gmail.com [A11y] TextField prefix icon and suffix icon create a sibling node' (flutter/flutter#173312)2025-08-07 1063596+reidbaker@users.noreply.github.com [Android templates] Remove jetifier usage (flutter/flutter#173431)2025-08-07 fmalita@gmail.com Remove a couple of asserts from display_list_unittest (flutter/flutter#173381)2025-08-07 50643541+Mairramer@users.noreply.github.com Fix ScaffoldGeometry null scale with noAnimation FAB (flutter/flutter#172914)2025-08-07 15619084+vashworth@users.noreply.github.com Prepare for iOS debugging with lldb and devicectl (flutter/flutter#173417)2025-08-07 1598289+lukemmtt@users.noreply.github.com Fix `ReorderableList` proxy animation for partial drag-back (flutter/flutter#172380)2025-08-07 41930132+hellohuanlin@users.noreply.github.com [ios26]Do not report error for Info.plist key not found (flutter/flutter#172913)2025-08-07 aam@google.com Manual roll to 3.10.0-75.1.beta (flutter/flutter#173423)2025-08-07 micaelcid10@gmail.com [web] add --static-assets-url argument to build web (flutter/flutter#171638)2025-08-07 30870216+gaaclarke@users.noreply.github.com Adds deprecation for impeller opt out on android (flutter/flutter#173375)If this roll has caused a breakage, revert this CL and stop the rollerusing the controls here:https://autoroll.skia.org/r/flutter-packagesPlease CC stuartmorgan@google.com,tarrinneal@google.com on the revert to ensure that a humanis aware of the problem.To file a bug in Packages:https://github.com/flutter/flutter/issues/new/chooseTo report a problem with the AutoRoller itself, please file a bug:https://issues.skia.org/issues/new?component=1389291&template=1850622Documentation for the AutoRoller is here:https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…ode 26+ (#173443) (#173472)Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request.### Issue Link:Part 2 of#144218### Changelog Description:Explain this cherry pick in one line that is accessible to most Flutter developers. See [best practices](https://github.com/flutter/flutter/blob/main/docs/releases/Hotfix-Documentation-Best-Practices.md) for examplesImplementation of a future fix to allow Xcode 26 to `flutter run` twice in a row.### Impact Description:What is the impact (ex. visual jank on Samsung phones, app crash, cannot ship an iOS app)? Does it impact development (ex. flutter doctor crashes when Android Studio is installed), or the shipping production app (the app crashes on launch)Flutter developers running Xcode 26 can `flutter run` to a tethered iOS device once. However subsequent `flutter run` attempts are likely to fail. ### Workaround:Is there a workaround for this issue?Quitting and reopening Xcode.### Risk:What is the risk level of this cherry-pick?### Test Coverage:Are you confident that your fix is well-tested by automated tests?### Validation Steps:What are the steps to validate that this fix works?Create a flutter project and run `flutter run` twice in a row with a physical iOS 17+ device and Xcode 26.
The previous integration test only tested one workflow, so I re-designedthe test to be able to test both workflows and validate the correctcommands are being used.Follow up to#173443.## Pre-launch Checklist- [x] I read the [Contributor Guide] and followed the process outlinedthere for submitting PRs.- [x] I read the [Tree Hygiene] wiki page, which explains myresponsibilities.- [x] I read and followed the [Flutter Style Guide], including [Featureswe expect every widget to implement].- [x] I signed the [CLA].- [x] I listed at least one issue that this PR fixes in the descriptionabove.- [x] I updated/added relevant documentation (doc comments with `///`).- [x] I added new tests to check the change I am making, or this PR is[test-exempt].- [x] I followed the [breaking change policy] and added [Data DrivenFixes] where supported.- [x] All existing and new tests are passing.If you need help, consider asking for advice on the #hackers-new channelon [Discord].**Note**: The Flutter team is currently trialing the use of [Gemini CodeAssist forGitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).Comments from the `gemini-code-assist` bot should not be taken asauthoritative feedback from the Flutter team. If you find its commentsuseful you can update your code accordingly, but if you are unsure ordisagree with the feedback, please feel free to wait for a Flutter teammember's review for guidance on which automated comments should beaddressed.<!-- Links -->[Contributor Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview[Tree Hygiene]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md[test-exempt]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests[Flutter Style Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md[Features we expect every widget to implement]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement[CLA]:https://cla.developers.google.com/[flutter/tests]:https://github.com/flutter/tests[breaking change policy]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes[Discord]:https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md[Data Driven Fixes]:https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…lutter#173443)This PR introduces a new feature flag called `lldb-debugging`, which isturned on by default. When this feature is turned on, if deploying to aphysical iOS 17+ device with Xcode 26+, it will use a mixture of`devicectl` and `lldb` to install, launch, and debug the app.If LLDB fails, it will fallback to use Xcode automation. If LLDB timesout, it will warn the user they may want to disable it. If LLDB isdisabled, it will use Xcode automation.This PR also adds analytics to track what deployment method is used andif it's successful.Part 2 and 3 offlutter#173416.Fixesflutter#144218.Fixesflutter#133465.## Pre-launch Checklist- [x] I read the [Contributor Guide] and followed the process outlinedthere for submitting PRs.- [x] I read the [Tree Hygiene] wiki page, which explains myresponsibilities.- [x] I read and followed the [Flutter Style Guide], including [Featureswe expect every widget to implement].- [x] I signed the [CLA].- [x] I listed at least one issue that this PR fixes in the descriptionabove.- [x] I updated/added relevant documentation (doc comments with `///`).- [x] I added new tests to check the change I am making, or this PR is[test-exempt].- [x] I followed the [breaking change policy] and added [Data DrivenFixes] where supported.- [x] All existing and new tests are passing.If you need help, consider asking for advice on the #hackers-new channelon [Discord].**Note**: The Flutter team is currently trialing the use of [Gemini CodeAssist forGitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).Comments from the `gemini-code-assist` bot should not be taken asauthoritative feedback from the Flutter team. If you find its commentsuseful you can update your code accordingly, but if you are unsure ordisagree with the feedback, please feel free to wait for a Flutter teammember's review for guidance on which automated comments should beaddressed.<!-- Links -->[Contributor Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview[Tree Hygiene]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md[test-exempt]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests[Flutter Style Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md[Features we expect every widget to implement]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement[CLA]:https://cla.developers.google.com/[flutter/tests]:https://github.com/flutter/tests[breaking change policy]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes[Discord]:https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md[Data Driven Fixes]:https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…ode 26+ (#173443) (#173659)Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request.### Issue Link:Part 2 of#144218### Changelog Description:Explain this cherry pick in one line that is accessible to most Flutter developers. See [best practices](https://github.com/flutter/flutter/blob/main/docs/releases/Hotfix-Documentation-Best-Practices.md) for examplesUse LLDB and devicectl for deploying to physical iOS devices when using Xcode 26. This will allow Xcode 26 to `flutter run` twice in a row.### Impact Description:What is the impact (ex. visual jank on Samsung phones, app crash, cannot ship an iOS app)? Does it impact development (ex. flutter doctor crashes when Android Studio is installed), or the shipping production app (the app crashes on launch)Flutter developers running Xcode 26 can `flutter run` to a tethered iOS device once. However subsequent `flutter run` attempts are likely to fail. ### Workaround:Is there a workaround for this issue?Quitting and reopening Xcode.### Risk:What is the risk level of this cherry-pick?### Test Coverage:Are you confident that your fix is well-tested by automated tests?### Validation Steps:What are the steps to validate that this fix works?Create a flutter project and run `flutter run` twice in a row with a physical iOS 17+ device and Xcode 26.
…lutter#173443)This PR introduces a new feature flag called `lldb-debugging`, which isturned on by default. When this feature is turned on, if deploying to aphysical iOS 17+ device with Xcode 26+, it will use a mixture of`devicectl` and `lldb` to install, launch, and debug the app.If LLDB fails, it will fallback to use Xcode automation. If LLDB timesout, it will warn the user they may want to disable it. If LLDB isdisabled, it will use Xcode automation.This PR also adds analytics to track what deployment method is used andif it's successful.Part 2 and 3 offlutter#173416.Fixesflutter#144218.Fixesflutter#133465.## Pre-launch Checklist- [x] I read the [Contributor Guide] and followed the process outlinedthere for submitting PRs.- [x] I read the [Tree Hygiene] wiki page, which explains myresponsibilities.- [x] I read and followed the [Flutter Style Guide], including [Featureswe expect every widget to implement].- [x] I signed the [CLA].- [x] I listed at least one issue that this PR fixes in the descriptionabove.- [x] I updated/added relevant documentation (doc comments with `///`).- [x] I added new tests to check the change I am making, or this PR is[test-exempt].- [x] I followed the [breaking change policy] and added [Data DrivenFixes] where supported.- [x] All existing and new tests are passing.If you need help, consider asking for advice on the #hackers-new channelon [Discord].**Note**: The Flutter team is currently trialing the use of [Gemini CodeAssist forGitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).Comments from the `gemini-code-assist` bot should not be taken asauthoritative feedback from the Flutter team. If you find its commentsuseful you can update your code accordingly, but if you are unsure ordisagree with the feedback, please feel free to wait for a Flutter teammember's review for guidance on which automated comments should beaddressed.<!-- Links -->[Contributor Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview[Tree Hygiene]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md[test-exempt]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests[Flutter Style Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md[Features we expect every widget to implement]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement[CLA]:https://cla.developers.google.com/[flutter/tests]:https://github.com/flutter/tests[breaking change policy]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes[Discord]:https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md[Data Driven Fixes]:https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
The previous integration test only tested one workflow, so I re-designedthe test to be able to test both workflows and validate the correctcommands are being used.Follow up toflutter#173443.## Pre-launch Checklist- [x] I read the [Contributor Guide] and followed the process outlinedthere for submitting PRs.- [x] I read the [Tree Hygiene] wiki page, which explains myresponsibilities.- [x] I read and followed the [Flutter Style Guide], including [Featureswe expect every widget to implement].- [x] I signed the [CLA].- [x] I listed at least one issue that this PR fixes in the descriptionabove.- [x] I updated/added relevant documentation (doc comments with `///`).- [x] I added new tests to check the change I am making, or this PR is[test-exempt].- [x] I followed the [breaking change policy] and added [Data DrivenFixes] where supported.- [x] All existing and new tests are passing.If you need help, consider asking for advice on the #hackers-new channelon [Discord].**Note**: The Flutter team is currently trialing the use of [Gemini CodeAssist forGitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).Comments from the `gemini-code-assist` bot should not be taken asauthoritative feedback from the Flutter team. If you find its commentsuseful you can update your code accordingly, but if you are unsure ordisagree with the feedback, please feel free to wait for a Flutter teammember's review for guidance on which automated comments should beaddressed.<!-- Links -->[Contributor Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview[Tree Hygiene]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md[test-exempt]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests[Flutter Style Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md[Features we expect every widget to implement]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement[CLA]:https://cla.developers.google.com/[flutter/tests]:https://github.com/flutter/tests[breaking change policy]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes[Discord]:https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md[Data Driven Fixes]:https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…lutter#173443)This PR introduces a new feature flag called `lldb-debugging`, which isturned on by default. When this feature is turned on, if deploying to aphysical iOS 17+ device with Xcode 26+, it will use a mixture of`devicectl` and `lldb` to install, launch, and debug the app.If LLDB fails, it will fallback to use Xcode automation. If LLDB timesout, it will warn the user they may want to disable it. If LLDB isdisabled, it will use Xcode automation.This PR also adds analytics to track what deployment method is used andif it's successful.Part 2 and 3 offlutter#173416.Fixesflutter#144218.Fixesflutter#133465.## Pre-launch Checklist- [x] I read the [Contributor Guide] and followed the process outlinedthere for submitting PRs.- [x] I read the [Tree Hygiene] wiki page, which explains myresponsibilities.- [x] I read and followed the [Flutter Style Guide], including [Featureswe expect every widget to implement].- [x] I signed the [CLA].- [x] I listed at least one issue that this PR fixes in the descriptionabove.- [x] I updated/added relevant documentation (doc comments with `///`).- [x] I added new tests to check the change I am making, or this PR is[test-exempt].- [x] I followed the [breaking change policy] and added [Data DrivenFixes] where supported.- [x] All existing and new tests are passing.If you need help, consider asking for advice on the #hackers-new channelon [Discord].**Note**: The Flutter team is currently trialing the use of [Gemini CodeAssist forGitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).Comments from the `gemini-code-assist` bot should not be taken asauthoritative feedback from the Flutter team. If you find its commentsuseful you can update your code accordingly, but if you are unsure ordisagree with the feedback, please feel free to wait for a Flutter teammember's review for guidance on which automated comments should beaddressed.<!-- Links -->[Contributor Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview[Tree Hygiene]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md[test-exempt]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests[Flutter Style Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md[Features we expect every widget to implement]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement[CLA]:https://cla.developers.google.com/[flutter/tests]:https://github.com/flutter/tests[breaking change policy]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes[Discord]:https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md[Data Driven Fixes]:https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
The previous integration test only tested one workflow, so I re-designedthe test to be able to test both workflows and validate the correctcommands are being used.Follow up toflutter#173443.## Pre-launch Checklist- [x] I read the [Contributor Guide] and followed the process outlinedthere for submitting PRs.- [x] I read the [Tree Hygiene] wiki page, which explains myresponsibilities.- [x] I read and followed the [Flutter Style Guide], including [Featureswe expect every widget to implement].- [x] I signed the [CLA].- [x] I listed at least one issue that this PR fixes in the descriptionabove.- [x] I updated/added relevant documentation (doc comments with `///`).- [x] I added new tests to check the change I am making, or this PR is[test-exempt].- [x] I followed the [breaking change policy] and added [Data DrivenFixes] where supported.- [x] All existing and new tests are passing.If you need help, consider asking for advice on the #hackers-new channelon [Discord].**Note**: The Flutter team is currently trialing the use of [Gemini CodeAssist forGitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).Comments from the `gemini-code-assist` bot should not be taken asauthoritative feedback from the Flutter team. If you find its commentsuseful you can update your code accordingly, but if you are unsure ordisagree with the feedback, please feel free to wait for a Flutter teammember's review for guidance on which automated comments should beaddressed.<!-- Links -->[Contributor Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview[Tree Hygiene]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md[test-exempt]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests[Flutter Style Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md[Features we expect every widget to implement]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement[CLA]:https://cla.developers.google.com/[flutter/tests]:https://github.com/flutter/tests[breaking change policy]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes[Discord]:https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md[Data Driven Fixes]:https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…lutter#173443)This PR introduces a new feature flag called `lldb-debugging`, which isturned on by default. When this feature is turned on, if deploying to aphysical iOS 17+ device with Xcode 26+, it will use a mixture of`devicectl` and `lldb` to install, launch, and debug the app.If LLDB fails, it will fallback to use Xcode automation. If LLDB timesout, it will warn the user they may want to disable it. If LLDB isdisabled, it will use Xcode automation.This PR also adds analytics to track what deployment method is used andif it's successful.Part 2 and 3 offlutter#173416.Fixesflutter#144218.Fixesflutter#133465.## Pre-launch Checklist- [x] I read the [Contributor Guide] and followed the process outlinedthere for submitting PRs.- [x] I read the [Tree Hygiene] wiki page, which explains myresponsibilities.- [x] I read and followed the [Flutter Style Guide], including [Featureswe expect every widget to implement].- [x] I signed the [CLA].- [x] I listed at least one issue that this PR fixes in the descriptionabove.- [x] I updated/added relevant documentation (doc comments with `///`).- [x] I added new tests to check the change I am making, or this PR is[test-exempt].- [x] I followed the [breaking change policy] and added [Data DrivenFixes] where supported.- [x] All existing and new tests are passing.If you need help, consider asking for advice on the #hackers-new channelon [Discord].**Note**: The Flutter team is currently trialing the use of [Gemini CodeAssist forGitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).Comments from the `gemini-code-assist` bot should not be taken asauthoritative feedback from the Flutter team. If you find its commentsuseful you can update your code accordingly, but if you are unsure ordisagree with the feedback, please feel free to wait for a Flutter teammember's review for guidance on which automated comments should beaddressed.<!-- Links -->[Contributor Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview[Tree Hygiene]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md[test-exempt]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests[Flutter Style Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md[Features we expect every widget to implement]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement[CLA]:https://cla.developers.google.com/[flutter/tests]:https://github.com/flutter/tests[breaking change policy]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes[Discord]:https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md[Data Driven Fixes]:https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
The previous integration test only tested one workflow, so I re-designedthe test to be able to test both workflows and validate the correctcommands are being used.Follow up toflutter#173443.## Pre-launch Checklist- [x] I read the [Contributor Guide] and followed the process outlinedthere for submitting PRs.- [x] I read the [Tree Hygiene] wiki page, which explains myresponsibilities.- [x] I read and followed the [Flutter Style Guide], including [Featureswe expect every widget to implement].- [x] I signed the [CLA].- [x] I listed at least one issue that this PR fixes in the descriptionabove.- [x] I updated/added relevant documentation (doc comments with `///`).- [x] I added new tests to check the change I am making, or this PR is[test-exempt].- [x] I followed the [breaking change policy] and added [Data DrivenFixes] where supported.- [x] All existing and new tests are passing.If you need help, consider asking for advice on the #hackers-new channelon [Discord].**Note**: The Flutter team is currently trialing the use of [Gemini CodeAssist forGitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).Comments from the `gemini-code-assist` bot should not be taken asauthoritative feedback from the Flutter team. If you find its commentsuseful you can update your code accordingly, but if you are unsure ordisagree with the feedback, please feel free to wait for a Flutter teammember's review for guidance on which automated comments should beaddressed.<!-- Links -->[Contributor Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview[Tree Hygiene]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md[test-exempt]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests[Flutter Style Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md[Features we expect every widget to implement]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement[CLA]:https://cla.developers.google.com/[flutter/tests]:https://github.com/flutter/tests[breaking change policy]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes[Discord]:https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md[Data Driven Fixes]:https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…lutter#173443)This PR introduces a new feature flag called `lldb-debugging`, which isturned on by default. When this feature is turned on, if deploying to aphysical iOS 17+ device with Xcode 26+, it will use a mixture of`devicectl` and `lldb` to install, launch, and debug the app.If LLDB fails, it will fallback to use Xcode automation. If LLDB timesout, it will warn the user they may want to disable it. If LLDB isdisabled, it will use Xcode automation.This PR also adds analytics to track what deployment method is used andif it's successful.Part 2 and 3 offlutter#173416.Fixesflutter#144218.Fixesflutter#133465.## Pre-launch Checklist- [x] I read the [Contributor Guide] and followed the process outlinedthere for submitting PRs.- [x] I read the [Tree Hygiene] wiki page, which explains myresponsibilities.- [x] I read and followed the [Flutter Style Guide], including [Featureswe expect every widget to implement].- [x] I signed the [CLA].- [x] I listed at least one issue that this PR fixes in the descriptionabove.- [x] I updated/added relevant documentation (doc comments with `///`).- [x] I added new tests to check the change I am making, or this PR is[test-exempt].- [x] I followed the [breaking change policy] and added [Data DrivenFixes] where supported.- [x] All existing and new tests are passing.If you need help, consider asking for advice on the #hackers-new channelon [Discord].**Note**: The Flutter team is currently trialing the use of [Gemini CodeAssist forGitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).Comments from the `gemini-code-assist` bot should not be taken asauthoritative feedback from the Flutter team. If you find its commentsuseful you can update your code accordingly, but if you are unsure ordisagree with the feedback, please feel free to wait for a Flutter teammember's review for guidance on which automated comments should beaddressed.<!-- Links -->[Contributor Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview[Tree Hygiene]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md[test-exempt]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests[Flutter Style Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md[Features we expect every widget to implement]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement[CLA]:https://cla.developers.google.com/[flutter/tests]:https://github.com/flutter/tests[breaking change policy]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes[Discord]:https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md[Data Driven Fixes]:https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
The previous integration test only tested one workflow, so I re-designedthe test to be able to test both workflows and validate the correctcommands are being used.Follow up toflutter#173443.## Pre-launch Checklist- [x] I read the [Contributor Guide] and followed the process outlinedthere for submitting PRs.- [x] I read the [Tree Hygiene] wiki page, which explains myresponsibilities.- [x] I read and followed the [Flutter Style Guide], including [Featureswe expect every widget to implement].- [x] I signed the [CLA].- [x] I listed at least one issue that this PR fixes in the descriptionabove.- [x] I updated/added relevant documentation (doc comments with `///`).- [x] I added new tests to check the change I am making, or this PR is[test-exempt].- [x] I followed the [breaking change policy] and added [Data DrivenFixes] where supported.- [x] All existing and new tests are passing.If you need help, consider asking for advice on the #hackers-new channelon [Discord].**Note**: The Flutter team is currently trialing the use of [Gemini CodeAssist forGitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).Comments from the `gemini-code-assist` bot should not be taken asauthoritative feedback from the Flutter team. If you find its commentsuseful you can update your code accordingly, but if you are unsure ordisagree with the feedback, please feel free to wait for a Flutter teammember's review for guidance on which automated comments should beaddressed.<!-- Links -->[Contributor Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview[Tree Hygiene]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md[test-exempt]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests[Flutter Style Guide]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md[Features we expect every widget to implement]:https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement[CLA]:https://cla.developers.google.com/[flutter/tests]:https://github.com/flutter/tests[breaking change policy]:https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes[Discord]:https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md[Data Driven Fixes]:https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Uh oh!
There was an error while loading.Please reload this page.
This PR introduces a new feature flag called
lldb-debugging, which is turned on by default. When this feature is turned on, if deploying to a physical iOS 17+ device with Xcode 26+, it will use a mixture ofdevicectlandlldbto install, launch, and debug the app.If LLDB fails, it will fallback to use Xcode automation. If LLDB times out, it will warn the user they may want to disable it. If LLDB is disabled, it will use Xcode automation.
This PR also adds analytics to track what deployment method is used and if it's successful.
Part 2 and 3 of#173416.
Fixes#144218.Fixes#133465.
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel onDiscord.
Note: The Flutter team is currently trialing the use ofGemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.