Treat package:stack_trace async-gap marker as asynchronous suspension#185791
Conversation
There was a problem hiding this comment.
Code Review
This pull request modifies StackFrame.fromStackTraceLine to treat the package:stack_trace asynchronous gap marker as an asynchronous suspension, removing a previous assertion that caused crashes. Test cases were updated to reflect this change and ensure debugPrintStack handles these markers correctly. Review feedback suggests correcting a typo in a code comment and removing an unused async keyword in the test suite.
ebf63a9 to
1e7aa80
Compare
justinmc
left a comment
There was a problem hiding this comment.
This is a little scary given that a change this deep is required to fix a problem with debugPrintStack. How do we know that this won't break anything else? I assume that assert was there for a reason. I'm not super familiar with StackFrame though.
|
Thanks, that's a fair concern. I dug into why the assert was there and added focused test-only follow-ups ( My read is that the original assert was intended to flag a I also checked the That line is semantically the same kind of boundary as the VM's existing async marker: Before this PR, debug mode asserted on that exact line. In profile/release, where the assert is absent, the parser would already drop the line as unparsed, so the practical behavior was inconsistent: debug crashed, non-debug silently lost the async boundary. This PR narrows that to treating only the exact sentinel as The follow-up tests now cover:
Verification I ran:
|
justinmc
left a comment
There was a problem hiding this comment.
LGTM 👍
I'm convinced that this is the best approach for Flutter to take for the sake of our developers. It feels a bit weird hard coding in the "asynchronous gap" string from package:stack_trace, but I guess we were doing that before this PR anyway. This change will likely save many app users from experiencing a crash.
For the record, the original PR that added this assert is #60478.
`StackFrame.fromStackTraceLine` used to assert when it encountered the literal `===== asynchronous gap ===========================` line that `package:stack_trace` emits between chained Dart-VM stacks. The diagnostic told callers to wire up `FlutterError.demangleStackTrace`, but utilities like `debugPrintStack` ran the parser unconditionally on caller-supplied stacks (e.g. the one carried by `ParallelWaitError` or by stacks that pass through the test runner) and crashed there before the demangle hook could help. That marker is the `package:stack_trace` equivalent of the VM's `<asynchronous suspension>` line, so the parser now folds it into `StackFrame.asynchronousSuspension` rather than asserting. Stacks that carry the marker round-trip cleanly through `debugPrintStack` and `FlutterError.defaultStackFilter` without losing the boundary. Fixes flutter#179018
46e6d69 to
087c682
Compare
flutter/flutter@cab057d...1ac2e82 2026-07-21 [email protected] Add BaseWindowController.isDestroyed flag (flutter/flutter#189061) 2026-07-21 [email protected] Roll Dart SDK from 666e1e2133b7 to 3b2f5ad7718d (1 revision) (flutter/flutter#189745) 2026-07-21 [email protected] Roll Skia from 3c52d80c960d to 569534e9fa59 (5 revisions) (flutter/flutter#189766) 2026-07-21 [email protected] Roll Skia from 11426cf7aaa1 to 3c52d80c960d (2 revisions) (flutter/flutter#189758) 2026-07-21 [email protected] Roll pub packages (flutter/flutter#189760) 2026-07-21 [email protected] [iOS] Inject DisplayLinkManager into FlutterKeyboardInsetManager (flutter/flutter#189751) 2026-07-21 [email protected] Treat package:stack_trace async-gap marker as asynchronous suspension (flutter/flutter#185791) 2026-07-21 [email protected] [iOS] Inject DisplayLinkManager into VsyncWaiterIOS (flutter/flutter#189749) 2026-07-20 [email protected] Use String builder in `InputConnectionAdaptorTest.java` (flutter/flutter#189281) 2026-07-20 [email protected] Fix non-independant tests in draggable_test.dart (flutter/flutter#186898) 2026-07-20 [email protected] Stop using ReLinker to load libflutter.so on Android 17 (API 37+) (flutter/flutter#189146) 2026-07-20 [email protected] [et] Refactor gn post-processing, fix minor clang[++] regex match bug (flutter/flutter#189685) 2026-07-20 [email protected] Take plugin_test_darwin out of bringup (flutter/flutter#189594) 2026-07-20 [email protected] Roll pub packages (flutter/flutter#189596) 2026-07-20 [email protected] widgets layer re-export ScrollCacheExtent (flutter/flutter#189483) 2026-07-20 [email protected] Roll Skia from 47143b6fa402 to 11426cf7aaa1 (7 revisions) (flutter/flutter#189740) 2026-07-20 [email protected] Sync CHANGELOG.md from stable (flutter/flutter#189735) 2026-07-20 [email protected] [Impeller] In the AHBTextureSourceVK destructor, do not call Vulkan APIs if the VkDevice has been destroyed (flutter/flutter#189666) 2026-07-20 [email protected] Add AutofillHints.emailOTPCode for Android AUTOFILL_HINT_EMAIL_OTP (flutter/flutter#188123) 2026-07-20 [email protected] Add a github workflow to remove flutteractionsbot branches after the PRs are merged or closed. (flutter/flutter#189668) 2026-07-20 [email protected] Roll ANGLE to cc08479fbcc1 (flutter/flutter#189595) 2026-07-20 [email protected] Roll Fuchsia Linux SDK from NL8xtzr8cxr5E8r8E... to GswhlPRO-D1qSNclx... (flutter/flutter#189715) 2026-07-20 [email protected] Roll Skia from ba90f98535de to 47143b6fa402 (4 revisions) (flutter/flutter#189721) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…r#12256) flutter/flutter@cab057d...1ac2e82 2026-07-21 [email protected] Add BaseWindowController.isDestroyed flag (flutter/flutter#189061) 2026-07-21 [email protected] Roll Dart SDK from 666e1e2133b7 to 3b2f5ad7718d (1 revision) (flutter/flutter#189745) 2026-07-21 [email protected] Roll Skia from 3c52d80c960d to 569534e9fa59 (5 revisions) (flutter/flutter#189766) 2026-07-21 [email protected] Roll Skia from 11426cf7aaa1 to 3c52d80c960d (2 revisions) (flutter/flutter#189758) 2026-07-21 [email protected] Roll pub packages (flutter/flutter#189760) 2026-07-21 [email protected] [iOS] Inject DisplayLinkManager into FlutterKeyboardInsetManager (flutter/flutter#189751) 2026-07-21 [email protected] Treat package:stack_trace async-gap marker as asynchronous suspension (flutter/flutter#185791) 2026-07-21 [email protected] [iOS] Inject DisplayLinkManager into VsyncWaiterIOS (flutter/flutter#189749) 2026-07-20 [email protected] Use String builder in `InputConnectionAdaptorTest.java` (flutter/flutter#189281) 2026-07-20 [email protected] Fix non-independant tests in draggable_test.dart (flutter/flutter#186898) 2026-07-20 [email protected] Stop using ReLinker to load libflutter.so on Android 17 (API 37+) (flutter/flutter#189146) 2026-07-20 [email protected] [et] Refactor gn post-processing, fix minor clang[++] regex match bug (flutter/flutter#189685) 2026-07-20 [email protected] Take plugin_test_darwin out of bringup (flutter/flutter#189594) 2026-07-20 [email protected] Roll pub packages (flutter/flutter#189596) 2026-07-20 [email protected] widgets layer re-export ScrollCacheExtent (flutter/flutter#189483) 2026-07-20 [email protected] Roll Skia from 47143b6fa402 to 11426cf7aaa1 (7 revisions) (flutter/flutter#189740) 2026-07-20 [email protected] Sync CHANGELOG.md from stable (flutter/flutter#189735) 2026-07-20 [email protected] [Impeller] In the AHBTextureSourceVK destructor, do not call Vulkan APIs if the VkDevice has been destroyed (flutter/flutter#189666) 2026-07-20 [email protected] Add AutofillHints.emailOTPCode for Android AUTOFILL_HINT_EMAIL_OTP (flutter/flutter#188123) 2026-07-20 [email protected] Add a github workflow to remove flutteractionsbot branches after the PRs are merged or closed. (flutter/flutter#189668) 2026-07-20 [email protected] Roll ANGLE to cc08479fbcc1 (flutter/flutter#189595) 2026-07-20 [email protected] Roll Fuchsia Linux SDK from NL8xtzr8cxr5E8r8E... to GswhlPRO-D1qSNclx... (flutter/flutter#189715) 2026-07-20 [email protected] Roll Skia from ba90f98535de to 47143b6fa402 (4 revisions) (flutter/flutter#189721) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Summary
StackFrame.fromStackTraceLineasserted whenever it encountered the literalline that
package:stack_traceemits between chained Dart-VM stacks. The assertion's diagnostic told callers to wire upFlutterError.demangleStackTrace, but utilities likedebugPrintStack(and, transitively,FlutterError.defaultStackFilter) run the parser unconditionally on caller-supplied stacks. Anything that carries that marker — e.g. the stack insideParallelWaitError, or any stack that passes through the test runner before reaching the framework — crashes before the demangle hook can intervene. The user-facing repro in the linked issue shows this with(future1, future2).wait'sonErrorhandler.That marker is the
package:stack_traceequivalent of the VM's<asynchronous suspension>line. This change folds it intoStackFrame.asynchronousSuspensionso the boundary is preserved and parsers downstream offromStackTraceLine(the default stack filter,debugPrintStack, etc.) round-trip cleanly without losing the async hop.Changes
packages/flutter/lib/src/foundation/stack_frame.dart— recognize the package:stack_trace async-gap line asasynchronousSuspension; remove the assertion that previously rejected it.packages/flutter/test/foundation/stack_frame_test.dart— replace the legacy "throws assertion" test with a parse-correctness test, add a unit test for the marker, and add an end-to-end regression test that pipes a stack carrying the marker throughdebugPrintStack(the exact code path from the linked issue).Test plan
flutter test packages/flutter/test/foundation/stack_frame_test.dart— 13/13 pass.flutter test packages/flutter/test/foundation/— 222/222 pass.(f1(), f2()).waitwithdebugPrintStackinonError) and verified it now passes.flutter analyzeon the changed files — clean.Fixes #179018