dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.22k stars 1.57k forks source link

Compiler crashes when Future is created and awaited later (during debug) #53637

Closed bernardolansing closed 1 year ago

bernardolansing commented 1 year ago

I am developing an Android app with Flutter. This afternoon, I started to receive this error:

Compiler crash > Unhandled exception: > invalid input > #0 parseDefinitionTypes (package:front_end/src/api_prototype/expression_compilation_tools.dart:110:43) > #1 createDefinitionsWithTypes (package:front_end/src/api_prototype/expression_compilation_tools.dart:32:7) > #2 IncrementalCompiler.compileExpression (package:vm/incremental_compiler.dart:219:50) > #3 FrontendCompiler.compileExpression (package:frontend_server/frontend_server.dart:981:45) > #4 listenAndCompile. (package:frontend_server/frontend_server.dart:1452:26) > #5 _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10) > #6 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11) > #7 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7) > #8 _SinkTransformerStreamSubscription._add (dart:async/stream_transformers.dart:63:11) > #9 _EventSinkWrapper.add (dart:async/stream_transformers.dart:13:11) > #10 _StringAdapterSink.add (dart:convert/string_conversion.dart:228:11) > #11 _LineSplitterSink._addLines (dart:convert/line_splitter.dart:164:13) > #12 _LineSplitterSink.addSlice (dart:convert/line_splitter.dart:131:7) > #13 StringConversionSink.add (dart:convert/string_conversion.dart:39:5) > #14 _SinkTransformerStreamSubscription._handleData (dart:async/stream_transformers.dart:111:24) > #15 _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10) > #16 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11) > #17 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7) > #18 _SinkTransformerStreamSubscription._add (dart:async/stream_transformers.dart:63:11) > #19 _EventSinkWrapper.add (dart:async/stream_transformers.dart:13:11) > #20 _StringAdapterSink.add (dart:convert/string_conversion.dart:228:11) > #21 _StringAdapterSink.addSlice (dart:convert/string_conversion.dart:233:7) > #22 _Utf8ConversionSink.addSlice (dart:convert/string_conversion.dart:307:20) > #23 _Utf8ConversionSink.add (dart:convert/string_conversion.dart:300:5) > #24 _ConverterStreamEventSink.add (dart:convert/chunked_conversion.dart:69:18) > #25 _SinkTransformerStreamSubscription._handleData (dart:async/stream_transformers.dart:111:24) > #26 _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10) > #27 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11) > #28 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7) > #29 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:784:19) > #30 _StreamController._add (dart:async/stream_controller.dart:658:7) > #31 _StreamController.add (dart:async/stream_controller.dart:606:5) > #32 _Socket._onData (dart:io-patch/socket_patch.dart:2447:41) > #33 _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10) > #34 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11) > #35 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7) > #36 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:784:19) > #37 _StreamController._add (dart:async/stream_controller.dart:658:7) > #38 _StreamController.add (dart:async/stream_controller.dart:606:5) > #39 new _RawSocket. (dart:io-patch/socket_patch.dart:1936:33) > #40 _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1379:14) > #41 _microtaskLoop (dart:async/schedule_microtask.dart:40:21) > #42 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5) > #43 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:123:13) > #44 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:190:5) > the Dart compiler exited unexpectedly. > the Dart compiler exited unexpectedly.

After some debugging, I found out that this crash only happened when I had the debugger on and I created a Future that was only awaited in a later moment of the code. Check this:

Future<void> update() async {
    // userData is a Map that comes from the database
    final anymalsFuture = _updateOwnedAnymals(userData);

    completeName = userData['completeName'];
    cpf = userData['cpf'];
    privacyPolicyAgreement = userData['privacyPolicyAgreement'] != null
        ? PrivacyPolicyAgreement.fromMap(userData['privacyPolicyAgreement'])
        : null;
    if (userData['messagingRegistrationTokens'] != null) {
      messagingRegistrationTokens = List<Map>.from(userData['messagingRegistrationTokens'])
          .map(MessagingRegistrationTokenEntry.fromEntry)
          .toList(growable: false);
    }
    else { messagingRegistrationTokens = []; }
    _updateOrders(userData);
    _updateOwnedCredits(userData);
    _updatePurchases(userData);

    await anymalsFuture;
    _lastUpdated = DateTime.now().millisecondsSinceEpoch;
  }

If the debugger pauses between the creation of the anymalsFuture and its latter await, the compiler will crash. For example, if I put a breakpoint in the line completeName = userData['completeName'];, the crash will happen somewhat 5 seconds after the pause, or when I mouse hover any variable. I am using Android Studio and when I mouse hover any name, the IDE will try to search that name value (if it is a variable) or its documentation (if it is a class/function). Either way, Dart crashes instantly.

If I just awaited that future from the beggining, everything runs normally. I tried to reproduce that with a simple Future.delayed, but no crash occured. This is the _updateOwnedAnymals:

