mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Flip on leak detector and suppress or fix remaining leak traces (flutter/engine#28625)
Patch/suppress the remaining leaks and flip on the leak detector to start catching new leaks in CI.
This commit is contained in:
parent
f9c5181cba
commit
7b6fa075a7
@ -60,24 +60,23 @@ class SurfaceMock : public Surface {
|
||||
};
|
||||
|
||||
fml::RefPtr<fml::RasterThreadMerger> GetThreadMergerFromPlatformThread(
|
||||
bool merged = false) {
|
||||
fml::Thread* rasterizer_thread = nullptr) {
|
||||
// Assume the current thread is the platform thread.
|
||||
fml::MessageLoop::EnsureInitializedForCurrentThread();
|
||||
auto platform_queue_id = fml::MessageLoop::GetCurrentTaskQueueId();
|
||||
|
||||
if (merged) {
|
||||
if (!rasterizer_thread) {
|
||||
return fml::MakeRefCounted<fml::RasterThreadMerger>(platform_queue_id,
|
||||
platform_queue_id);
|
||||
}
|
||||
auto rasterizer_thread = new fml::Thread("rasterizer");
|
||||
auto rasterizer_queue_id =
|
||||
rasterizer_thread->GetTaskRunner()->GetTaskQueueId();
|
||||
return fml::MakeRefCounted<fml::RasterThreadMerger>(platform_queue_id,
|
||||
rasterizer_queue_id);
|
||||
}
|
||||
|
||||
fml::RefPtr<fml::RasterThreadMerger> GetThreadMergerFromRasterThread() {
|
||||
auto platform_thread = new fml::Thread("rasterizer");
|
||||
fml::RefPtr<fml::RasterThreadMerger> GetThreadMergerFromRasterThread(
|
||||
fml::Thread* platform_thread) {
|
||||
auto platform_queue_id = platform_thread->GetTaskRunner()->GetTaskQueueId();
|
||||
|
||||
// Assume the current thread is the raster thread.
|
||||
@ -94,7 +93,9 @@ TEST(AndroidExternalViewEmbedder, GetCurrentCanvases) {
|
||||
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
|
||||
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
|
||||
android_context, jni_mock, nullptr);
|
||||
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
|
||||
fml::Thread rasterizer_thread("rasterizer");
|
||||
auto raster_thread_merger =
|
||||
GetThreadMergerFromPlatformThread(&rasterizer_thread);
|
||||
|
||||
EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
|
||||
embedder->BeginFrame(SkISize::Make(10, 20), nullptr, 1.0,
|
||||
@ -117,7 +118,9 @@ TEST(AndroidExternalViewEmbedder, GetCurrentCanvases__CompositeOrder) {
|
||||
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
|
||||
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
|
||||
android_context, jni_mock, nullptr);
|
||||
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
|
||||
fml::Thread rasterizer_thread("rasterizer");
|
||||
auto raster_thread_merger =
|
||||
GetThreadMergerFromPlatformThread(&rasterizer_thread);
|
||||
|
||||
EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
|
||||
embedder->BeginFrame(SkISize::Make(10, 20), nullptr, 1.0,
|
||||
@ -169,7 +172,9 @@ TEST(AndroidExternalViewEmbedder, RasterizerRunsOnPlatformThread) {
|
||||
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
|
||||
android_context, jni_mock, nullptr);
|
||||
|
||||
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
|
||||
fml::Thread rasterizer_thread("rasterizer");
|
||||
auto raster_thread_merger =
|
||||
GetThreadMergerFromPlatformThread(&rasterizer_thread);
|
||||
ASSERT_FALSE(raster_thread_merger->IsMerged());
|
||||
|
||||
EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
|
||||
@ -201,7 +206,9 @@ TEST(AndroidExternalViewEmbedder, RasterizerRunsOnRasterizerThread) {
|
||||
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
|
||||
android_context, jni_mock, nullptr);
|
||||
|
||||
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
|
||||
fml::Thread rasterizer_thread("rasterizer");
|
||||
auto raster_thread_merger =
|
||||
GetThreadMergerFromPlatformThread(&rasterizer_thread);
|
||||
ASSERT_FALSE(raster_thread_merger->IsMerged());
|
||||
|
||||
PostPrerollResult result = embedder->PostPrerollAction(raster_thread_merger);
|
||||
@ -219,7 +226,9 @@ TEST(AndroidExternalViewEmbedder, PlatformViewRect) {
|
||||
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
|
||||
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
|
||||
android_context, jni_mock, nullptr);
|
||||
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
|
||||
fml::Thread rasterizer_thread("rasterizer");
|
||||
auto raster_thread_merger =
|
||||
GetThreadMergerFromPlatformThread(&rasterizer_thread);
|
||||
|
||||
EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
|
||||
embedder->BeginFrame(SkISize::Make(100, 100), nullptr, 1.5,
|
||||
@ -245,7 +254,9 @@ TEST(AndroidExternalViewEmbedder, PlatformViewRect__ChangedParams) {
|
||||
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
|
||||
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
|
||||
android_context, jni_mock, nullptr);
|
||||
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
|
||||
fml::Thread rasterizer_thread("rasterizer");
|
||||
auto raster_thread_merger =
|
||||
GetThreadMergerFromPlatformThread(&rasterizer_thread);
|
||||
|
||||
EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
|
||||
embedder->BeginFrame(SkISize::Make(100, 100), nullptr, 1.5,
|
||||
@ -318,8 +329,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) {
|
||||
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
|
||||
*android_context, jni_mock, surface_factory);
|
||||
|
||||
auto raster_thread_merger =
|
||||
GetThreadMergerFromPlatformThread(/*merged=*/true);
|
||||
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
|
||||
|
||||
// ------------------ First frame ------------------ //
|
||||
{
|
||||
@ -511,8 +521,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame__overlayComposition) {
|
||||
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
|
||||
*android_context, jni_mock, surface_factory);
|
||||
|
||||
auto raster_thread_merger =
|
||||
GetThreadMergerFromPlatformThread(/*merged=*/true);
|
||||
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
|
||||
|
||||
EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
|
||||
embedder->BeginFrame(frame_size, nullptr, 1.5, raster_thread_merger);
|
||||
@ -613,8 +622,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame__platformViewWithoutAnyOverlay) {
|
||||
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
|
||||
*android_context, jni_mock, surface_factory);
|
||||
|
||||
auto raster_thread_merger =
|
||||
GetThreadMergerFromPlatformThread(/*merged=*/true);
|
||||
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
|
||||
|
||||
EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
|
||||
embedder->BeginFrame(frame_size, nullptr, 1.5, raster_thread_merger);
|
||||
@ -655,7 +663,8 @@ TEST(AndroidExternalViewEmbedder, DoesNotCallJNIPlatformThreadOnlyMethods) {
|
||||
|
||||
// While on the raster thread, don't make JNI calls as these methods can only
|
||||
// run on the platform thread.
|
||||
auto raster_thread_merger = GetThreadMergerFromRasterThread();
|
||||
fml::Thread platform_thread("platform");
|
||||
auto raster_thread_merger = GetThreadMergerFromRasterThread(&platform_thread);
|
||||
|
||||
EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()).Times(0);
|
||||
embedder->BeginFrame(SkISize::Make(10, 20), nullptr, 1.0,
|
||||
@ -699,7 +708,9 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) {
|
||||
|
||||
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
|
||||
*android_context, jni_mock, surface_factory);
|
||||
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
|
||||
fml::Thread rasterizer_thread("rasterizer");
|
||||
auto raster_thread_merger =
|
||||
GetThreadMergerFromPlatformThread(&rasterizer_thread);
|
||||
|
||||
// ------------------ First frame ------------------ //
|
||||
{
|
||||
@ -784,7 +795,9 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) {
|
||||
|
||||
// ------------------ First frame ------------------ //
|
||||
{
|
||||
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
|
||||
fml::Thread rasterizer_thread("rasterizer");
|
||||
auto raster_thread_merger =
|
||||
GetThreadMergerFromPlatformThread(&rasterizer_thread);
|
||||
EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
|
||||
embedder->BeginFrame(frame_size, nullptr, 1.5, raster_thread_merger);
|
||||
|
||||
@ -827,8 +840,9 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) {
|
||||
EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces()).Times(0);
|
||||
EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()).Times(0);
|
||||
|
||||
fml::Thread platform_thread("platform");
|
||||
embedder->BeginFrame(SkISize::Make(30, 40), nullptr, 1.0,
|
||||
GetThreadMergerFromRasterThread());
|
||||
GetThreadMergerFromRasterThread(&platform_thread));
|
||||
}
|
||||
|
||||
TEST(AndroidExternalViewEmbedder, SupportsDynamicThreadMerging) {
|
||||
@ -845,7 +859,8 @@ TEST(AndroidExternalViewEmbedder, DisableThreadMerger) {
|
||||
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
|
||||
android_context, jni_mock, nullptr);
|
||||
|
||||
auto raster_thread_merger = GetThreadMergerFromRasterThread();
|
||||
fml::Thread platform_thread("platform");
|
||||
auto raster_thread_merger = GetThreadMergerFromRasterThread(&platform_thread);
|
||||
ASSERT_FALSE(raster_thread_merger->IsMerged());
|
||||
|
||||
// The shell may disable the thread merger during `OnPlatformViewDestroyed`.
|
||||
|
||||
@ -3537,7 +3537,9 @@ TEST_F(EmbedderTest, CreateInvalidBackingstoreOpenGLTexture) {
|
||||
backing_store_out->open_gl.texture.target = 0;
|
||||
backing_store_out->open_gl.texture.name = 0;
|
||||
backing_store_out->open_gl.texture.format = 0;
|
||||
backing_store_out->open_gl.texture.user_data = new TestCollectOnce();
|
||||
static TestCollectOnce collect_once_user_data;
|
||||
collect_once_user_data = {};
|
||||
backing_store_out->open_gl.texture.user_data = &collect_once_user_data;
|
||||
backing_store_out->open_gl.texture.destruction_callback =
|
||||
[](void* user_data) {
|
||||
reinterpret_cast<TestCollectOnce*>(user_data)->Collect();
|
||||
@ -3597,8 +3599,10 @@ TEST_F(EmbedderTest, CreateInvalidBackingstoreOpenGLFramebuffer) {
|
||||
backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
|
||||
backing_store_out->open_gl.framebuffer.target = 0;
|
||||
backing_store_out->open_gl.framebuffer.name = 0;
|
||||
static TestCollectOnce collect_once_user_data;
|
||||
collect_once_user_data = {};
|
||||
backing_store_out->open_gl.framebuffer.user_data =
|
||||
new TestCollectOnce();
|
||||
&collect_once_user_data;
|
||||
backing_store_out->open_gl.framebuffer.destruction_callback =
|
||||
[](void* user_data) {
|
||||
reinterpret_cast<TestCollectOnce*>(user_data)->Collect();
|
||||
|
||||
@ -42,8 +42,9 @@ static void listen_channel(FlBinaryMessenger* messenger, FlValue* args) {
|
||||
g_autoptr(FlValue) invoke_args = fl_value_new_list();
|
||||
fl_value_append_take(invoke_args, fl_value_new_string("test/standard-event"));
|
||||
fl_value_append_take(invoke_args, fl_value_new_string("listen"));
|
||||
fl_value_append(invoke_args,
|
||||
args != nullptr ? fl_value_ref(args) : fl_value_new_null());
|
||||
g_autoptr(FlValue) value =
|
||||
args != nullptr ? fl_value_ref(args) : fl_value_new_null();
|
||||
fl_value_append(invoke_args, value);
|
||||
fl_method_channel_invoke_method(channel, "InvokeMethod", invoke_args, nullptr,
|
||||
nullptr, nullptr);
|
||||
}
|
||||
@ -58,8 +59,9 @@ static void cancel_channel(FlBinaryMessenger* messenger, FlValue* args) {
|
||||
g_autoptr(FlValue) invoke_args = fl_value_new_list();
|
||||
fl_value_append_take(invoke_args, fl_value_new_string("test/standard-event"));
|
||||
fl_value_append_take(invoke_args, fl_value_new_string("cancel"));
|
||||
fl_value_append_take(
|
||||
invoke_args, args != nullptr ? fl_value_ref(args) : fl_value_new_null());
|
||||
g_autoptr(FlValue) value =
|
||||
args != nullptr ? fl_value_ref(args) : fl_value_new_null();
|
||||
fl_value_append(invoke_args, value);
|
||||
fl_method_channel_invoke_method(channel, "InvokeMethod", invoke_args, nullptr,
|
||||
nullptr, nullptr);
|
||||
}
|
||||
|
||||
@ -40,3 +40,26 @@ leak:flutter::Engine::Run(flutter::RunConfiguration)
|
||||
leak:txt::FontCollection::CreateMinikinFontFamily
|
||||
leak:CGFontCreateFontsWithURL
|
||||
leak:txt::GetDefaultFontFamily
|
||||
|
||||
# The RefCounted DebugChecks tests intentionally fail to wrap and manage heap
|
||||
# allocated objects.
|
||||
leak:RefCountedTest_DebugChecks_Test::TestBody
|
||||
|
||||
# Objects allocated by this mock API are intentionally not collected and are
|
||||
# instead marked as released in order to explicitly assert double free attempts
|
||||
# and allow some tests to inspect contents.
|
||||
leak:*flutter/shell/platform/linux/testing/mock_engine.cc
|
||||
|
||||
# TODO(bdero): Fix FL leaks: https://github.com/flutter/flutter/issues/90155
|
||||
leak:*flutter/shell/platform/linux/fl_keyboard_manager_test.cc*
|
||||
leak:*flutter/shell/platform/linux/fl_key_channel_responder_test.cc*
|
||||
leak:*flutter/shell/platform/linux/fl_basic_message_channel_test.cc*
|
||||
leak:fl_message_codec_decode_message
|
||||
|
||||
# TODO(bdero): https://github.com/flutter/flutter/issues/90156
|
||||
# Unfortunately, realloc calls originating from g_realloc effectively obscure
|
||||
# the trace of the original allocation. Deeper investigation is required to
|
||||
# identify the original allocation source for these.
|
||||
# At the time of writing, this only amounts to 4 allocations totaling 512 bytes
|
||||
# worth of leaks.
|
||||
leak:g_realloc
|
||||
|
||||
@ -22,6 +22,5 @@ UBSAN_SUPPRESSIONS_FILE="${TESTING_DIRECTORY}/ubsan_suppressions.txt"
|
||||
export UBSAN_OPTIONS="suppressions=${UBSAN_SUPPRESSIONS_FILE}"
|
||||
echo "Using Undefined Behavior suppressions in ${UBSAN_SUPPRESSIONS_FILE}"
|
||||
|
||||
|
||||
export ASAN_OPTIONS="symbolize=1:detect_leaks=0"
|
||||
export ASAN_OPTIONS="symbolize=1:detect_leaks=1"
|
||||
export ASAN_SYMBOLIZER_PATH="${BUILDTOOLS_DIRECTORY}/clang/bin/llvm-symbolizer"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user