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:
Brandon DeRosier 2021-09-16 12:58:56 -07:00 committed by GitHub
parent f9c5181cba
commit 7b6fa075a7
5 changed files with 73 additions and 30 deletions

View File

@ -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`.

View File

@ -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();

View File

@ -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);
}

View File

@ -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

View File

@ -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"