Future<void> _updateOwnedAnymals(Map<String, dynamic> userData) async {
    final ownedSerialKeys = List<String>.from(userData['ownedAnymals']);

    // remove anymals that are not owned by user anymore
    ownedAnymals.removeWhere((anymal) => ! ownedSerialKeys.contains(anymal.serialKey));

    // list of serial keys of anymals that need to be created. Does not include anymals that were created already
    final anymalsToCreate = ownedSerialKeys
        .where((serial) => ! ownedAnymals.any((anymal) => anymal.serialKey == serial));
    final createdAnymals = await Future.wait(anymalsToCreate.map(Anymal.createFromSerial));
    ownedAnymals.addAll(createdAnymals);
}

And the Anymal.createFromSerial is below. Actually, this is supposed to be a constructor. I'm aware that this code is awful; by the time I wrote it I was very newbie. Even so, I don't believe it is so bad that it would crash the compiler.

static Future<Anymal> createFromSerial(String serial) async {
    final anymal = Anymal(serial);

    final infoSnapshot = await FirebaseFirestore.instance.collection('anymals').doc(serial).get();
    final info = infoSnapshot.data();
    if (info == null) { throw 'Could not fetch information on any+ of serial $serial'; }
    anymal._name = info['name'];
    anymal._firstConnected = info['firstConnected'];
    anymal.species = AnymalSpecies.values.byName(info['species']);
    anymal._ownedAddonsCodes = (info['addons'] as List<Object?>).map((addon) => addon?.toString() ?? '').toList();

    anymal.network = NetworkModule(anymal._dbHandler);
    anymal.alarmManager = AlarmModule(anymal._dbHandler);
    anymal.addons = AddonModule(anymal._dbHandler);
    anymal.eyeSettings = EyeSettings(anymal._dbHandler);
    anymal.playback = Playback(anymal._dbHandler);
    anymal.parrotMode = ParrotModeModule(anymal._dbHandler);

    return anymal;
  }

Unfortunately, this is a comercial software so I won't be able to share much more than this. I hope this report could be useful.

dart info #### General info - Dart 3.1.3 (stable) (Tue Sep 26 14:25:13 2023 +0000) on "linux_x64" - on linux / Linux 5.15.0-84-generic #93~20.04.1-Ubuntu SMP Wed Sep 6 16:15:40 UTC 2023 - locale is en_US.UTF-8 #### Project info - sdk constraint: '>=2.19.6 <3.0.0' - dependencies: animations, app_settings, async, cloud_firestore, collection, firebase_auth, firebase_core, firebase_database, firebase_messaging, flutter, flutter_colorpicker, flutter_webrtc, http, qr_code_scanner, skeleton_loader, webview_flutter - dev_dependencies: flutter_lints, flutter_test #### Process info | Memory | CPU | Elapsed time | Command line | | -----: | ---: | -----------: | ------------------------------------------------------------------------------------------ | | 33 MB | 0.0% | 01:09:01 | dart devtools --no-launch-browser | | 32 MB | 0.0% | 01:06:30 | dart devtools --no-launch-browser | | 34 MB | 0.0% | 21:45 | dart devtools --no-launch-browser | | 34 MB | 0.0% | 19:20 | dart devtools --no-launch-browser | | 33 MB | 0.0% | 14:15 | dart devtools --no-launch-browser | | 33 MB | 0.0% | 11:04 | dart devtools --no-launch-browser | | 38 MB | 0.3% | 01:39 | dart devtools --no-launch-browser | | 583 MB | 1.0% | 45:43 | dart language-server --client-id=Android-Studio --client-version=AI-221.6008.13 --protocol=analyzer | | 75 MB | 0.4% | 46:48 | flutter_tools.snapshot daemon |
npavelko commented 1 year ago

I have the same problem

angelru commented 1 year ago

The same issue:

Unhandled exception:
invalid input
#0      parseDefinitionTypes (package:front_end/src/api_prototype/expression_compilation_tools.dart:110:43)
#1      createDefinitionsWithTypes (package:front_end/src/api_prototype/expression_compilation_tools.dart:32:7)
#2      IncrementalCompiler.compileExpression (package:vm/incremental_compiler.dart:219:50)
#3      FrontendCompiler.compileExpression (package:frontend_server/frontend_server.dart:981:45)

#4      listenAndCompile.<anonymous closure> (package:frontend_server/frontend_server.dart:1452:26)
#5      _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)
#6      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
#7      _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#8      _SinkTransformerStreamSubscription._add (dart:async/stream_transformers.dart:63:11)
#9      _EventSinkWrapper.add (dart:async/stream_transformers.dart:13:11)
#10     _StringAdapterSink.add (dart:convert/string_conversion.dart:228:11)

#11     _LineSplitterSink._addLines (dart:convert/line_splitter.dart:164:13)
#12     _LineSplitterSink.addSlice (dart:convert/line_splitter.dart:131:7)
Avataromvatar commented 1 year ago

