Repository: flutter
Issue: Hot reload crashes when launching two bundles and one of them extends another class
Labels: c: crash,tool,dependency: dart,t: hot reload,a: desktop,has reproducible steps,P3,c: fatal crash,found in release: 3.7,found in release: 3.8,team-macos,triaged-macos

Given a flutter desktop app which launches two flutter bundles, if the source code of one of the flutter bundles has a class which extends another class, then the application crashes after reload.

#### Steps to reproduce
The steps below use macOS and latest flutter stable (Flutter 3.7.3).

1. Set up a working directory to host the flutter projects and macos project.
```
mkdir reload_crash
cd reload_crash
mkdir out
mkdir out/bundles
flutter create fish
flutter create dog
```

2. In fish project, create lib/foo.dart with contents:
```
abstract class Foo {
  void bar();
}
```

3. In fish project, create lib/fish.dart with contents:
```
import 'foo.dart'; 

class Fish extends Foo { 
  String sound() => "ppp";
  @override
  void bar() {
    // TODO: implement bar
  }  
}
```

4. In fish project, add import to lib/main.dart:
```
import 'package:flutter/material.dart';

import 'fish.dart'; // add this line

void main() {
  runApp(const MyApp());
}
...
```

5. The project dog doesn't require any changes.

6. Build flutter bundle for fish project. From a shell inside fish directory, run:
```shell
flutter build bundle -t lib/main.dart --debug --target-platform darwin --asset-dir ../out/bundles/fish/flutter_assets
```

7. Build flutter bundle for dog project. From a shell inside dog directory, run:
```shell
flutter build bundle -t lib/main.dart --debug --target-platform darwin --asset-dir ../out/bundles/dog/flutter_assets
```

8. Create new Xcode project with these details:
    - Platform: macOS
    - Application: App
    - Product Name: pets_macos
    - Interface: Storyboard
    - Language: Swift
    - Create it inside reload_crash directory

9. Once xcode project is created select pets_macos on the left, then Targets > pets_macos > Signing & Capabilities. Then delete App Sandbox and Hardened Runtime.

10. In the xcode project, go to Targets > pets_macos> General > Framework, Libraries and Embedded Content. Add FlutterMacOS.framework from `/path/to/flutter-sdk/bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework`

11. Replace contents of AppDelegate.swift with  code that will launch both bundles in their own windows:

```swift
import Cocoa
import FlutterMacOS

@main
class AppDelegate: NSObject, NSApplicationDelegate {

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        _launch_1()
        _launch_2()
    }

    func applicationWillTerminate(_ aNotification: Notification) {
    }

    func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
        return true
    }

    func _launch_1() {
        let bundleUrl = URL(fileURLWithPath: "/PATH/TO/reload_crash/out/bundles/fish")
        let bundle = Bundle.init(path: bundleUrl.path)
        let project = FlutterDartProject.init(precompiledDartBundle: bundle)
        let controller = FlutterViewController.init(project: project)
        let window = NSWindow()
        window.contentViewController = controller
        let windowController = NSWindowController()
        windowController.contentViewController = window.contentViewController
        
        window.setContentSize(NSSize(width: 300, height: 400))
        window.setFrameOrigin(NSPoint(x: 100.0, y: 100.0))
        window.title = "fish"
        
        windowController.window = window
        windowController.showWindow(self)
    }
    
    func _launch_2() {
        let bundleUrl = URL(fileURLWithPath: "/PATH/TO/reload_crash/out/bundles/dog")
        let bundle = Bundle.init(path: bundleUrl.path)
        let project = FlutterDartProject.init(precompiledDartBundle: bundle)
        let controller = FlutterViewController.init(project: project)
        let window = NSWindow()
        window.contentViewController = controller
        let windowController = NSWindowController()
        windowController.contentViewController = window.contentViewController
        
        window.setContentSize(NSSize(width: 300, height: 400))
        window.setFrameOrigin(NSPoint(x: 120.0, y: 120.0))
        window.title = "dog"
        
        windowController.window = window
        windowController.showWindow(self)
    }
}


```

