Repository navigation
[CP-stable] Detach LLDB and print stack trace on process stop (#188576) - #190550
Conversation
This PR automatically detaches LLDB from the process and prints the stack trace if the app process stops. This prevents the app from hanging on crash. Fixes flutter#186366. - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [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 Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot 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. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [AI contribution guidelines]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines [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
|
This pull request was opened from and to a release candidate branch. This should only be done as part of the official Flutter release process. If you are attempting to make a regular contribution to the Flutter project, please close this PR and follow the instructions at Tree Hygiene for detailed instructions on contributing to Flutter. Reviewers: Use caution before merging pull requests to release branches. Ensure the proper procedure has been followed. |
There was a problem hiding this comment.
Code Review
This pull request updates iOS device launching to detect early app termination using a log interceptor, replacing the previous 10-minute CI timeout. It also configures LLDB stop hooks to print thread backtraces and detach on crashes to prevent debugger hangs. The review feedback identifies three key issues: a potential memory leak from not removing the app_terminated log interceptor, a possible StateError when calling completeError on an already completed _logCompleter during LLDB exit, and a potential infinite hang in _setupStopHooks if _lldbProcess is null.
| if (deviceLogReader is SharedIOSDeviceLogReader) { | ||
| deviceLogReader.removeLogInterceptorByIdentifier(kJITCrashLogInterceptorIdentifier); | ||
| } |
There was a problem hiding this comment.
The app_terminated log interceptor is added to deviceLogReader (which is a SharedIOSDeviceLogReader and can be long-lived), but it is never removed when the app launch sequence completes or fails. This will lead to a memory leak (as the interceptor closures the completer and other context) and performance degradation over multiple runs because the list of active interceptors on the shared log reader will grow indefinitely. Please ensure it is removed along with kJITCrashLogInterceptorIdentifier.
if (deviceLogReader is SharedIOSDeviceLogReader) {
deviceLogReader.removeLogInterceptorByIdentifier(kJITCrashLogInterceptorIdentifier);
deviceLogReader.removeLogInterceptorByIdentifier('app_terminated');
}| if (_logCompleter != null) { | ||
| _logCompleter!.completeError(_LLDBError('LLDB process exited')); | ||
| } |
There was a problem hiding this comment.
If _logCompleter has already been completed (e.g., when the expected log was matched), calling completeError on it during exit() will throw a StateError: Future already completed. To prevent this crash, check if the completer is already completed before calling completeError.
if (_logCompleter != null && !_logCompleter!.isCompleted) {
_logCompleter!.completeError(_LLDBError('LLDB process exited'));
}| Future<void> _setupStopHooks() async { | ||
| final Future<String> futureLog = _startWaitingForLog( | ||
| _stopHookAddedPattern, | ||
| ).then((value) => value, onError: _handleAsyncError); | ||
| await _lldbProcess?.stdinWriteln('target stop-hook add -o "thread backtrace all" -o "detach"'); | ||
| await futureLog; | ||
| } |
There was a problem hiding this comment.
If _lldbProcess is null, the null-aware call _lldbProcess?.stdinWriteln(...) will be a no-op, but the subsequent await futureLog will hang indefinitely because the expected log pattern will never be printed. Guarding the method with a null check on _lldbProcess prevents this potential hang.
Future<void> _setupStopHooks() async {
final lldbProcess = _lldbProcess;
if (lldbProcess == null) {
return;
}
final Future<String> futureLog = _startWaitingForLog(
_stopHookAddedPattern,
).then((value) => value, onError: _handleAsyncError);
await lldbProcess.stdinWriteln('target stop-hook add -o "thread backtrace all" -o "detach"');
await futureLog;
}|
Since this isn't an automated cherry-pick, @okorohelijah could you review the CP since you reviewed the original pull request? |
LongCatIsLooong
left a comment
There was a problem hiding this comment.
The only merge conflict was in the test files.
a9014e7
into
flutter:flutter-3.44-candidate.0
#190184 <- omitted in the changelog, not an end user facing change. #190550 If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot 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.
…r#188576) (flutter#190550) Impacted Users (Approximately who will hit this issue, ex. all Flutter devs, Windows developers, all end-customers, apps using X framework feature). iOS developers debugging on iOS 17+ devices. 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 shipping a production app? ex. the app crashes on launch). [flutter/186366](flutter#186366) When debugging an iOS app, if the app crashes, the Flutter CLI will hang. Tests that crash will hang. Workaround (Is there a workaround for this issue?) Manually kill the Flutter CLI Risk (What is the risk level of this cherry-pick?) Low Test Coverage (Are you confident that your fix is well-tested by automated tests?) Yes Validation Steps (What are the steps to validate that this fix works?) Debug an iOS app and force it to crash. Flutter CLI should stop and print stack trace
flutter#190184 <- omitted in the changelog, not an end user facing change. flutter#190550 If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot 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.
Impacted Users (Approximately who will hit this issue, ex. all Flutter devs, Windows developers, all end-customers, apps using X framework feature).
iOS developers debugging on iOS 17+ devices.
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 shipping a production app? ex. the app crashes on launch).
flutter/186366 When debugging an iOS app, if the app crashes, the Flutter CLI will hang. Tests that crash will hang.
Workaround (Is there a workaround for this issue?)
Manually kill the Flutter CLI
Risk (What is the risk level of this cherry-pick?)
Low
Test Coverage (Are you confident that your fix is well-tested by automated tests?)
Yes
Validation Steps (What are the steps to validate that this fix works?)
Debug an iOS app and force it to crash. Flutter CLI should stop and print stack trace