A crash occurred when opening multiple pages containing PlatformView using EngineGroup.
Crash information is as follows:
[VERBOSE-3:shared_thread_merger.cc(59)] Check failed: lease_term_ref > 0. lease_term should always be positive when merged, lease_term=0
2023-10-20 14:44:03.206019+0800 Runner[44679:2472818]
[VERBOSE-2:profiler_metrics_ios.mm(203)] Error retrieving thread information: (os/kern) invalid argument
Steps to reproduce
1.Start an engine using EngineGroup and open a page containing a PlatformView, then remove the PlatformView from the page.
2.Use the same EngineGroup to create a new engine to render a new page containing a PlatformView, which will trigger a crash.
PlatformView should display properly when using EngineGroup.
Actual behavior
A crash occurred.
Environment
[!] Flutter (Channel [user-branch], 3.13.8-0.0.pre.4, on macOS 13.3.1 22E772610a darwin-arm64, locale zh-Hans-CN)
! Flutter version 3.13.8-0.0.pre.4 on channel [user-branch] at
Currently on an unknown channel. Run flutter channel to switch to an official channel.
If that doesn't fix the issue, reinstall Flutter by following instructions at https://flutter.dev/docs/get-started/install.
! Upstream repository is not a standard remote.
Set environment variable "FLUTTER_GIT_URL" to dismiss this error.
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.1)
[✓] IntelliJ IDEA Ultimate Edition (version 2020.2.4)
[✓] IntelliJ IDEA Community Edition (version 2021.3.3)
[✓] VS Code (version 1.82.2)
[✓] Connected device (4 available)
[✓] Network resources
platform: iOS
Additional details
Cause analysis:
After the page removes the PlatformView, SharedThreadMerger will perform an unmerge when the lease count for the corresponding engine decreases to 0. However, after the unmerge, the raster_thread_merger for the engine is not removed from the lease map. When opening the second page, since the page contains a PlatformView, it will trigger a merge again. This causes the first engine to also check if the lease has expired when drawing. Since the raster_thread_merger of the main engine was not removed during the previous unmerge, a situation with a lease count of 0 occurs. Thus, the error check below was triggered:
bool SharedThreadMerger::DecrementLease(RasterThreadMergerId caller) {
std::scoped_lock lock(mutex_);
auto entry = lease_term_by_caller_.find(caller);
bool exist = entry != lease_term_by_caller_.end();
if (exist) {
std::atomic_size_t& lease_term_ref = entry->second;
FML_CHECK(lease_term_ref > 0)
<< "lease_term should always be positive when merged, lease_term="
<< lease_term_ref;
lease_term_ref--;
} else {
FML_LOG(WARNING) << "The caller does not exist when calling "
"DecrementLease(), ignored. This may happens after "
"caller is erased in UnMergeNowIfLastOne(). caller="
<< caller;
}
if (IsAllLeaseTermsZeroUnSafe()) {
// Unmerge now because lease_term_ decreased to zero.
UnMergeNowUnSafe();
return true;
}
return false;
}
Suggested modifications:
In DecrementLease, check if the lease count has been reduced to 0 for a caller. If so, remove the caller from lease_term_bycaller. However, it's unclear whether this change might have any side effects.
Problem description
A crash occurred when opening multiple pages containing PlatformView using EngineGroup. Crash information is as follows:
Steps to reproduce
1.Start an engine using EngineGroup and open a page containing a PlatformView, then remove the PlatformView from the page. 2.Use the same EngineGroup to create a new engine to render a new page containing a PlatformView, which will trigger a crash.
https://github.com/google/flutter.widgets/assets/42142356/9fd02489-4307-4133-bdb8-b5e7887f6c19
Expected behavior
PlatformView should display properly when using EngineGroup.
Actual behavior
A crash occurred.
Environment
[!] Flutter (Channel [user-branch], 3.13.8-0.0.pre.4, on macOS 13.3.1 22E772610a darwin-arm64, locale zh-Hans-CN) ! Flutter version 3.13.8-0.0.pre.4 on channel [user-branch] at Currently on an unknown channel. Run
flutter channel
to switch to an official channel. If that doesn't fix the issue, reinstall Flutter by following instructions at https://flutter.dev/docs/get-started/install. ! Upstream repository is not a standard remote. Set environment variable "FLUTTER_GIT_URL" to dismiss this error. [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3) [✓] Xcode - develop for iOS and macOS (Xcode 14.3) [✓] Chrome - develop for the web [✓] Android Studio (version 2022.1) [✓] IntelliJ IDEA Ultimate Edition (version 2020.2.4) [✓] IntelliJ IDEA Community Edition (version 2021.3.3) [✓] VS Code (version 1.82.2) [✓] Connected device (4 available) [✓] Network resourcesplatform: iOS
Additional details
Cause analysis: After the page removes the PlatformView, SharedThreadMerger will perform an unmerge when the lease count for the corresponding engine decreases to 0. However, after the unmerge, the raster_thread_merger for the engine is not removed from the lease map. When opening the second page, since the page contains a PlatformView, it will trigger a merge again. This causes the first engine to also check if the lease has expired when drawing. Since the raster_thread_merger of the main engine was not removed during the previous unmerge, a situation with a lease count of 0 occurs. Thus, the error check below was triggered:
Suggested modifications: In DecrementLease, check if the lease count has been reduced to 0 for a caller. If so, remove the caller from lease_term_bycaller. However, it's unclear whether this change might have any side effects.