Replace `/PATH/TO` above with your local path to the reload_crash directory.

12. Build and run the xcode project, note the console message:
```
flutter: The Dart VM service is listening on http://127.0.0.1:PORT/HASH/
```

13. Copy the URL above and from a terminal run `flutter attach` inside the fish directory:
```
cd reload_crash/fish
flutter attach --debug -d macOS -t lib/main.dart --debug-uri http://127.0.0.1:PORT/HASH/
```

14. Once it fully attaches, go to fish/lib/fish.dart and edit the source code. For example, change the string below to some other string value:
```
String sound() => "ppp"; // change "ppp" to "aaa"
```

15. Then hit "r" on the terminal running flutter attach. Notice how the application crashes with a message similar to:
```
../../third_party/dart/runtime/vm/object.cc: 4717: error: Unable to use class Library:'package:fish/foo.dart' Class: Foo which is not loaded yet.
version=2.19.2 (stable) (Tue Feb 7 18:37:17 2023 +0000) on "macos_x64"
pid=87498, thread=83715, isolate_group=main(0x7fefc580aa00), isolate=(nil)(0x0)
os=macos, arch=x64, comp=no, sim=no
isolate_instructions=108360a60, vm_instructions=108360a60
  pc 0x00000001084c8655 fp 0x0000700003d31240 dart::Profiler::DumpStackTrace(void*)+0x85
  pc 0x0000000108360cd4 fp 0x0000700003d31320 dart::Assert::Fail(char const*, ...) const+0x84
  pc 0x00000001084402da fp 0x0000700003d31350 dart::Class::EnsureDeclarationLoaded() const+0x6a
  pc 0x00000001083a197e fp 0x0000700003d31400 dart::ClassFinalizer::FinalizeTypesInClass(dart::Class const&)+0x3e
  pc 0x00000001083a1a8c fp 0x0000700003d314b0 dart::ClassFinalizer::FinalizeTypesInClass(dart::Class const&)+0x14c
  pc 0x00000001083a1848 fp 0x0000700003d31620 dart::ClassFinalizer::ProcessPendingClasses()+0x188
  pc 0x00000001083ff463 fp 0x0000700003d31780 dart::kernel::KernelLoader::LoadProgram(bool)+0x1b3
  pc 0x00000001083fea07 fp 0x0000700003d31cd0 dart::kernel::KernelLoader::LoadEntireProgram(dart::kernel::Program*, bool)+0x77
  pc 0x00000001083e7c24 fp 0x0000700003d31de0 dart::ProgramReloadContext::ReloadPhase2LoadKernel(dart::kernel::Program*, dart::String const&)+0xc4
  pc 0x00000001083e57b9 fp 0x0000700003d320c0 dart::IsolateGroupReloadContext::Reload(bool, char const*, char const*, unsigned char const*, long)+0xa09
  pc 0x00000001083dc3b9 fp 0x0000700003d32150 dart::IsolateGroup::ReloadSources(dart::JSONStream*, bool, char const*, char const*, bool)+0x1a9
  pc 0x0000000108534880 fp 0x0000700003d32190 dart::ReloadSources(dart::Thread*, dart::JSONStream*)+0x170
  pc 0x000000010852879c fp 0x0000700003d32790 dart::Service::InvokeMethod(dart::Isolate*, dart::Array const&, bool)+0x34c
  pc 0x0000000108528de3 fp 0x0000700003d327c0 dart::Service::HandleIsolateMessage(dart::Isolate*, dart::Array const&)+0x23
  pc 0x00000001083d9eac fp 0x0000700003d32d60 dart::IsolateMessageHandler::HandleMessage(std::_LIBCPP_ABI_NAMESPACE::unique_ptr<dart::Message, std::_LIBCPP_ABI_NAMESPACE::default_delete<dart::Message>>)+0x27c
  pc 0x0000000108409000 fp 0x0000700003d32df0 dart::MessageHandler::HandleMessages(dart::MonitorLocker*, bool, bool)+0x140
  pc 0x00000001084091ce fp 0x0000700003d32e30 dart::MessageHandler::HandleNextMessage()+0x4e
  pc 0x00000001087ff825 fp 0x0000700003d32ec0 Dart_HandleMessage+0x125
  pc 0x00000001080e46da fp 0x0000700003d32f10 tonic::DartMessageHandler::OnHandleMessage(tonic::DartState*)+0xca
  pc 0x00000001080e4b64 fp 0x0000700003d32f40 std::_LIBCPP_ABI_NAMESPACE::__function::__func<tonic::DartMessageHandler::OnMessage(tonic::DartState*)::$_0, std::_LIBCPP_ABI_NAMESPACE::allocator<tonic::DartMessageHandler::OnMessage(tonic::DartState*)::$_0>, void ()>::operator()()+0x44
  pc 0x000000010830a4b9 fp 0x0000700003d32f60 std::_LIBCPP_ABI_NAMESPACE::__function::__func<flutter::DartIsolate::SetMessageHandlingTaskRunner(fml::RefPtr<fml::TaskRunner> const&)::$_3::operator()(std::_LIBCPP_ABI_NAMESPACE::function<void ()>) const::'lambda'(), std::_LIBCPP_ABI_NAMESPACE::allocator<flutter::DartIsolate::SetMessageHandlingTaskRunner(fml::RefPtr<fml::TaskRunner> const&)::$_3::operator()(std::_LIBCPP_ABI_NAMESPACE::function<void ()>) const::'lambda'()>, void ()>::operator()()+0x39
  pc 0x0000000107a1493e fp 0x0000700003d33010 fml::MessageLoopImpl::FlushTasks(fml::FlushType)+0x10e
  pc 0x0000000107a1ceec fp 0x0000700003d33040 fml::MessageLoopDarwin::OnTimerFire(__CFRunLoopTimer*, fml::MessageLoopDarwin*)+0x2c
  pc 0x00007ff818a96f69 fp 0x0000700003d33050 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__+0x14
  pc 0x00007ff818a96a58 fp 0x0000700003d34100 __CFRunLoopDoTimer+0x39b
  pc 0x00007ff818a965c8 fp 0x0000700003d34150 __CFRunLoopDoTimers+0x133
  pc 0x00007ff818a7ccd6 fp 0x0000700003d34e80 __CFRunLoopRun+0x7da
  pc 0x00007ff818a7be3c fp 0x0000700003d34f20 CFRunLoopRunSpecific+0x232
  pc 0x0000000107a1d15d fp 0x0000700003d34f60 fml::MessageLoopDarwin::Run()+0x8d
  pc 0x0000000107a14755 fp 0x0000700003d34f80 fml::MessageLoopImpl::DoRun()+0x25
  pc 0x0000000107a1b560 fp 0x0000700003d34fb0 void* std::_LIBCPP_ABI_NAMESPACE::__thread_proxy[abi:v15000]<std::_LIBCPP_ABI_NAMESPACE::tuple<std::_LIBCPP_ABI_NAMESPACE::unique_ptr<std::_LIBCPP_ABI_NAMESPACE::__thread_struct, std::_LIBCPP_ABI_NAMESPACE::default_delete<std::_LIBCPP_ABI_NAMESPACE::__thread_struct>>, fml::Thread::Thread(std::_LIBCPP_ABI_NAMESPACE::function<void (fml::Thread::ThreadConfig const&)> const&, fml::Thread::ThreadConfig const&)::$_0>>(void*)+0xb0
  pc 0x00007ff8189b74e1 fp 0x0000700003d34fd0 _pthread_start+0x7d
  pc 0x00007ff8189b2f6b fp 0x0000700003d34ff0 thread_start+0xf
-- End of DumpStackTrace
Abort trap: 6
```

#### Other notes
For the crash to occur, the project that `flutter attach` runs on needs to have libraries with these relationships:
- there is a dart file which declares an abstract class (see foo.dart)
- there is another dart file which extends the abstract class (see fish.dart)
- the main.dart imports this last dart file

The crash also occurs when importing libraries from other popular packages, like mockito and json_serializable, which generate code that extend other base classes.

This crash is also reproducible on Windows and Linux.