The same trouble, but the error is a little different. It always works when you hover over a variable at a breakpoint (in the Future) to look at it. I also tried to repeat the problem in a simple test, but it didn't work out. This started happening quite recently after the update.

Unhandled exception: FormatException: Invalid radix-10 number (at character 1) null ^

0 int._handleFormatError (dart:core-patch/integers_patch.dart:126:5)

1 int._parseRadix (dart:core-patch/integers_patch.dart:137:16)

2 int._parse (dart:core-patch/integers_patch.dart:98:12)

3 int.parse (dart:core-patch/integers_patch.dart:60:12)

4 parseDefinitionTypes (package:front_end/src/api_prototype/expression_compilation_tools.dart:113:36)

5 createDefinitionsWithTypes (package:front_end/src/api_prototype/expression_compilation_tools.dart:32:7)

6 IncrementalCompiler.compileExpression (package:vm/incremental_compiler.dart:219:50)

7 FrontendCompiler.compileExpression (package:frontend_server/frontend_server.dart:981:45)

8 listenAndCompile. (package:frontend_server/frontend_server.dart:1452:26)

9 _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)

10 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)

11 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)

12 _SinkTransformerStreamSubscription._add (dart:async/stream_transformers.dart:63:11)

13 _EventSinkWrapper.add (dart:async/stream_transformers.dart:13:11)

14 _StringAdapterSink.add (dart:convert/string_conversion.dart:228:11)

15 _LineSplitterSink._addLines (dart:convert/line_splitter.dart:164:13)

16 _LineSplitterSink.addSlice (dart:convert/line_splitter.dart:131:7)

17 StringConversionSink.add (dart:convert/string_conversion.dart:39:5)

18 _SinkTransformerStreamSubscription._handleData (dart:async/stream_transformers.dart:111:24)

19 _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)

20 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)

21 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)

22 _SinkTransformerStreamSubscription._add (dart:async/stream_transformers.dart:63:11)

23 _EventSinkWrapper.add (dart:async/stream_transformers.dart:13:11)

24 _StringAdapterSink.add (dart:convert/string_conversion.dart:228:11)

25 _StringAdapterSink.addSlice (dart:convert/string_conversion.dart:233:7)

26 _Utf8ConversionSink.addSlice (dart:convert/string_conversion.dart:307:20)

27 _Utf8ConversionSink.add (dart:convert/string_conversion.dart:300:5)

28 _ConverterStreamEventSink.add (dart:convert/chunked_conversion.dart:69:18)

29 _SinkTransformerStreamSubscription._handleData (dart:async/stream_transformers.dart:111:24)

30 _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)

31 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)

32 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)

33 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:784:19)

34 _StreamController._add (dart:async/stream_controller.dart:658:7)

35 _StreamController.add (dart:async/stream_controller.dart:606:5)

36 _Socket._onData (dart:io-patch/socket_patch.dart:2447:41)

37 _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)

38 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)

39 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)

40 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:784:19)

41 _StreamController._add (dart:async/stream_controller.dart:658:7)

42 _StreamController.add (dart:async/stream_controller.dart:606:5)

43 new _RawSocket. (dart:io-patch/socket_patch.dart:1936:33)

44 _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1379:14)

45 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)

46 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)

47 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:123:13)

48 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:190:5)

the Dart compiler exited unexpectedly. the Dart compiler exited unexpectedly.

Flutter (Channel stable, 3.13.6, on macOS 14.0 23A344 darwin-arm64, locale en-RU) • Flutter version 3.13.6 on channel stable at * • Upstream repository https://github.com/flutter/flutter.git • Framework revision ead455963c (7 days ago), 2023-09-26 18:28:17 -0700 • Engine revision a794cf2681 • Dart version 3.1.3 • DevTools version 2.25.0

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) • Android SDK *** • Platform android-33, build-tools 33.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301) • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.0) • Xcode at *** • Build 15A240d • CocoaPods version 1.11.3

[✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.1) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301)

[✓] VS Code (version 1.82.3) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.74.0

JCKodel commented 1 year ago

Maybe same here? https://github.com/Dart-Code/Dart-Code/issues/4776

But my code doesn't have any futures at that point (but indeed had some Future<void> stacked on a List to be awaited later with a await Future.wait(list)).

At that specific point in the video, there were no async code executed (at least on my code base).

johnniwinther commented 1 year ago

Likely related to #53382

johnniwinther commented 1 year ago

cc @derekxu16

derekxu16 commented 1 year ago

If I run the following Flutter app on an Android emulator using Flutter 3.13.7, set a breakpoint to pause at print(m); and then hover over m, the compiler crashes. If I do the same thing using Flutter from the main channel, the compiler does not crash. So, I think this is a problem you already fixed, @johnniwinther.

import 'dart:collection' show HashMap;

Future<void> _update(Map<String, dynamic> m) async {}

Future<void> main() async {
  final m = HashMap<String, dynamic>();
  final f = _update(m);
  print(m);
  await f;
}
johnniwinther commented 1 year ago

Thanks @derekxu16