Repository navigation
[stable] [flutter_tools] Fix crash in symbolize command on stream error - #191605
Conversation
…er#191273) Ensure the stream subscription in `DwarfSymbolizationService.decodeWithUnits` sets `cancelOnError: true`. When an error occurs in the stream, this automatically cancels the subscription and prevents `onDone` from being invoked after `onError`, avoiding a `StateError` from completing the completer a second time. Fixes flutter#191205 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [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 between commits]. - [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] All existing and new tests are passing.
|
@bkonyi please fill out the PR description above, afterwards the release team will review this request. |
|
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 the DwarfSymbolizationService to cancel stream subscriptions on error and catch all Object types instead of just Exception during symbolization. It also adds a regression test to verify stream error handling. Feedback suggests utilizing a finally block to ensure output.close() is always executed, preventing potential resource leaks when stream errors occur.
| try { | ||
| await onDone.future; | ||
| await output.close(); | ||
| } on Exception catch (err) { | ||
| } on Object catch (err) { | ||
| throwToolExit('Failed to symbolize stack trace:\n $err'); | ||
| } |
There was a problem hiding this comment.
If onDone.future throws an error, await output.close() is skipped, which can lead to resource leaks (e.g., unclosed file descriptors or sockets) when stream errors occur. Consider using a finally block to ensure that output.close() is always called, regardless of whether the symbolization succeeded or failed.
try {
await onDone.future;
} on Object catch (err) {
throwToolExit('Failed to symbolize stack trace:\n $err');
} finally {
await output.close();
}bb693d7
into
flutter:flutter-3.47-candidate.0
Issue Link:
#191205
Impact Description:
When running
flutter symbolizeon an obfuscated stack trace, if the underlying process output stream completes or encounters an error while aCompleteris already resolved,Symbolizercrashes unexpectedly withStateError: Bad state: Future already completed. This causes the CLI to exit abruptly during stack deobfuscation and crash report generation.Changelog Description:
[flutter/191205] Prevent
StateError: Bad state: Future already completedinSymbolizerby checkingcompleter.isCompletedwhen handling stream errors and completions during stack symbolization.Workaround:
Manually deobfuscate stack traces using standalone
addr2line/atos/llvm-symbolizertools.Risk:
Test Coverage:
Validation Steps:
flutter build apk --obfuscate --split-debug-info=....flutter symbolize --debug-info=<symbols-file> -i <stacktrace.txt>.flutter symbolizeprocesses the stack trace without throwingStateError: Bad state: Future already completed.